Repository: sonic-net/sonic-pins
Pull request #1056: [SAI-P4] Adding Preprocess SAI P4 Programs for P4Testgen to produce tests without invoking its internal preprocessor
Author: login: ksravani-hcl
Created: 2025-05-02T08:30:19Z | Merged: 2025-05-15T01:22:32Z

Keyword Check:
/sonic-buildimage/src/sonic-p4rt/sonic-pins$ ~/tools/keyword_checks.sh .
Keyword check Passed.



Build Result:
/sonic/src/sonic-p4rt/sonic-pins$ bazel build $BAZEL_BUILD_OPTS ...
INFO: Analyzed 725 targets (0 packages loaded, 0 targets configured).
INFO: Found 725 targets...
sai_p4/instantiations/google/../../fixed/mirroring.p4(33): [--Wwarn=unused] warning: Unused action parameter src_ip
      @id(2) @format(IPV4_ADDRESS) ipv4_addr_t src_ip,
                                               ^^^^^^
sai_p4/instantiations/google/../../fixed/mirroring.p4(34): [--Wwarn=unused] warning: Unused action parameter dst_ip
      @id(3) @format(IPV4_ADDRESS) ipv4_addr_t dst_ip,
                                               ^^^^^^
sai_p4/instantiations/google/../../fixed/mirroring.p4(35): [--Wwarn=unused] warning: Unused action parameter src_mac
      @id(4) @format(MAC_ADDRESS) ethernet_addr_t src_mac,
                                                  ^^^^^^^
sai_p4/instantiations/google/../../fixed/mirroring.p4(36): [--Wwarn=unused] warning: Unused action parameter dst_mac
      @id(5) @format(MAC_ADDRESS) ethernet_addr_t dst_mac,
                                                  ^^^^^^^
sai_p4/instantiations/google/../../fixed/mirroring.p4(37): [--Wwarn=unused] warning: Unused action parameter ttl
      @id(6) bit<8> ttl,
                    ^^^
sai_p4/instantiations/google/../../fixed/mirroring.p4(38): [--Wwarn=unused] warning: Unused action parameter tos
      @id(7) bit<8> tos) {
                    ^^^
sai_p4/instantiations/google/../../fixed/mirroring.p4(63): [--Wwarn=unused] warning: Unused action parameter monitor_failover_port
      @id(2) port_id_t monitor_failover_port,
                       ^^^^^^^^^^^^^^^^^^^^^
sai_p4/instantiations/google/../../fixed/routing.p4(549): [--Wwarn=unsupported] warning: Target does not support default_action for ingress.routing_resolution.wcmp_group_table (due to action profiles)
  table wcmp_group_table {
        ^^^^^^^^^^^^^^^^
sai_p4/instantiations/google/acl_pre_ingress.p4(34): [--Wwarn=unused] warning: ingress.acl_pre_ingress.acl_pre_ingress_vlan_counter: Direct counter not used; ignoring
  direct_counter(CounterType.packets_and_bytes) acl_pre_ingress_vlan_counter;
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sai_p4/instantiations/google/acl_pre_ingress.p4(37): [--Wwarn=unused] warning: ingress.acl_pre_ingress.acl_pre_ingress_metadata_counter: Direct counter not used; ignoring
  direct_counter(CounterType.packets_and_bytes) acl_pre_ingress_metadata_counter;
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sai_p4/instantiations/google/acl_ingress.p4(44): [--Wwarn=unused] warning: ingress.acl_ingress.acl_ingress_security_counter: Direct counter not used; ignoring
  direct_counter(CounterType.packets_and_bytes) acl_ingress_security_counter;
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sai_p4/instantiations/google/acl_egress.p4(24): [--Wwarn=unused] warning: egress.acl_egress.acl_egress_dhcp_to_host_counter: Direct counter not used; ignoring
  direct_counter(CounterType.packets_and_bytes) acl_egress_dhcp_to_host_counter;
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
INFO: Elapsed time: 74.572s, Critical Path: 73.27s
INFO: 96 processes: 6 internal, 90 linux-sandbox.
INFO: Build completed successfully, 96 total actions




Test Result:
/sonic/src/sonic-p4rt/sonic-pins$ bazel test $BAZEL_BUILD_OPTS --cache_test_results=no ...
INFO: Analyzed 725 targets (0 packages loaded, 66 targets configured).
INFO: Found 500 targets and 225 test targets...
INFO: Elapsed time: 288.018s, Critical Path: 117.58s
INFO: 282 processes: 339 linux-sandbox, 18 local.
INFO: Build completed successfully, 282 total actions
//dvaas:port_id_map_test                                                 PASSED in 0.8s
//dvaas:test_run_validation_golden_test                                  PASSED in 0.1s
//dvaas:test_run_validation_test                                         PASSED in 0.7s
//dvaas:test_run_validation_test_runner                                  PASSED in 0.0s
//dvaas:test_vector_stats_diff_test                                      PASSED in 0.1s
//dvaas:test_vector_stats_test                                           PASSED in 0.0s
//dvaas:test_vector_test                                                 PASSED in 0.7s
//dvaas:user_provided_packet_test_vector_diff_test                       PASSED in 0.2s
//dvaas:user_provided_packet_test_vector_test                            PASSED in 0.1s
//gutil:collections_test                                                 PASSED in 0.5s
//gutil:io_test                                                          PASSED in 0.5s
//gutil:proto_matchers_test                                              PASSED in 0.7s
//gutil:proto_ordering_test                                              PASSED in 0.6s
//p4rt_app/tests:vrf_table_test                                          PASSED in 2.4s
//p4rt_app/tests/lib:app_db_entry_builder_test                           PASSED in 0.0s
//p4rt_app/utils:event_data_tracker_test                                 PASSED in 0.0s
//p4rt_app/utils:table_utility_test                                      PASSED in 1.6s
//sai_p4/instantiations/google:clos_stage_test                           PASSED in 0.5s
//sai_p4/instantiations/google:fabric_border_router_p4info_up_to_date_test PASSED in 0.1s
//sai_p4/instantiations/google:middleblock_p4info_up_to_date_test        PASSED in 0.0s
//sai_p4/instantiations/google:preprocessed_sai_programs_test            PASSED in 0.1s
//sai_p4/instantiations/google:sai_nonstandard_platforms_build_test      PASSED in 0.1s
//sai_p4/instantiations/google:sai_nonstandard_platforms_cc_test         PASSED in 0.7s
//sai_p4/instantiations/google:sai_p4info_fetcher_test                   PASSED in 0.7s
//sai_p4/instantiations/google:sai_p4info_test                           PASSED in 1.1s
//sai_p4/instantiations/google:sai_pd_proto_test                         PASSED in 0.0s
//sai_p4/instantiations/google:sai_pd_util_test                          PASSED in 0.6s
//sai_p4/instantiations/google:tor_p4info_up_to_date_test                PASSED in 0.0s
//sai_p4/instantiations/google:union_p4info_up_to_date_test              PASSED in 0.1s
//sai_p4/instantiations/google:wbb_p4info_up_to_date_test                PASSED in 0.0s
//sai_p4/instantiations/google/test_tools:table_entry_generator_helper_test PASSED in 3.9s
//sai_p4/instantiations/google/test_tools:test_entries_test              PASSED in 1.0s
//sai_p4/instantiations/google/tests:p4_fuzzer_integration_test          PASSED in 4.0s
//sai_p4/tools:p4info_tools_test                                         PASSED in 0.6s
//sai_p4/tools:packetio_tools_test                                       PASSED in 0.8s
//tests:thinkit_gnmi_interface_util_tests                                PASSED in 1.3s
//tests/forwarding:hash_statistics_util_test                             PASSED in 1.0s
//tests/lib:p4info_helper_test                                           PASSED in 0.8s
//tests/lib:p4rt_fixed_table_programming_helper_test                     PASSED in 0.8s
//tests/lib:switch_test_setup_helpers_golden_test                        PASSED in 0.1s
//tests/lib:switch_test_setup_helpers_golden_test_runner                 PASSED in 0.1s
//tests/qos:gnmi_parsers_test                                            PASSED in 0.1s
//tests/qos:gnmi_parsers_test_runner                                     PASSED in 0.1s
//tests/sflow:sflow_util_test                                            PASSED in 6.9s
//thinkit:bazel_test_environment_test                                    PASSED in 0.6s
//thinkit:generic_testbed_test                                           PASSED in 0.9s
//thinkit:mock_control_device_test                                       PASSED in 0.5s
//thinkit:mock_generic_testbed_test                                      PASSED in 0.7s
//thinkit:mock_mirror_testbed_test                                       PASSED in 0.7s
//thinkit:mock_ssh_client_test                                           PASSED in 0.0s
//thinkit:mock_switch_test                                               PASSED in 0.7s
//thinkit:mock_test_environment_test                                     PASSED in 0.1s
//thinkit:switch_test                                                    PASSED in 0.8s
//tests/lib:packet_generator_test                                        PASSED in 64.7s
  Stats over 4 runs: max = 64.7s, min = 61.2s, avg = 63.3s, dev = 1.4s
//sai_p4/instantiations/google/tests:p4_constraints_integration_test     PASSED in 0.9s
  Stats over 5 runs: max = 0.9s, min = 0.7s, avg = 0.8s, dev = 0.1s
//sai_p4/instantiations/google/test_tools:table_entry_generator_test     PASSED in 47.0s
  Stats over 50 runs: max = 47.0s, min = 0.8s, avg = 4.0s, dev = 10.8s

Executed 225 out of 225 tests: 225 tests pass.
INFO: Build completed successfully, 282 total actions



Diff:
diff --git a/sai_p4/fixed/drop_martians.p4 b/sai_p4/fixed/drop_martians.p4
index 9cebb0327..8eb846d2b 100644
--- a/sai_p4/fixed/drop_martians.p4
+++ b/sai_p4/fixed/drop_martians.p4
@@ -55,22 +55,27 @@ control drop_martians(in headers_t headers,
     // Drop the packet if:
     // - Src IPv6 address is in multicast range; or
     // - Src IPv4 address is in multicast or broadcast range; or
-    // - Src/Dst IPv4/IPv6 address is a loopback address.
+    // - Src/Dst IPv4/IPv6 address is a loopback address; or
+    // - Dst IPv4/IPv6 is the all-zero address.
     // Rationale:
     // Src IP multicast drop: https://www.rfc-editor.org/rfc/rfc1812#section-5.3.7
     // Src/Dst IP loopback drop: https://en.wikipedia.org/wiki/Localhost#Packet_processing
     //    "Packets received on a non-loopback interface with a loopback source
     //     or destination address must be dropped."
+    // Dst IP all zeroes drop: https://en.wikipedia.org/wiki/0.0.0.0
+    //    "RFC 1122 [...] prohibits this as a destination address."
     if ((headers.ipv6.isValid() &&
             (IS_MULTICAST_IPV6(headers.ipv6.src_addr) ||
              IS_LOOPBACK_IPV6(headers.ipv6.src_addr) ||
-             IS_LOOPBACK_IPV6(headers.ipv6.dst_addr))) ||
+             IS_LOOPBACK_IPV6(headers.ipv6.dst_addr) ||
+             headers.ipv6.dst_addr == 0)) ||
         (headers.ipv4.isValid() &&
             (IS_MULTICAST_IPV4(headers.ipv4.src_addr) ||
              IS_BROADCAST_IPV4(headers.ipv4.src_addr) ||
              IS_BROADCAST_IPV4(headers.ipv4.dst_addr) ||
              IS_LOOPBACK_IPV4(headers.ipv4.src_addr) ||
-             IS_LOOPBACK_IPV4(headers.ipv4.dst_addr)))
+             IS_LOOPBACK_IPV4(headers.ipv4.dst_addr) ||
+             headers.ipv4.dst_addr == 0))
        ) {
         mark_to_drop(standard_metadata);
     }
diff --git a/sai_p4/instantiations/google/BUILD.bazel b/sai_p4/instantiations/google/BUILD.bazel
index 4074db60c..6ffa29db0 100644
--- a/sai_p4/instantiations/google/BUILD.bazel
+++ b/sai_p4/instantiations/google/BUILD.bazel
@@ -334,6 +334,25 @@ build_test(
     ],
 )
 
+# P4 info and config for non-standard platforms, accessible via C++ API.
+cc_library(
+    name = "sai_nonstandard_platforms_cc",
+    srcs = ["sai_nonstandard_platforms.cc"],
+    hdrs = ["sai_nonstandard_platforms.h"],
+    deps = [
+        ":instantiations",
+        ":sai_nonstandard_platforms_embed",
+        "//p4_pdpi:ir_cc_proto",
+        "@com_github_google_glog//:glog",
+        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
+        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
+        "@com_google_absl//absl/container:flat_hash_map",
+        "@com_google_absl//absl/strings",
+        "@com_google_absl//absl/strings:str_format",
+        "@com_google_protobuf//:protobuf",
+    ],
+)
+
 cc_library(
     name = "clos_stage",
     srcs = ["clos_stage.cc"],
@@ -358,24 +377,6 @@ cc_test(
     ],
 )
 
-# P4 info and config for non-standard platforms, accessible via C++ API.
-cc_library(
-    name = "sai_nonstandard_platforms_cc",
-    srcs = ["sai_nonstandard_platforms.cc"],
-    hdrs = ["sai_nonstandard_platforms.h"],
-    visibility = ["//visibility:public"],
-    deps = [
-	":instantiations",
-	":sai_nonstandard_platforms_embed",
-        "//p4_pdpi:ir_cc_proto",
-        "@com_github_google_glog//:glog",
-        "@com_github_p4lang_p4runtime//:p4info_cc_proto",
-        "@com_github_p4lang_p4runtime//:p4runtime_cc_proto",
-        "@com_google_absl//absl/strings:str_format",
-        "@com_google_protobuf//:protobuf",
-	],
-)
-
 # Auxiliary target, see go/totw/128.
 cc_embed_data(
     name = "sai_nonstandard_platforms_embed",
@@ -411,3 +412,57 @@ filegroup(
     name = "sai_p4",
     srcs = glob(["**/*.p4"]) + glob(["**/*.h"]),
 )
+
+[
+    # In cases where we are unable to access P4C's internal preprocessor ('cc') we need to
+    # preprocess the P4 program of a particular instantiation.
+    genrule(
+        name = "preprocessed_%s_%s" % (platform, instantiation),
+        srcs = [
+            "@com_github_p4lang_p4c//:p4include",
+            "@com_github_p4lang_p4c//:p4include/v1model.p4",
+            "//sai_p4/instantiations/google:%s.p4" % instantiation,
+            "//sai_p4/instantiations/google:sai_p4",
+            "//sai_p4/fixed",
+        ],
+        outs = ["preprocessed_%s_%s.p4" % (platform, instantiation)],
+        cmd = """
+              # This command mimicks the command found at
+              # https://github.com/p4lang/p4c/blob/a274a5bab0e63e01935c46593bc490852ec385bd/frontends/common/parser_options.cpp#L410
+              # genrules do not support retrieval of directories from dependencies, so we need to use a workaround. 
+              # We depend on v1model.p4 and retrieve its parent directory. 
+              # TODO: Maybe there is a better way to do this?
+              P4INCLUDE_DIR=$$(dirname $(location @com_github_p4lang_p4c//:p4include/v1model.p4))
+              $(CC) -E -x c -Wno-comment -C -undef -nostdinc -x assembler-with-cpp -I$$P4INCLUDE_DIR -I. %s \
+              $(location //sai_p4/instantiations/google:%s.p4) > $(OUTS)
+              """ % (
+            "-D" + MACRO_BY_NONSTANDARD_PLATFORM_NAME[platform] if platform in MACRO_BY_NONSTANDARD_PLATFORM_NAME else "",
+            instantiation,
+        ),
+        toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"],
+    )
+    for (instantiation, deps) in INSTANTIATIONS
+    for platform in ("standard", "bmv2")
+]
+
+filegroup(
+    name =
+        "preprocessed_sai_programs",
+    srcs = [
+        "//sai_p4/instantiations/google:preprocessed_%s_%s.p4" % (platform, instantiation)
+        for (instantiation, _) in INSTANTIATIONS
+        for platform in ("standard", "bmv2")
+    ],
+)
+
+cc_test(
+    name = "preprocessed_sai_programs_test",
+    srcs = ["preprocessed_sai_programs_test.cc"],
+    data = [":preprocessed_sai_programs"],
+    deps = [
+        ":instantiations",
+        ":sai_nonstandard_platforms_cc",
+        "@com_google_absl//absl/strings",
+        "@com_google_googletest//:gtest_main",
+    ],
+)
diff --git a/sai_p4/instantiations/google/acl_ingress.p4 b/sai_p4/instantiations/google/acl_ingress.p4
index 98a902774..73cb2581c 100644
--- a/sai_p4/instantiations/google/acl_ingress.p4
+++ b/sai_p4/instantiations/google/acl_ingress.p4
@@ -146,9 +146,9 @@ control acl_ingress(in headers_t headers,
   @unsupported
   action set_cpu_and_multicast_queues_and_deny_above_rate_limit(
       @id(1) @sai_action_param(QOS_QUEUE) qos_queue_t cpu_queue,
-      @id(2) @sai_action_param(MULTICAST_QOS_QUEUE, SAI_PACKET_COLOR_GREEN)
+      @id(2) @sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION, SAI_PACKET_COLOR_GREEN)
         qos_queue_t green_multicast_queue,
-      @id(3) @sai_action_param(MULTICAST_QOS_QUEUE, SAI_PACKET_COLOR_RED)
+      @id(3) @sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION, SAI_PACKET_COLOR_RED)
         qos_queue_t red_multicast_queue) {
     acl_ingress_qos_meter.read(local_metadata.color);
     // We model the behavior for GREEN packes only here.
@@ -578,14 +578,11 @@ control acl_ingress(in headers_t headers,
     actions = {
 // We don't usually restrict actions to instantiations because they don't
 // require resources but we make an exception here because of issues with
-// metering (go/gpins-meter-consistency for details).
-// `acl_forward` in `mirror_and_redirect` is needed for `experimental_tor` and is an
+// metering (go/pins-meter-consistency for details).
 // unmetered action there. `middleblock` needs `mirror_and_redirect` but NOT
 // `acl_forward` which is a metered action there. If we include it in
 // `middleblock` we run into resource issues.
-#if defined(SAI_INSTANTIATION_EXPERIMENTAL_TOR)
       @proto_id(4) acl_forward();
-#endif
       @proto_id(1) acl_mirror();
       @proto_id(2) redirect_to_nexthop();
       @proto_id(3) redirect_to_ipmc_group();
diff --git a/sai_p4/instantiations/google/fabric_border_router.p4info.pb.txt b/sai_p4/instantiations/google/fabric_border_router.p4info.pb.txt
index 0aa748e18..bd84e3be3 100644
--- a/sai_p4/instantiations/google/fabric_border_router.p4info.pb.txt
+++ b/sai_p4/instantiations/google/fabric_border_router.p4info.pb.txt
@@ -1365,7 +1365,7 @@ actions {
   params {
     id: 2
     name: "green_multicast_queue"
-    annotations: "@sai_action_param(MULTICAST_QOS_QUEUE , SAI_PACKET_COLOR_GREEN)"
+    annotations: "@sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION , SAI_PACKET_COLOR_GREEN)"
     type_name {
       name: "qos_queue_t"
     }
@@ -1373,7 +1373,7 @@ actions {
   params {
     id: 3
     name: "red_multicast_queue"
-    annotations: "@sai_action_param(MULTICAST_QOS_QUEUE , SAI_PACKET_COLOR_RED)"
+    annotations: "@sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION , SAI_PACKET_COLOR_RED)"
     type_name {
       name: "qos_queue_t"
     }
diff --git a/sai_p4/instantiations/google/middleblock.p4info.pb.txt b/sai_p4/instantiations/google/middleblock.p4info.pb.txt
index 6cebae1a8..8671185e2 100755
--- a/sai_p4/instantiations/google/middleblock.p4info.pb.txt
+++ b/sai_p4/instantiations/google/middleblock.p4info.pb.txt
@@ -611,6 +611,10 @@ tables {
     bitwidth: 1
     match_type: OPTIONAL
   }
+  action_refs {
+    id: 16777475
+    annotations: "@proto_id(4)"
+  }
   action_refs {
     id: 16777476
     annotations: "@proto_id(1)"
diff --git a/sai_p4/instantiations/google/preprocessed_sai_programs_test.cc b/sai_p4/instantiations/google/preprocessed_sai_programs_test.cc
new file mode 100644
index 000000000..6fe7e7014
--- /dev/null
+++ b/sai_p4/instantiations/google/preprocessed_sai_programs_test.cc
@@ -0,0 +1,64 @@
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "absl/strings/str_cat.h"
+#include "gtest/gtest.h"
+#include "sai_p4/instantiations/google/instantiations.h"
+#include "sai_p4/instantiations/google/sai_nonstandard_platforms.h"
+
+namespace sai {
+
+namespace {
+
+struct TestParams {
+  // The flavor of SAI P4 to be tested. The test should pass for all
+  // instantiations.
+  sai::Instantiation instantiation;
+  // Whether the instantiation is preprocessed for BMv2.
+  std::optional<NonstandardPlatform> nonstandard_platform;
+};
+
+std::vector<TestParams> GetTestParams() {
+  std::vector<TestParams> params;
+  for (const auto& instantiation : sai::AllInstantiations()) {
+    for (bool processed_for_bmv2 : {false, true}) {
+      auto test_params = TestParams{
+          .instantiation = instantiation,
+      };
+      if (processed_for_bmv2) {
+        test_params.nonstandard_platform = NonstandardPlatform::kBmv2;
+      }
+      params.emplace_back() = test_params;
+    }
+  }
+  return params;
+}
+
+using PreprocessedSaiProgramsTest = ::testing::TestWithParam<TestParams>;
+
+TEST_P(PreprocessedSaiProgramsTest, PreprocessedInstantiationIsAccessible) {
+  std::string preprocessed_instantiation_file_path = absl::StrCat(
+      "sai_p4/instantiations/google/",
+      PreprocessedInstantiationFileName(
+          GetParam().instantiation,
+          /*nonstandard_platform=*/GetParam().nonstandard_platform));
+  // Portable method to check that the file exists.
+  struct stat buffer;
+  EXPECT_EQ(0, stat(preprocessed_instantiation_file_path.c_str(), &buffer));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    PreprocessedSaiProgramsTest, PreprocessedSaiProgramsTest,
+    testing::ValuesIn(GetTestParams()), [](const auto& test) {
+      return absl::StrFormat(
+          "%v%s", test.param.instantiation,
+          "_preprocessed_" +
+              (test.param.nonstandard_platform.has_value()
+                   ? PlatformName(test.param.nonstandard_platform.value())
+                   : "standard"));
+    });
+
+}  // namespace
+
+}  // namespace sai
diff --git a/sai_p4/instantiations/google/sai_nonstandard_platforms.cc b/sai_p4/instantiations/google/sai_nonstandard_platforms.cc
index 8a506928c..54e6c6ddc 100644
--- a/sai_p4/instantiations/google/sai_nonstandard_platforms.cc
+++ b/sai_p4/instantiations/google/sai_nonstandard_platforms.cc
@@ -1,6 +1,14 @@
 #include "sai_p4/instantiations/google/sai_nonstandard_platforms.h"
 
+#include <algorithm>
+#include <optional>
+#include <string>
+
+#include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
+#include "absl/strings/str_replace.h"
+#include "absl/strings/string_view.h"
+#include "absl/strings/substitute.h"
 #include "glog/logging.h"
 #include "google/protobuf/text_format.h"
 #include "p4/config/v1/p4info.pb.h"
@@ -13,13 +21,20 @@ namespace {
 
 using ::p4::config::v1::P4Info;
 
+// Return the base (no suffix) name of the instantiation p4info file.
+std::string InstantiationName(Instantiation instantiation) {
+  return InstantiationToString(instantiation);
+}
+
+// Return the name of the P4Config JSON file.
 std::string P4ConfigName(Instantiation instantiation, NonstandardPlatform platform) {
-  return absl::StrFormat("sai_%s_%s.config.json", InstantiationToString(instantiation),
+  return absl::StrFormat("sai_%s_%s.config.json",  InstantiationName(instantiation),
                          PlatformName(platform));
 }
 
-std::string P4infoName(Instantiation instantiation, NonstandardPlatform platform) {
-  return absl::StrFormat("sai_%s_%s.p4info.pb.txt", InstantiationToString(instantiation),
+// Return the name of the P4Info protobuf file.
+std::string P4InfoName(Instantiation instantiation, NonstandardPlatform platform) {
+  return absl::StrFormat("sai_%s_%s.p4info.pb.txt",  InstantiationName(instantiation),
                          PlatformName(platform));
 }
 
@@ -53,7 +68,7 @@ std::string GetNonstandardP4Config(Instantiation instantiation,
 P4Info GetNonstandardP4Info(Instantiation instantiation, NonstandardPlatform platform) {
   P4Info p4info;
   const gutil::FileToc* toc = sai_nonstandard_platforms_embed_create();
-  std::string key = P4infoName(instantiation, platform);
+  std::string key = P4InfoName(instantiation, platform);
   for (int i = 0; i < sai_nonstandard_platforms_embed_size(); ++i) {
     if (toc[i].name == key) {
       CHECK(  // Crash ok: TAP rules out failures.
@@ -79,4 +94,14 @@ p4::v1::ForwardingPipelineConfig GetNonstandardForwardingPipelineConfig(
   return config;
 }
 
+std::string PreprocessedInstantiationFileName(
+    Instantiation role,
+    std::optional<NonstandardPlatform> nonstandard_platform) {
+  return "preprocessed_" +
+         (nonstandard_platform.has_value()
+              ? PlatformName(nonstandard_platform.value())
+              : "standard") +
+         "_" + InstantiationName(role) + ".p4";
+}
+
 }  // namespace sai
diff --git a/sai_p4/instantiations/google/sai_nonstandard_platforms.h b/sai_p4/instantiations/google/sai_nonstandard_platforms.h
index 3904a46e8..4c4eac27a 100644
--- a/sai_p4/instantiations/google/sai_nonstandard_platforms.h
+++ b/sai_p4/instantiations/google/sai_nonstandard_platforms.h
@@ -1,6 +1,12 @@
 #ifndef PINS_SAI_P4_INSTANTIATIONS_GOOGLE_SAI_NONSTANDARD_PLATFORMS_H_
 #define PINS_SAI_P4_INSTANTIATIONS_GOOGLE_SAI_NONSTANDARD_PLATFORMS_H_
 
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/container/flat_hash_map.h"
 #include "p4/v1/p4runtime.pb.h"
 #include "p4_pdpi/ir.pb.h"
 #include "sai_p4/instantiations/google/instantiations.h"
@@ -35,6 +41,12 @@ std::string PreprocessedInstantiationFileName(
     Instantiation role,
     std::optional<NonstandardPlatform> nonstandard_platform);
 
-} // namespace sai
+// Returns the file name of the preprocessed P4 program for the given
+// instantiation and platform.
+std::string PreprocessedInstantiationFileName(
+    Instantiation role,
+    std::optional<NonstandardPlatform> nonstandard_platform);
+
+}  // namespace sai
 
 #endif // PINS_SAI_P4_INSTANTIATIONS_GOOGLE_SAI_NONSTANDARD_PLATFORMS_H_
diff --git a/sai_p4/instantiations/google/sai_pd.proto b/sai_p4/instantiations/google/sai_pd.proto
index cbe9083db..bacd60710 100755
--- a/sai_p4/instantiations/google/sai_pd.proto
+++ b/sai_p4/instantiations/google/sai_pd.proto
@@ -523,6 +523,7 @@ message AclPreIngressVlanTableEntry {
     Optional is_ipv6 = 3;    // optional match / Format::HEX_STRING / 1 bits
     Ternary ether_type = 4;  // ternary match / Format::HEX_STRING / 16 bits
     Ternary vlan_id = 5;     // ternary match / Format::HEX_STRING / 12 bits
+    Optional in_port = 6;    // optional match / Format::STRING
   }
   Match match = 1;
   message Action {
diff --git a/sai_p4/instantiations/google/tor.p4info.pb.txt b/sai_p4/instantiations/google/tor.p4info.pb.txt
index 94d2270e4..47795c802 100644
--- a/sai_p4/instantiations/google/tor.p4info.pb.txt
+++ b/sai_p4/instantiations/google/tor.p4info.pb.txt
@@ -872,6 +872,10 @@ tables {
     bitwidth: 1
     match_type: OPTIONAL
   }
+  action_refs {
+    id: 16777475
+    annotations: "@proto_id(4)"
+  }
   action_refs {
     id: 16777476
     annotations: "@proto_id(1)"
@@ -1582,7 +1586,7 @@ actions {
   params {
     id: 2
     name: "green_multicast_queue"
-    annotations: "@sai_action_param(MULTICAST_QOS_QUEUE , SAI_PACKET_COLOR_GREEN)"
+    annotations: "@sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION , SAI_PACKET_COLOR_GREEN)"
     type_name {
       name: "qos_queue_t"
     }
@@ -1590,7 +1594,7 @@ actions {
   params {
     id: 3
     name: "red_multicast_queue"
-    annotations: "@sai_action_param(MULTICAST_QOS_QUEUE , SAI_PACKET_COLOR_RED)"
+    annotations: "@sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION , SAI_PACKET_COLOR_RED)"
     type_name {
       name: "qos_queue_t"
     }
diff --git a/sai_p4/instantiations/google/unioned_p4info.pb.txt b/sai_p4/instantiations/google/unioned_p4info.pb.txt
index a45d7b823..38d8123f5 100644
--- a/sai_p4/instantiations/google/unioned_p4info.pb.txt
+++ b/sai_p4/instantiations/google/unioned_p4info.pb.txt
@@ -1247,6 +1247,10 @@ tables {
     bitwidth: 12
     match_type: TERNARY
   }
+  action_refs {
+    id: 16777475
+    annotations: "@proto_id(4)"
+  }
   action_refs {
     id: 16777476
     annotations: "@proto_id(1)"
@@ -1880,7 +1884,7 @@ actions {
   params {
     id: 2
     name: "green_multicast_queue"
-    annotations: "@sai_action_param(MULTICAST_QOS_QUEUE , SAI_PACKET_COLOR_GREEN)"
+    annotations: "@sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION , SAI_PACKET_COLOR_GREEN)"
     type_name {
       name: "qos_queue_t"
     }
@@ -1888,7 +1892,7 @@ actions {
   params {
     id: 3
     name: "red_multicast_queue"
-    annotations: "@sai_action_param(MULTICAST_QOS_QUEUE , SAI_PACKET_COLOR_RED)"
+    annotations: "@sai_action_param(SAI_POLICER_ATTR_COLORED_PACKET_SET_MCAST_COS_QUEUE_ACTION , SAI_PACKET_COLOR_RED)"
     type_name {
       name: "qos_queue_t"
     }


Reviews:
user: login: kishanps
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-03T20:29:11Z
user: login: ksravani-hcl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T07:11:47Z
user: login: divyagayathri-hcl
body: @kishanps, Could you please review.
Thanks.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T13:38:53Z
user: login: kishanps
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-15T01:22:19Z

Review comments:
diff_hunk: @@ -155,6 +155,11 @@ control acl_pre_ingress(in headers_t headers,
           @sai_field(SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE);
       local_metadata.vlan_id : ternary @id(5) @name("vlan_id")
           @sai_field(SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID);
+#if defined(SAI_INSTANTIATION_EXPERIMENTAL_TOR)
path: sai_p4/instantiations/google/acl_pre_ingress.p4
user: login: kishanps
body: We don't need to upstream any code related to experimenal tor, pls remove this
created_at: 2025-05-03T20:29:11Z
author_association: COLLABORATOR
diff_hunk: @@ -155,6 +155,11 @@ control acl_pre_ingress(in headers_t headers,
           @sai_field(SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE);
       local_metadata.vlan_id : ternary @id(5) @name("vlan_id")
           @sai_field(SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID);
+#if defined(SAI_INSTANTIATION_EXPERIMENTAL_TOR)
path: sai_p4/instantiations/google/acl_pre_ingress.p4
user: login: ksravani-hcl
body: @kishanps,
removed the code related to experimental tor, could you please review the PR
created_at: 2025-05-07T07:11:46Z
author_association: CONTRIBUTOR

PR comments:
user: login: mssonicbld
created_at: 2025-05-02T08:30:27Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-02T08:30:32Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: ksravani-hcl
created_at: 2025-05-02T08:32:20Z
body: Co-authored-by: Srikishen Pondicherry Shanmugam kishanps@google.com
Co-authored-by: Jonathan Dilorenzo <dilo@google.com>

author_association: CONTRIBUTOR
user: login: mssonicbld
created_at: 2025-05-03T20:27:54Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-03T20:28:00Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-05-05T11:36:08Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-05T11:36:14Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-05-06T14:07:33Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-06T14:07:40Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-05-07T07:47:17Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-07T07:47:23Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-05-07T10:03:16Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-07T10:03:22Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-05-11T15:42:51Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-11T15:42:56Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE
user: login: mssonicbld
created_at: 2025-05-14T09:14:40Z
body: /azp run
author_association: NONE
user: login: azure-pipelines[bot]
created_at: 2025-05-14T09:14:46Z
body: <samp>
No pipelines are associated with this pull request.<br>

</samp>
author_association: NONE