diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 000000000..3bad6b4ab --- /dev/null +++ b/.bazelrc @@ -0,0 +1,14 @@ +build --cxxopt=-std=c++17 +build --host_cxxopt=-std=c++17 + +build --copt=-fPIC + +build --copt=-Wall +build --copt=-Wextra + +build --per_file_copt=external/.*@-Wno-error + +build --linkopt=-L/usr/local/lib +build --linkopt=-Wl,-rpath,/usr/local/lib + +test --test_output=errors diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..6d2890793 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +8.5.0 diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml new file mode 100644 index 000000000..d210a281c --- /dev/null +++ b/.github/workflows/bazel.yml @@ -0,0 +1,42 @@ +name: "Bazel Build" + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build_and_test: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install system dependencies + run: sudo bash install_deps_ubuntu_22.04.sh + + - name: Setup Buildifier + run: | + sudo curl -L https://github.com/bazelbuild/buildtools/releases/download/v8.5.1/buildifier-linux-amd64 -o /usr/bin/buildifier --fail + sudo chmod +x /usr/bin/buildifier + + - name: Run Buildifier + run: | + BZL_FILES=$(find . -name *BUILD* -o -name '*bzl' -o -name '*.bazel') + if ! buildifier --mode=check $BZL_FILES; then + echo "::error::Buildifier formatting issues found." + echo "::group::Buildifier Diff" + buildifier --mode=diff $BZL_FILES + echo "::endgroup::" + exit 1 + else + echo "All files are formatted correctly." + fi + + - name: Build + run: bazel build //targets/simple_switch_grpc:simple_switch_grpc + + - name: Test + run: bazel test //targets/simple_switch_grpc/tests/... diff --git a/.gitignore b/.gitignore index fa3f77839..f1b50dcfc 100644 --- a/.gitignore +++ b/.gitignore @@ -104,3 +104,7 @@ VERSION-build core vgcore* + +# Bazel build outputs +/bazel-* +MODULE.bazel.lock diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 000000000..ddf4d7d70 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,50 @@ +load("@bazel_skylib//rules:expand_template.bzl", "expand_template") +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +expand_template( + name = "config_h", + out = "include/bm/config.h", + substitutions = { + # disabled + "#cmakedefine BM_DEBUG_ON @BM_DEBUG_ON@": "/* #undef BM_DEBUG_ON */", + # enabled + "#cmakedefine BM_ELOG_ON @BM_ELOG_ON@": "#define BM_ELOG_ON 1", + "#cmakedefine BM_ENABLE_MODULES @BM_ENABLE_MODULES@": "#define BM_ENABLE_MODULES 1", + "#cmakedefine BM_HAVE_ALGORITHM @BM_HAVE_ALGORITHM@": "#define BM_HAVE_ALGORITHM 1", + "#cmakedefine BM_HAVE_ARRAY @BM_HAVE_ARRAY@": "#define BM_HAVE_ARRAY 1", + "#cmakedefine BM_HAVE_CASSERT @BM_HAVE_CASSERT@": "#define BM_HAVE_CASSERT 1", + "#cmakedefine BM_HAVE_CMATH @BM_HAVE_CMATH@": "#define BM_HAVE_CMATH 1", + "#cmakedefine BM_HAVE_CSTDIO @BM_HAVE_CSTDIO@": "#define BM_HAVE_CSTDIO 1", + "#cmakedefine BM_HAVE_CTIME @BM_HAVE_CTIME@": "#define BM_HAVE_CTIME 1", + "#cmakedefine BM_HAVE_DLFCN_H @BM_HAVE_DLFCN_H@": "#define BM_HAVE_DLFCN_H 1", + "#cmakedefine BM_HAVE_DLOPEN @BM_HAVE_DLOPEN@": "#define BM_HAVE_DLOPEN 1", + "#cmakedefine BM_HAVE_QUEUE @BM_HAVE_QUEUE@": "#define BM_HAVE_QUEUE 1", + "#cmakedefine BM_HAVE_STRING @BM_HAVE_STRING@": "#define BM_HAVE_STRING 1", + "#cmakedefine BM_HAVE_SYS_STAT_H @BM_HAVE_SYS_STAT_H@": "#define BM_HAVE_SYS_STAT_H 1", + "#cmakedefine BM_HAVE_SYS_TYPES_H @BM_HAVE_SYS_TYPES_H@": "#define BM_HAVE_SYS_TYPES_H 1", + # disabled + "#cmakedefine BM_HAVE_THRIFT_STDCXX_H @BM_HAVE_THRIFT_STDCXX_H@": "/* #undef BM_HAVE_THRIFT_STDCXX_H */", + # enabled + "#cmakedefine BM_HAVE_TUPLE @BM_HAVE_TUPLE@": "#define BM_HAVE_TUPLE 1", + "#cmakedefine BM_HAVE_UNISTD_H @BM_HAVE_UNISTD_H@": "#define BM_HAVE_UNISTD_H 1", + "#cmakedefine BM_HAVE_UNORDERED_MAP @BM_HAVE_UNORDERED_MAP@": "#define BM_HAVE_UNORDERED_MAP 1", + "#cmakedefine BM_HAVE_UTILITY @BM_HAVE_UTILITY@": "#define BM_HAVE_UTILITY 1", + "#cmakedefine BM_HAVE_VECTOR @BM_HAVE_VECTOR@": "#define BM_HAVE_VECTOR 1", + "#cmakedefine BM_LOG_DEBUG_ON @BM_LOG_DEBUG_ON@": "#define BM_LOG_DEBUG_ON 1", + "#cmakedefine BM_LOG_TRACE_ON @BM_LOG_TRACE_ON@": "#define BM_LOG_TRACE_ON 1", + "#cmakedefine BM_NANOMSG_ON @BM_NANOMSG_ON@": "#define BM_NANOMSG_ON 1", + # disabled + "#cmakedefine BM_THRIFT_ON @BM_THRIFT_ON@": "/* #undef BM_THRIFT_ON */", + "#cmakedefine BM_THRIFT_VERSION @BM_THRIFT_VERSION@": "/* #undef BM_THRIFT_VERSION */", + # enabled + "#cmakedefine BM_WP4_16_STACKS @BM_WP4_16_STACKS@": "#define BM_WP4_16_STACKS 1", + }, + template = "include/bm/config.h.in", +) + +cc_library( + name = "bm_headers", + hdrs = glob(["include/bm/**/*.h"]) + [":config_h"], + includes = ["include"], + visibility = ["//visibility:public"], +) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 000000000..b4edd51ff --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,13 @@ +module( + name = "behavioral-model", + version = "1.15.0", + bazel_compatibility = [">=7.2.1"], +) + +bazel_dep(name = "bazel_skylib", version = "1.9.0") +bazel_dep(name = "rules_cc", version = "0.2.17") + +bazel_dep(name = "googletest", version = "1.17.0", dev_dependency = True) + +ubuntu2204 = use_extension("//bazel:ubuntu2204.bzl", "ubuntu2204") +use_repo(ubuntu2204, "ubuntu2204") diff --git a/PI/BUILD.bazel b/PI/BUILD.bazel new file mode 100644 index 000000000..3defd6822 --- /dev/null +++ b/PI/BUILD.bazel @@ -0,0 +1,19 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +cc_library( + name = "bmpi", + srcs = glob([ + "src/*.cpp", + "src/*.h", + ]), + hdrs = ["bm/PI/pi.h"], + copts = ["-Wno-error=redundant-move"], + includes = ["."], + local_defines = ["WITH_SIMPLE_SWITCH"], + visibility = ["//visibility:public"], + deps = [ + "//:bm_headers", + "//targets/simple_switch:simpleswitch", + ], + alwayslink = True, +) diff --git a/bazel/BUILD.bazel b/bazel/BUILD.bazel new file mode 100644 index 000000000..e69de29bb diff --git a/bazel/ubuntu2204.bzl b/bazel/ubuntu2204.bzl new file mode 100644 index 000000000..37799c635 --- /dev/null +++ b/bazel/ubuntu2204.bzl @@ -0,0 +1,114 @@ +""" +Module extension for system-installed libraries. +""" + +def _ubuntu2204_impl(rctx): + rctx.file("BUILD.bazel", """ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +# p4lang/PI libraries (installed via apt: p4lang-pi) +cc_library( + name = "pi", + linkopts = ["-lpi"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "pifeproto", + linkopts = ["-lpifeproto"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "pigrpcserver", + linkopts = ["-lpigrpcserver"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "pip4info", + linkopts = ["-lpip4info"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "piprotogrpc", + linkopts = ["-lpiprotogrpc"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "piprotobuf", + linkopts = ["-lpiprotobuf"], + visibility = ["//visibility:public"], +) + +# Boost libraries +cc_library( + name = "boost_program_options", + linkopts = ["-lboost_program_options"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "boost_filesystem", + linkopts = ["-lboost_filesystem"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "boost_thread", + linkopts = ["-lboost_thread"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "boost_system", + linkopts = ["-lboost_system"], + visibility = ["//visibility:public"], +) + +# GMP (GNU Multiple Precision) +cc_library( + name = "gmp", + linkopts = ["-lgmp"], + visibility = ["//visibility:public"], +) + +# PCAP +cc_library( + name = "pcap", + linkopts = ["-lpcap"], + visibility = ["//visibility:public"], +) + +# nanomsg +cc_library( + name = "nanomsg", + linkopts = ["-lnanomsg"], + visibility = ["//visibility:public"], +) + +# grpc +cc_library( + name = "grpc", + linkopts = [ + "-lgrpc++", + "-lgrpc", + "-lprotobuf", + "-lgpr", + ], + visibility = ["//visibility:public"], +) +""") + +_ubuntu2204_repo = repository_rule( + implementation = _ubuntu2204_impl, +) + +def _ubuntu2204_ext_impl(_): + _ubuntu2204_repo(name = "ubuntu2204") + +ubuntu2204 = module_extension( + implementation = _ubuntu2204_ext_impl, +) diff --git a/install_deps_ubuntu_22.04.sh b/install_deps_ubuntu_22.04.sh index 9ac35b871..40f4ada92 100755 --- a/install_deps_ubuntu_22.04.sh +++ b/install_deps_ubuntu_22.04.sh @@ -3,8 +3,7 @@ set -e apt-get update apt-get install -y curl gnupg -echo 'deb http://download.opensuse.org/repositories/home:/p4lang/xUbuntu_22.04/ /' | tee /etc/apt/sources.list.d/home:p4lang.list -curl -fsSL https://download.opensuse.org/repositories/home:p4lang/xUbuntu_22.04/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_p4lang.gpg > /dev/null +echo 'deb [trusted=yes] http://download.opensuse.org/repositories/home:/p4lang/xUbuntu_22.04/ /' | tee /etc/apt/sources.list.d/home:p4lang.list apt-get update diff --git a/services/BUILD.bazel b/services/BUILD.bazel new file mode 100644 index 000000000..544c498b7 --- /dev/null +++ b/services/BUILD.bazel @@ -0,0 +1,28 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +genrule( + name = "dataplane_interface_codegen", + srcs = ["p4/bm/dataplane_interface.proto"], + outs = [ + "p4/bm/dataplane_interface.pb.h", + "p4/bm/dataplane_interface.pb.cc", + "p4/bm/dataplane_interface.grpc.pb.h", + "p4/bm/dataplane_interface.grpc.pb.cc", + ], + cmd = "protoc -Iservices --cpp_out=$(RULEDIR) --grpc_out=$(RULEDIR) --plugin=protoc-gen-grpc=$$(which grpc_cpp_plugin) $(location p4/bm/dataplane_interface.proto)", +) + +cc_library( + name = "bm_grpc_dataplane", + srcs = [ + "p4/bm/dataplane_interface.grpc.pb.cc", + "p4/bm/dataplane_interface.pb.cc", + ], + hdrs = [ + "p4/bm/dataplane_interface.grpc.pb.h", + "p4/bm/dataplane_interface.pb.h", + ], + includes = ["."], + visibility = ["//visibility:public"], + deps = ["@ubuntu2204//:grpc"], +) diff --git a/src/BMI/BUILD.bazel b/src/BMI/BUILD.bazel new file mode 100644 index 000000000..bcefd2d31 --- /dev/null +++ b/src/BMI/BUILD.bazel @@ -0,0 +1,17 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +cc_library( + name = "bmi", + srcs = [ + "bmi_interface.c", + "bmi_port.c", + ], + hdrs = [ + "BMI/bmi_port.h", + "bmi_interface.h", + ], + includes = ["."], + local_defines = ["WITH_PCAP_FIX"], + visibility = ["//visibility:public"], + deps = ["@ubuntu2204//:pcap"], +) diff --git a/src/bm_sim/BUILD.bazel b/src/bm_sim/BUILD.bazel new file mode 100644 index 000000000..4c9c7b4a2 --- /dev/null +++ b/src/bm_sim/BUILD.bazel @@ -0,0 +1,31 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +genrule( + name = "version_cpp", + srcs = ["version.cpp.in"], + outs = ["version.cpp"], + cmd = "sed 's/@BM_VERSION@/1.15.0/' $< > $@", +) + +cc_library( + name = "bmsim", + srcs = glob([ + "*.cpp", + "*.c", + "*.h", + "core/*.cpp", + ]) + [":version_cpp"], + copts = ["-Isrc/bm_sim"], + linkopts = ["-ldl"], + visibility = ["//visibility:public"], + deps = [ + "//:bm_headers", + "//src/BMI:bmi", + "//third_party:jsoncpp", + "//third_party:spdlog", + "@ubuntu2204//:boost_thread", + "@ubuntu2204//:gmp", + "@ubuntu2204//:nanomsg", + "@ubuntu2204//:pcap", + ], +) diff --git a/targets/simple_switch/BUILD.bazel b/targets/simple_switch/BUILD.bazel new file mode 100644 index 000000000..5df55fc8f --- /dev/null +++ b/targets/simple_switch/BUILD.bazel @@ -0,0 +1,23 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +cc_library( + name = "simpleswitch", + srcs = [ + "primitives.cpp", + "simple_switch.cpp", + ], + hdrs = [ + "register_access.h", + "simple_switch.h", + ], + includes = ["."], + visibility = ["//visibility:public"], + deps = [ + "//:bm_headers", + "//src/BMI:bmi", + "//src/bm_sim:bmsim", + "//third_party:jsoncpp", + "@ubuntu2204//:boost_filesystem", + "@ubuntu2204//:boost_program_options", + ], +) diff --git a/targets/simple_switch_grpc/BUILD.bazel b/targets/simple_switch_grpc/BUILD.bazel new file mode 100644 index 000000000..089f16e08 --- /dev/null +++ b/targets/simple_switch_grpc/BUILD.bazel @@ -0,0 +1,32 @@ +load("@rules_cc//cc:cc_binary.bzl", "cc_binary") +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +cc_library( + name = "simpleswitchgrpc", + srcs = ["switch_runner.cpp"], + hdrs = ["switch_runner.h"], + includes = ["."], + visibility = ["//visibility:public"], + deps = [ + "//:bm_headers", + "//PI:bmpi", + "//services:bm_grpc_dataplane", + "//targets/simple_switch:simpleswitch", + "@ubuntu2204//:grpc", + "@ubuntu2204//:pi", + "@ubuntu2204//:pifeproto", + "@ubuntu2204//:pigrpcserver", + "@ubuntu2204//:pip4info", + "@ubuntu2204//:piprotobuf", + "@ubuntu2204//:piprotogrpc", + ], +) + +cc_binary( + name = "simple_switch_grpc", + srcs = ["main.cpp"], + deps = [ + ":simpleswitchgrpc", + "//:bm_headers", + ], +) diff --git a/targets/simple_switch_grpc/tests/BUILD.bazel b/targets/simple_switch_grpc/tests/BUILD.bazel new file mode 100644 index 000000000..fd17ae3b5 --- /dev/null +++ b/targets/simple_switch_grpc/tests/BUILD.bazel @@ -0,0 +1,55 @@ +load("@rules_cc//cc:cc_test.bzl", "cc_test") + +_COMMON_SRCS = [ + "base_test.cpp", + "base_test.h", + "main.cpp", + "utils.cpp", + "utils.h", +] + +_COMMON_DEPS = [ + "//targets/simple_switch_grpc:simpleswitchgrpc", + "//targets/simple_switch:simpleswitch", + "//services:bm_grpc_dataplane", + "@googletest//:gtest", + "@ubuntu2204//:grpc", + "@ubuntu2204//:pi", + "@ubuntu2204//:pifeproto", + "@ubuntu2204//:pigrpcserver", + "@ubuntu2204//:pip4info", + "@ubuntu2204//:piprotobuf", + "@ubuntu2204//:piprotogrpc", +] + +_COMMON_COPTS = [ + "-Wno-error=unused-result", + "-Wno-error=deprecated-declarations", +] + +_TESTS = [ + "test_basic", + "test_grpc_dp", + "test_packet_io", + "test_counter", + "test_meter", + "test_ternary", + "test_pre", + "test_digest", + "test_idle_timeout", + "test_action_profile", + "test_optional", +] + +[ + cc_test( + name = test, + srcs = _COMMON_SRCS + [test + ".cpp"], + copts = _COMMON_COPTS, + data = glob(["testdata/**"]), + defines = ["TESTDATADIR=\\\"" + package_name() + "/testdata\\\""], + tags = ["exclusive"], # tests share a gRPC port; must not run in parallel + deps = _COMMON_DEPS, + ) + for test in _TESTS +] diff --git a/third_party/BUILD.bazel b/third_party/BUILD.bazel new file mode 100644 index 000000000..f7e0fb517 --- /dev/null +++ b/third_party/BUILD.bazel @@ -0,0 +1,20 @@ +load("@rules_cc//cc:cc_library.bzl", "cc_library") + +cc_library( + name = "jsoncpp", + srcs = ["jsoncpp/src/jsoncpp.cpp"], + hdrs = ["jsoncpp/include/jsoncpp/json.h"], + includes = ["jsoncpp/include"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "spdlog", + hdrs = glob([ + "spdlog/bm/spdlog/*.h", + "spdlog/bm/spdlog/**/*.h", + "spdlog/bm/spdlog/**/*.cc", + ]), + includes = ["spdlog"], + visibility = ["//visibility:public"], +)