From e4e8571d0dca534bfea7719e5da2cd49ce955be0 Mon Sep 17 00:00:00 2001 From: Yi Tseng Date: Sat, 24 Oct 2020 06:28:53 +0800 Subject: [PATCH] Use Stratum device config binary format (#118) * Use Stratum device config binary format * Simplify the pipeconf - Merge profiles for stratum_bf and stratum_bfrt * remove device parameter from ptf_runner * fix tests * Apply suggestions from code review Co-authored-by: Carmelo Cascone * Minor cleanup to build.sh * add pipeline config build image sha * remove stratum_bf from pipeconf name Co-authored-by: Carmelo Cascone --- Makefile | 2 +- README.md | 4 +- p4src/build.sh | 43 +++---- ptf/run/tm/Makefile | 15 +-- ptf/run/tm/run | 11 +- ptf/run/tv/Makefile | 24 ++-- ptf/run/tv/run | 8 +- ptf/tests/ptf/base_test.py | 7 -- ptf/tests/ptf/ptf_runner.py | 107 +++--------------- .../fabric/tna/PipeconfLoader.java | 87 ++++---------- 10 files changed, 73 insertions(+), 235 deletions(-) diff --git a/Makefile b/Makefile index a97e6107d..86f172b65 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ constants: docker run -v $(curr_dir):/root -w /root --rm \ --entrypoint ./util/gen-p4-constants.py onosproject/fabric-p4test:latest \ -o /root/src/main/java/org/stratumproject/fabric/tna/behaviour/P4InfoConstants.java \ - p4info /root/src/main/resources/p4c-out/fabric-spgw-int/stratum_bf/mavericks_sde_9_2_0/p4info.txt + p4info /root/src/main/resources/p4c-out/fabric-spgw-int/mavericks_sde_9_2_0/p4info.txt _mvn_package: $(info *** Building ONOS app...) diff --git a/README.md b/README.md index b5d9d1c3a..d01604cbc 100644 --- a/README.md +++ b/README.md @@ -141,8 +141,8 @@ new Tofino-specific pipeconfs in the system, depending on the `fabric-tna.p4` profiles compiled before and the Barefoot SDE/p4c version used: ``` -New pipeconf registered: org.stratumproject.fabric.stratum_bfrt.mavericks_sde_9_2_0 (fingerprint=...) -New pipeconf registered: org.stratumproject.fabric.stratum_bfrt.montara_sde_9_2_0 (fingerprint=...) +New pipeconf registered: org.stratumproject.fabric.mavericks_sde_9_2_0 (fingerprint=...) +New pipeconf registered: org.stratumproject.fabric.montara_sde_9_2_0 (fingerprint=...) ... ``` diff --git a/p4src/build.sh b/p4src/build.sh index f7c5f16ed..83d4b6c09 100755 --- a/p4src/build.sh +++ b/p4src/build.sh @@ -5,6 +5,7 @@ MAVERICKS_CPU_PORT=320 MONTARA_CPU_PORT=192 SDE_DOCKER_IMG=${SDE_DOCKER_IMG:-opennetworking/bf-sde:9.2.0} +PIPELINE_CONFIG_BUILDER_IMG=${PIPELINE_BUILD_IMG:-"stratumproject/stratum-bf-pipeline-builder@sha256:006db61b4c8797cc46f9008549b9d073ccfdc6c2e67641650fcb63afc318846a"} # DIR is this file directory. DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" @@ -42,25 +43,31 @@ SDE_VER=$( ${P4C_CMD} --version | cut -d' ' -f2 ) # shellcheck disable=SC2086 function base_build() { - pltf="sde_${SDE_VER//./_}" + output_dir="${P4C_OUT}/sde_${SDE_VER//./_}" echo "*** Compiling profile '${PROFILE}' for ${pltf}..." - echo "*** Output in ${P4C_OUT}/${pltf}" + echo "*** Output in ${output_dir}" p4c_flags="--auto-init-metadata" - mkdir -p ${P4C_OUT}/${pltf} + mkdir -p ${output_dir} ( $P4C_CMD --arch tna -g --create-graphs --verbose 2 \ - -o ${P4C_OUT}/${pltf} -I ${P4_SRC_DIR} \ + -o ${output_dir} -I ${P4_SRC_DIR} \ ${pp_flags} ${OTHER_PP_FLAGS} \ ${p4c_flags} \ - --p4runtime-files ${P4C_OUT}/${pltf}/p4info.txt \ + --p4runtime-files ${output_dir}/p4info.txt \ --p4runtime-force-std-externs \ ${DIR}/fabric_tna.p4 ) # Adds register information to p4info file # TODO: remove this part when compiler support it. if [[ "$PROFILE" == *int ]]; then - $P4INFO_PATCH_SHELL "cat ${DIR}/p4info-register.txt >> ${P4C_OUT}/${pltf}/p4info.txt" + $P4INFO_PATCH_SHELL "cat ${DIR}/p4info-register.txt >> ${output_dir}/p4info.txt" fi + + # Generate the pipeline config binary + docker run --rm -v "${output_dir}:${output_dir}" -w "${output_dir}" \ + ${PIPELINE_CONFIG_BUILDER_IMG} \ + -p4c_conf_file=./fabric_tna.conf \ + -bf_pipeline_config_binary_file=./pipeline_config.pb.bin } # shellcheck disable=SC2086 @@ -70,26 +77,10 @@ function gen_profile() { cpu_port=$2 # Copy only the relevant files to the pipeconf resources. - mkdir -p "${DEST_DIR}/stratum_bf/${pltf}/pipe" - mkdir -p "${DEST_DIR}/stratum_bfrt/${pltf}/pipe" - cp "${output_dir}/p4info.txt" "${DEST_DIR}/stratum_bf/${pltf}" - cp "${output_dir}/bfrt.json" "${DEST_DIR}/stratum_bf/${pltf}" - cp "${output_dir}/fabric_tna.conf" "${DEST_DIR}/stratum_bf/${pltf}" - cp "${output_dir}/pipe/context.json" "${DEST_DIR}/stratum_bf/${pltf}/pipe" - cp "${output_dir}/pipe/tofino.bin" "${DEST_DIR}/stratum_bf/${pltf}/pipe" - cp "${output_dir}/pipe/context.json" "${DEST_DIR}/stratum_bfrt/${pltf}/pipe/" - cp "${output_dir}/pipe/tofino.bin" "${DEST_DIR}/stratum_bfrt/${pltf}/pipe/" - echo "${cpu_port}" > "${DEST_DIR}/stratum_bf/${pltf}/cpu_port.txt" - - # New pipeline format which uses tar ball - mkdir -p "${DEST_DIR}/stratum_bfrt/${pltf}" - tar cf "pipeline.tar.bz2" -C "${DEST_DIR}/stratum_bf/${pltf}" . - mv "pipeline.tar.bz2" "${DEST_DIR}/stratum_bfrt/${pltf}/" - cp "${output_dir}/p4info.txt" "${DEST_DIR}/stratum_bfrt/${pltf}/" - echo "${cpu_port}" > "${DEST_DIR}/stratum_bfrt/${pltf}/cpu_port.txt" - - rm "${DEST_DIR}/stratum_bf/${pltf}/fabric_tna.conf" - + mkdir -p "${DEST_DIR}/${pltf}" + cp "${output_dir}/p4info.txt" "${DEST_DIR}/${pltf}" + echo "${cpu_port}" > "${DEST_DIR}/${pltf}/cpu_port.txt" + cp "${output_dir}/pipeline_config.pb.bin" "${DEST_DIR}/${pltf}/" echo } diff --git a/ptf/run/tm/Makefile b/ptf/run/tm/Makefile index 1255c9b86..55877129d 100644 --- a/ptf/run/tm/Makefile +++ b/ptf/run/tm/Makefile @@ -2,23 +2,12 @@ # SPDX-License-Identifier: ONF-Member-Only-1.0 # 320 cpu port is for mavericks (65Q) -DEVICE ?= stratum-bf - -DEVICE_CONFIG_BF := --tofino-bin /p4c-out/pipe/tofino.bin --tofino-ctx-json /p4c-out/pipe/context.json -DEVICE_CONFIG_BFRT := --tofino-pipeline-tar /p4c-out/pipeline.tar.bz2 - -ifeq ($(DEVICE),stratum-bfrt) -config := $(DEVICE_CONFIG_BFRT) -else -config := $(DEVICE_CONFIG_BF) -endif - define run_tests - python -u ptf_runner.py --device $(DEVICE) --port-map port_map.veth.json \ + python -u ptf_runner.py --port-map port_map.veth.json \ --ptf-dir fabric.ptf --cpu-port 320 --device-id 1 \ --grpc-addr "127.0.0.1:28000" \ --p4info /p4c-out/p4info.txt \ - $(config) \ + --tofino-pipeline-config /p4c-out/pipeline_config.pb.bin \ $(2) endef diff --git a/ptf/run/tm/run b/ptf/run/tm/run index e1345f7f5..cafa2c3a7 100755 --- a/ptf/run/tm/run +++ b/ptf/run/tm/run @@ -58,7 +58,7 @@ fi # Find Tofino compiled artifacts sdeVer_=$(echo "${SDE_VERSION}" | tr . _) # Replace dots with underscores -P4C_OUT=${FABRIC_TNA}/src/main/resources/p4c-out/${fabricProfile}/stratum_bfrt/mavericks_sde_${sdeVer_} +P4C_OUT=${FABRIC_TNA}/src/main/resources/p4c-out/${fabricProfile}/mavericks_sde_${sdeVer_} echo "*** Using P4 compiler output in ${P4C_OUT}..." # Fix a name for each container so we can stop them @@ -99,7 +99,7 @@ docker run --name ${tmRunName} -d -t --privileged \ "${SDE_DOCKER_IMG}" sleep 5 -# Run stratum_bf +# Run Stratum container echo "*** Starting ${stratumBfRunName} (from ${STRATUM_BF_DOCKER_IMG})..." docker run --name ${stratumBfRunName} -d --privileged \ --network "container:${tmRunName}" \ @@ -110,12 +110,6 @@ docker run --name ${stratumBfRunName} -d --privileged \ sleep 5 wait_for ${stratumBfRunName} 28000 600 -testerDevice="stratum-bf" -if [[ "${STRATUM_BF_DOCKER_IMG}" == *"stratum-bfrt"* ]]; then - echo "*** Detected stratum-bfrt..." - testerDevice="stratum-bfrt" -fi - echo "*** Starting ${testerRunName}..." # Do not attach stdin if running in an environment without it (e.g., Jenkins) it=$(test -t 0 && echo "-it" || echo "-t") @@ -123,7 +117,6 @@ docker run --name ${testerRunName} ${it} --privileged --rm \ --network "container:${tmRunName}" \ -v "${FP4TEST_ROOT}":/fabric-p4test \ -v "${P4C_OUT}":/p4c-out \ - -e DEVICE=${testerDevice} \ -e PTF_FILTER=${PTF_FILTER} \ --entrypoint /fabric-p4test/run/tm/start_test.sh \ "${TESTER_DOCKER_IMG}" \ diff --git a/ptf/run/tv/Makefile b/ptf/run/tv/Makefile index 1f311c251..c2697977f 100644 --- a/ptf/run/tv/Makefile +++ b/ptf/run/tv/Makefile @@ -1,28 +1,18 @@ # Copyright 2020-present Open Networking Foundation # SPDX-License-Identifier: ONF-Member-Only-1.0 -DEVICE ?= stratum-bf PORTMAP ?= port_map.veth.json GRPCADDR ?= 127.0.0.1:28000 CPUPORT ?= 320 -DEVICE_CONFIG_BF := --tofino-bin /p4c-out/pipe/tofino.bin --tofino-ctx-json /p4c-out/pipe/context.json -DEVICE_CONFIG_BFRT := --tofino-pipeline-tar /p4c-out/pipeline.tar.bz2 - -ifeq ($(DEVICE),stratum-bfrt) -config := $(DEVICE_CONFIG_BFRT) -else -config := $(DEVICE_CONFIG_BF) -endif - define run_tests -python -u ptf_runner.py --device $(DEVICE) --port-map $(PORTMAP) \ - --ptf-dir fabric.ptf --cpu-port $(CPUPORT) --device-id 1 \ - --grpc-addr $(GRPCADDR) \ - --p4info /p4c-out/p4info.txt \ - $(config) \ - --generate-tv \ - $(2) + python -u ptf_runner.py --port-map $(PORTMAP) \ + --ptf-dir fabric.ptf --cpu-port $(CPUPORT) --device-id 1 \ + --grpc-addr $(GRPCADDR) \ + --p4info /p4c-out/p4info.txt \ + --tofino-pipeline-config /p4c-out/pipeline_config.pb.bin \ + --generate-tv \ + $(2) endef .DEFAULT_GOAL := all diff --git a/ptf/run/tv/run b/ptf/run/tv/run index 25178d838..ddef88044 100755 --- a/ptf/run/tv/run +++ b/ptf/run/tv/run @@ -32,12 +32,12 @@ fi # Find Tofino compiled artifacts sdeVer_=$(echo "${SDE_VERSION}" | tr . _) # Replace dots with underscores -#P4C_OUT=${FABRIC_TNA}/src/main/resources/p4c-out/${fabricProfile}/stratum_bfrt/montara_sde_${sdeVer_} -P4C_OUT=${FABRIC_TNA}/src/main/resources/p4c-out/${fabricProfile}/stratum_bfrt/mavericks_sde_${sdeVer_} +#P4C_OUT=${FABRIC_TNA}/src/main/resources/p4c-out/${fabricProfile}/montara_sde_${sdeVer_} +P4C_OUT=${FABRIC_TNA}/src/main/resources/p4c-out/${fabricProfile}/mavericks_sde_${sdeVer_} echo "*** Using P4 compiler output in ${P4C_OUT}..." -if [ ! -f "${P4C_OUT}"/pipe/tofino.bin ]; then - echo "ERROR: missing tofino.bin in ${P4C_OUT}" +if [ ! -f "${P4C_OUT}"/pipeline_config.pb.bin ]; then + echo "ERROR: missing pipeline_config.pb.bin in ${P4C_OUT}" exit 1 fi diff --git a/ptf/tests/ptf/base_test.py b/ptf/tests/ptf/base_test.py index 537b2231b..01dd99ff5 100644 --- a/ptf/tests/ptf/base_test.py +++ b/ptf/tests/ptf/base_test.py @@ -199,10 +199,6 @@ def setUp(self): if self.cpu_port is None: self.fail("CPU port is not set") - self.device = testutils.test_param_get("device") - if self.device is None: - self.fail("Device is not set") - pltfm = testutils.test_param_get("pltfm") if pltfm is not None and pltfm == 'hw' and getattr(self, "_skip_on_hw", False): raise SkipTest("Skipping test in HW") @@ -239,9 +235,6 @@ def setUp(self): self.stub = p4runtime_pb2_grpc.P4RuntimeStub(self.channel) self.set_up_stream() - def is_bmv2(self): - return self.device is "bmv2" - # In order to make writing tests easier, we accept any suffix that uniquely # identifies the object among p4info objects of the same type. def import_p4info_names(self): diff --git a/ptf/tests/ptf/ptf_runner.py b/ptf/tests/ptf/ptf_runner.py index 015ad55ad..1585f64de 100755 --- a/ptf/tests/ptf/ptf_runner.py +++ b/ptf/tests/ptf/ptf_runner.py @@ -51,39 +51,14 @@ def check_ifaces(ifaces): return ifaces <= present_ifaces -def build_bmv2_config(bmv2_json_path): - """ - Builds the device config for BMv2 - """ - with open(bmv2_json_path) as f: - device_config = f.read() - return device_config - - -def build_tofino_config(prog_name, bin_path, cxt_json_path): - with open(bin_path, 'rb') as bin_f: - with open(cxt_json_path, 'r') as cxt_json_f: - device_config = "" - device_config += struct.pack("// - private static final String P4C_RES_BASE_PATH = P4C_OUT_PATH + "/%s/%s/%s/"; + // p4c-out// + private static final String P4C_RES_BASE_PATH = P4C_OUT_PATH + "/%s/%s/"; private static final String SEP = File.separator; @Reference(cardinality = ReferenceCardinality.MANDATORY) @@ -63,13 +63,9 @@ public class PipeconfLoader { private Collection pipeconfs; - private static final String STRATUM_BF = "stratum_bf"; - private static final String STRATUM_BFRT = "stratum_bfrt"; private static final String P4INFO_TXT = "p4info.txt"; private static final String CPU_PORT_TXT = "cpu_port.txt"; - private static final String TOFINO_BIN = "pipe/tofino.bin"; - private static final String TOFINO_CTX_JSON = "pipe/context.json"; - private static final String PIPELINE_TAR = "pipeline.tar.bz2"; + private static final String PIPELINE_CONFIG = "pipeline_config.pb.bin"; private static final String INT_PROFILE_SUFFIX = "-int"; private static final String FULL_PROFILE_SUFFIX = "-full"; @@ -109,35 +105,21 @@ private Collection buildAllPipeconfs() { private PiPipeconf buildPipeconfFromPath(String path) { String[] pieces = path.split(SEP); - // We expect a path of 4 elements, e.g. - // p4c-out/// - if (pieces.length != 4) { + // We expect a path of 3 elements, e.g. + // p4c-out// + // p4c-out/fabric/mavericks_sde_9_2_0 + if (pieces.length != 3) { return null; } String profile = pieces[1]; - String target = pieces[2]; - String platform = pieces[3]; + String platform = pieces[2]; final DefaultPiPipeconf.Builder builder; - if (target.equals(STRATUM_BF)) { - try { - builder = stratumBfPipeconf(profile, platform); - } catch (FileNotFoundException e) { - log.warn("Unable to build pipeconf at {} because file is missing: {}", - path, e.getMessage()); - return null; - } - } else if (target.equals(STRATUM_BFRT)) { - try { - builder = stratumBfRtPipeconf(profile, platform); - } catch (FileNotFoundException e) { - log.warn("Unable to build pipeconf at {} because file is missing: {}", - path, e.getMessage()); - return null; - } - } else { - log.warn("Unknown target '{}', skipping pipeconf build at '{}'...", - target, path); + try { + builder = buildPipeconf(profile, platform); + } catch (FileNotFoundException e) { + log.warn("Got error when building the pipeconf with profile {} and platform {}: {}", + profile, platform, e.getMessage()); return null; } @@ -153,56 +135,29 @@ private PiPipeconf buildPipeconfFromPath(String path) { return builder.build(); } - private DefaultPiPipeconf.Builder stratumBfPipeconf(String profile, String platform) + private DefaultPiPipeconf.Builder buildPipeconf(String profile, String platform) throws FileNotFoundException { - final URL tofinoBinUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + TOFINO_BIN, profile, STRATUM_BF, platform)); - final URL contextJsonUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + TOFINO_CTX_JSON, profile, STRATUM_BF, platform)); + final URL tofinoPipelineConfigUrl = this.getClass().getResource(format( + P4C_RES_BASE_PATH + PIPELINE_CONFIG, profile, platform)); final URL p4InfoUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + P4INFO_TXT, profile, STRATUM_BF, platform)); + P4C_RES_BASE_PATH + P4INFO_TXT, profile, platform)); final URL cpuPortUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, STRATUM_BF, platform)); + P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, platform)); - checkFileExists(tofinoBinUrl, TOFINO_BIN); - checkFileExists(contextJsonUrl, TOFINO_CTX_JSON); + checkFileExists(tofinoPipelineConfigUrl, PIPELINE_CONFIG); checkFileExists(p4InfoUrl, P4INFO_TXT); checkFileExists(cpuPortUrl, CPU_PORT_TXT); return DefaultPiPipeconf.builder() .withId(new PiPipeconfId(format( - "%s.%s.stratum_bf.%s", BASE_PIPECONF_ID, profile, platform))) + "%s.%s.%s", BASE_PIPECONF_ID, profile, platform))) .withPipelineModel(parseP4Info(p4InfoUrl)) - .addExtension(ExtensionType.TOFINO_BIN, tofinoBinUrl) - .addExtension(ExtensionType.TOFINO_CONTEXT_JSON, contextJsonUrl) + .addExtension(ExtensionType.RAW_DEVICE_CONFIG, tofinoPipelineConfigUrl) .addExtension(ExtensionType.P4_INFO_TEXT, p4InfoUrl) .addExtension(ExtensionType.CPU_PORT_TXT, cpuPortUrl); } - private DefaultPiPipeconf.Builder stratumBfRtPipeconf(String profile, String platform) - throws FileNotFoundException { - - final URL tofinoPipelineTarUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + PIPELINE_TAR, profile, STRATUM_BFRT, platform)); - final URL p4InfoUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + P4INFO_TXT, profile, STRATUM_BFRT, platform)); - final URL cpuPortUrl = this.getClass().getResource(format( - P4C_RES_BASE_PATH + CPU_PORT_TXT, profile, STRATUM_BFRT, platform)); - - checkFileExists(tofinoPipelineTarUrl, PIPELINE_TAR); - checkFileExists(p4InfoUrl, P4INFO_TXT); - checkFileExists(cpuPortUrl, CPU_PORT_TXT); - - return DefaultPiPipeconf.builder() - .withId(new PiPipeconfId(format( - "%s.%s.stratum_bfrt.%s", BASE_PIPECONF_ID, profile, platform))) - .withPipelineModel(parseP4Info(p4InfoUrl)) - .addExtension(ExtensionType.RAW_DEVICE_CONFIG, tofinoPipelineTarUrl) - .addExtension(ExtensionType.P4_INFO_TEXT, p4InfoUrl) - .addExtension(ExtensionType.CPU_PORT_TXT, cpuPortUrl); - } - private void checkFileExists(URL url, String name) throws FileNotFoundException { if (url == null) {