From 33f768354860d99beb390904fd99f58cb4a32560 Mon Sep 17 00:00:00 2001 From: "Vivi.W" Date: Fri, 31 Jan 2025 23:31:40 +0000 Subject: [PATCH 1/2] add comments to test script --- targets/bmv2/test/run_test_batch.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/targets/bmv2/test/run_test_batch.py b/targets/bmv2/test/run_test_batch.py index 5d7bc7d..e86aea1 100644 --- a/targets/bmv2/test/run_test_batch.py +++ b/targets/bmv2/test/run_test_batch.py @@ -1,3 +1,6 @@ +# This script takes a P4 program and runs it through the p4rtsmith tool to generate a config file. +# i.e. python run_test_batch.py -td -s + import argparse import logging import os @@ -73,6 +76,7 @@ def find_p4c_dir(): def run_tests(options: Options) -> int: + """Run the tests for the given options.""" config_file_path = "initial_config.txtpb" seed = options.seed From b3b394f2f150b3db1abde91414ed7120f007ea29 Mon Sep 17 00:00:00 2001 From: "Vivi.W" Date: Sat, 1 Feb 2025 02:05:14 +0000 Subject: [PATCH 2/2] fuzzer for bmv2 --- targets/bmv2/CMakeLists.txt | 64 +++++++++++++++++++++++++++++++++++++ targets/bmv2/run_bmv2.sh | 25 +++++++++++++++ targets/bmv2/send_config.py | 23 +++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 targets/bmv2/run_bmv2.sh create mode 100644 targets/bmv2/send_config.py diff --git a/targets/bmv2/CMakeLists.txt b/targets/bmv2/CMakeLists.txt index 84f9ca4..9ec8556 100644 --- a/targets/bmv2/CMakeLists.txt +++ b/targets/bmv2/CMakeLists.txt @@ -4,6 +4,17 @@ if(ENABLE_TESTING) include(test/P4Tests.cmake) endif() +find_program(RTSMITH_DRIVER p4rtsmith) +if (NOT RTSMITH_DRIVER) + message(FATAL_ERROR "RtSmith tool not found! Please ensure it is in your PATH.") +endif() + +# Find p4c (for JSON generation) +find_program(P4C_EXECUTABLE p4c) +if (NOT P4C_EXECUTABLE) + message(FATAL_ERROR "p4c not found! Please ensure it is in your PATH.") +endif() + # Source files for the main P4RtSmith. set(RTSMITH_SOURCES ${RTSMITH_SOURCES} @@ -16,3 +27,56 @@ set(RTSMITH_SOURCES set(RTSMITH_LIBS ${RTSMITH_LIBS} ${P4C_LIBRARIES} ${P4C_LIB_DEPS} ${CMAKE_THREAD_LIBS_INIT} PARENT_SCOPE) +set(CONFIG_DIR "${CMAKE_BINARY_DIR}/rtsmith/configs") +set(JSON_DIR "${CMAKE_BINARY_DIR}/rtsmith/jsons") + +file(MAKE_DIRECTORY ${CONFIG_DIR}) +file(MAKE_DIRECTORY ${JSON_DIR}) + +file(GLOB P4_PROGRAMS + # "${P4C_SOURCE_DIR}/testdata/p4_16_samples/*.p4" + # "${P4C_SOURCE_DIR}/testdata/p4_16_samples/dash/*.p4" + # "${P4C_SOURCE_DIR}/testdata/p4_16_samples/fabric_*/fabric.p4" + # "${P4C_SOURCE_DIR}/testdata/p4_16_samples/omec/*.p4" + # "${P4C_SOURCE_DIR}/testdata/p4_16_samples/pins/*.p4" + # "${flay_SOURCE_DIR}/targets/bmv2/test/programs/*.p4" + "${P4C_SOURCE_DIR}/testdata/p4_16_samples/dash/dash-pipeline-pna-dpdk.p4" +) + +set(ALL_DEPENDENCIES "") + +foreach(P4_PROGRAM ${P4_PROGRAMS}) + get_filename_component(PROGRAM_NAME ${P4_PROGRAM} NAME_WE) + + # Generate random config + set(CONFIG_FILE "${CONFIG_DIR}/${PROGRAM_NAME}_init_config.txtpb") + if (NOT CONFIG_FILE IN_LIST ALL_DEPENDENCIES) + add_custom_command( + OUTPUT ${CONFIG_FILE} + COMMAND ${RTSMITH_DRIVER} ${P4_PROGRAM} --target bmv2 --arch v1model --output-dir ${CONFIG_DIR} --config-name ${PROGRAM_NAME} --random-seed + DEPENDS ${P4_PROGRAM} + COMMENT "Generating random config for ${PROGRAM_NAME}" + ) + list(APPEND ALL_DEPENDENCIES ${CONFIG_FILE}) + endif() + + # Compile P4 program + set(JSON_FILE "${JSON_DIR}/${PROGRAM_NAME}.json") + if (NOT JSON_FILE IN_LIST ALL_DEPENDENCIES) + add_custom_command( + OUTPUT ${JSON_FILE} + COMMAND ${P4C_EXECUTABLE} --target bmv2 --arch v1model --output "${JSON_DIR}/${PROGRAM_NAME}.json" ${P4_PROGRAM} + DEPENDS ${P4_PROGRAM} + COMMENT "Compiling ${PROGRAM_NAME} to JSON" + ) + list(APPEND ALL_DEPENDENCIES ${JSON_FILE}) + endif() +endforeach() + +# Step 3: Run BMv2 with the config +add_custom_target( + run_all + COMMAND ${CMAKE_SOURCE_DIR}/run_bmv2.sh "${JSON_DIR}" "${CONFIG_DIR}" + DEPENDS ${ALL_DEPENDENCIES} + COMMENT "Running BMv2 for all programs" +) \ No newline at end of file diff --git a/targets/bmv2/run_bmv2.sh b/targets/bmv2/run_bmv2.sh new file mode 100644 index 0000000..9a7e923 --- /dev/null +++ b/targets/bmv2/run_bmv2.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Arguments +JSON_DIR=$1 +CONFIG_DIR=$1 + +# Loop through all JSON files in the output directory +for JSON_FILE in ${JSON_DIR}/*.json; do + # Get the program name (e.g., program1 from program1.json) + PROGRAM_NAME=$(basename ${JSON_FILE} .json) + + # Start BMv2 + simple_switch -i 0@veth0 -i 1@veth1 ${JSON_FILE} & + + # Wait for BMv2 to start + sleep 2 + + # Send the config file to BMv2 using P4Runtime + CONFIG_FILE="${CONFIG_DIR}/${PROGRAM_NAME}_init_config.txtpb" + if [[ -f ${CONFIG_FILE} ]]; then + python3 ${CMAKE_SOURCE_DIR}/send_config.py ${CONFIG_FILE} + else + echo "Config file not found: ${CONFIG_FILE}" + fi +done \ No newline at end of file diff --git a/targets/bmv2/send_config.py b/targets/bmv2/send_config.py new file mode 100644 index 0000000..4c07391 --- /dev/null +++ b/targets/bmv2/send_config.py @@ -0,0 +1,23 @@ +import sys +from p4runtime_lib import helper +from p4runtime_lib.switch import ShutdownAllSwitchConnections +from google.protobuf import text_format +from p4.v1 import p4runtime_pb2 + +# Load the config file +config_file = sys.argv[1] +with open(config_file, "r") as f: + config = f.read() + +# Parse the config +write_request = p4runtime_pb2.WriteRequest() +text_format.Parse(config, write_request) + +# Connect to BMv2 +switch = helper.P4RuntimeSwitchConnection("localhost", 50051, device_id=0) + +# Send the config +switch.WriteRequest(write_request) + +# Clean up +ShutdownAllSwitchConnections() \ No newline at end of file