├── py
├── p4
│ ├── __init__.py
│ ├── v1
│ │ ├── __init__.py
│ │ ├── p4data_pb2_grpc.py
│ │ └── p4runtime_pb2_grpc.py
│ └── config
│ │ ├── __init__.py
│ │ └── v1
│ │ ├── __init__.py
│ │ ├── p4info_pb2_grpc.py
│ │ └── p4types_pb2_grpc.py
├── LICENSE
├── README.md
├── setup.py
├── pyproject.toml
└── setup.cfg
├── rust
├── LICENSE
├── Cargo.toml
├── p4runtime-tonic
│ ├── src
│ │ └── lib.rs
│ ├── Cargo.toml
│ └── build.rs
├── p4runtime-prost
│ ├── Cargo.toml
│ ├── build.rs
│ └── src
│ │ └── lib.rs
└── README.md
├── docs
├── v1
│ ├── resources
│ │ ├── figs
│ │ │ ├── .gitignore
│ │ │ ├── error-report.odg
│ │ │ ├── reference-architecture.odg
│ │ │ ├── psa-metadata-translation.odg
│ │ │ ├── single-embedded-controller.odg
│ │ │ ├── single-remote-controller.odg
│ │ │ ├── embedded-plus-two-remote-controllers.odg
│ │ │ ├── embedded-plus-single-remote-controller.odg
│ │ │ └── embedded-plus-two-remote-ha-controllers.odg
│ │ ├── theme
│ │ │ ├── logo.png
│ │ │ ├── references.bib
│ │ │ └── p4-theme.yml
│ │ └── fonts
│ │ │ ├── LuxiMono
│ │ │ ├── luximb.ttf
│ │ │ ├── luximr.ttf
│ │ │ ├── luximbi.ttf
│ │ │ ├── luximri.ttf
│ │ │ └── LICENSE.txt
│ │ │ ├── Utopia
│ │ │ ├── utopia-bold.ttf
│ │ │ ├── utopia-italic.ttf
│ │ │ ├── utopia-regular.ttf
│ │ │ ├── utopia-bolditalic.ttf
│ │ │ └── LICENSE-utopia.txt
│ │ │ ├── OpenSans
│ │ │ ├── OpenSans-Bold.ttf
│ │ │ ├── OpenSans-Italic.ttf
│ │ │ ├── OpenSans-Regular.ttf
│ │ │ └── OpenSans-BoldItalic.ttf
│ │ │ └── verify-font
│ ├── libre-office.png
│ ├── Makefile
│ ├── README.md
│ └── guidance-for-generating-p4info.md
├── libre-office.png
├── tools
│ ├── fonts
│ │ ├── luximr.ttf
│ │ ├── UtopiaStd-Regular.otf
│ │ └── fix_helvetica.conf
│ ├── Makefile
│ ├── README.md
│ └── Dockerfile.asciidoc
└── README.md
├── bazel
└── example
│ ├── using-workspace
│ ├── .bazelversion
│ ├── BUILD.bazel
│ ├── .bazelrc
│ ├── hello_p4runtime.cc
│ └── WORKSPACE.bazel
│ └── using-bzlmod
│ ├── BUILD.bazel
│ ├── .bazelrc
│ ├── MODULE.bazel
│ └── hello_p4runtime.cc
├── .gitignore
├── proto
├── .bazelrc
├── WORKSPACE.bzlmod
├── update_google_rpc_status.sh
├── MODULE.bazel
├── WORKSPACE.bazel
├── google
│ └── rpc
│ │ └── status.proto
├── p4
│ ├── v1
│ │ └── p4data.proto
│ └── config
│ │ └── v1
│ │ ├── p4types.proto
│ │ └── p4info.proto
├── p4runtime_deps.bzl
├── BUILD.bazel
└── LICENSE
├── .github
├── workflows
│ ├── rust-build.yml
│ ├── codegen.yml
│ ├── spec.yml
│ ├── google-rpc-status-synced.yml
│ ├── any-branch-uploads.yml
│ ├── main-branch-uploads.yml
│ ├── tag-uploads.yml
│ └── bazel-build.yml
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── go.mod
├── CONTRIBUTING.md
├── CI
└── check_codegen.sh
├── codegen
├── update.sh
├── Dockerfile
└── compile_protos.sh
├── tools
├── asciidocint.conf.json
└── asciidoclint.py
├── go.sum
├── README.md
├── LICENSE
└── go
└── p4
└── v1
└── p4runtime_grpc.pb.go
/py/p4/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/py/LICENSE:
--------------------------------------------------------------------------------
1 | ../LICENSE
--------------------------------------------------------------------------------
/py/p4/v1/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/rust/LICENSE:
--------------------------------------------------------------------------------
1 | ../LICENSE
--------------------------------------------------------------------------------
/py/README.md:
--------------------------------------------------------------------------------
1 | ../README.md
--------------------------------------------------------------------------------
/py/p4/config/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/py/p4/config/v1/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/v1/resources/figs/.gitignore:
--------------------------------------------------------------------------------
1 | stem*
2 |
--------------------------------------------------------------------------------
/bazel/example/using-workspace/.bazelversion:
--------------------------------------------------------------------------------
1 | 7.4.1
2 |
--------------------------------------------------------------------------------
/docs/libre-office.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/libre-office.png
--------------------------------------------------------------------------------
/py/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 | if __name__ == "__main__":
4 | setuptools.setup()
5 |
--------------------------------------------------------------------------------
/docs/v1/libre-office.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/libre-office.png
--------------------------------------------------------------------------------
/docs/tools/fonts/luximr.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/tools/fonts/luximr.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/theme/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/theme/logo.png
--------------------------------------------------------------------------------
/docs/tools/fonts/UtopiaStd-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/tools/fonts/UtopiaStd-Regular.otf
--------------------------------------------------------------------------------
/rust/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = [
3 | "p4runtime-prost",
4 | "p4runtime-tonic",
5 | ]
6 | resolver = "2"
7 |
--------------------------------------------------------------------------------
/docs/v1/resources/figs/error-report.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/error-report.odg
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/LuxiMono/luximb.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/LuxiMono/luximb.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/LuxiMono/luximr.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/LuxiMono/luximr.ttf
--------------------------------------------------------------------------------
/docs/tools/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | docker build -t p4rt-asciidoc -f Dockerfile.asciidoc .
3 | docker tag p4rt-asciidoc p4lang/p4rt-asciidoc:latest
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/LuxiMono/luximbi.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/LuxiMono/luximbi.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/LuxiMono/luximri.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/LuxiMono/luximri.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/Utopia/utopia-bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/Utopia/utopia-bold.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/Utopia/utopia-italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/Utopia/utopia-italic.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/figs/reference-architecture.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/reference-architecture.odg
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/OpenSans/OpenSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/OpenSans/OpenSans-Bold.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/Utopia/utopia-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/Utopia/utopia-regular.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/figs/psa-metadata-translation.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/psa-metadata-translation.odg
--------------------------------------------------------------------------------
/docs/v1/resources/figs/single-embedded-controller.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/single-embedded-controller.odg
--------------------------------------------------------------------------------
/docs/v1/resources/figs/single-remote-controller.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/single-remote-controller.odg
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/OpenSans/OpenSans-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/OpenSans/OpenSans-Italic.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/OpenSans/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/OpenSans/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/Utopia/utopia-bolditalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/Utopia/utopia-bolditalic.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/OpenSans/OpenSans-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/fonts/OpenSans/OpenSans-BoldItalic.ttf
--------------------------------------------------------------------------------
/docs/v1/resources/figs/embedded-plus-two-remote-controllers.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/embedded-plus-two-remote-controllers.odg
--------------------------------------------------------------------------------
/docs/v1/resources/figs/embedded-plus-single-remote-controller.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/embedded-plus-single-remote-controller.odg
--------------------------------------------------------------------------------
/docs/v1/resources/figs/embedded-plus-two-remote-ha-controllers.odg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/p4lang/p4runtime/HEAD/docs/v1/resources/figs/embedded-plus-two-remote-ha-controllers.odg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Emacs
2 | *~
3 | docs/v1/build/
4 | .DS_Store
5 | build
6 | dist
7 | *.egg-info
8 | .eggs
9 |
10 | # Rust
11 | target/
12 |
13 | # Bazel
14 | bazel-*
15 | *.lock
16 |
--------------------------------------------------------------------------------
/py/p4/v1/p4data_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/py/p4/config/v1/p4info_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/py/p4/config/v1/p4types_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 |
--------------------------------------------------------------------------------
/rust/p4runtime-tonic/src/lib.rs:
--------------------------------------------------------------------------------
1 | /// The official Tonic API for all P4Runtime gRPC services, including clients and server code.
2 | pub mod p4 {
3 | pub mod v1 {
4 | tonic::include_proto!("p4.v1");
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/bazel/example/using-bzlmod/BUILD.bazel:
--------------------------------------------------------------------------------
1 | cc_binary(
2 | name = "hello_p4runtime",
3 | srcs = ["hello_p4runtime.cc"],
4 | deps = [
5 | "@com_github_p4lang_p4runtime//:p4info_cc_proto",
6 | "@com_google_protobuf//:protobuf",
7 | ]
8 | )
9 |
--------------------------------------------------------------------------------
/bazel/example/using-workspace/BUILD.bazel:
--------------------------------------------------------------------------------
1 | cc_binary(
2 | name = "hello_p4runtime",
3 | srcs = ["hello_p4runtime.cc"],
4 | deps = [
5 | "@com_github_p4lang_p4runtime//:p4info_cc_proto",
6 | "@com_google_protobuf//:protobuf",
7 | ]
8 | )
9 |
--------------------------------------------------------------------------------
/proto/.bazelrc:
--------------------------------------------------------------------------------
1 | # Use Bzlmod (`MODULE.bazel`) instead of `WORKSPACE.bazel`.
2 | common --enable_bzlmod
3 | common --noenable_workspace
4 |
5 | # Use C++17 (required for recent gRPC versions).
6 | build --cxxopt=-std=c++17
7 | build --host_cxxopt=-std=c++17
8 |
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/verify-font:
--------------------------------------------------------------------------------
1 | require 'ttfunk'
2 | require 'ttfunk/subset_collection'
3 |
4 | ttf_subsets = TTFunk::SubsetCollection.new TTFunk::File.open ARGV[0]
5 | (0...(ttf_subsets.instance_variable_get :@subsets).size).each {|idx| ttf_subsets[idx].encode }
--------------------------------------------------------------------------------
/bazel/example/using-bzlmod/.bazelrc:
--------------------------------------------------------------------------------
1 | # Use Bzlmod (`MODULE.bazel`) instead of `WORKSPACE.bazel`.
2 | common --enable_bzlmod
3 | common --noenable_workspace
4 |
5 | # Use C++17 (required for recent gRPC versions).
6 | build --cxxopt=-std=c++17
7 | build --host_cxxopt=-std=c++17
8 |
--------------------------------------------------------------------------------
/bazel/example/using-workspace/.bazelrc:
--------------------------------------------------------------------------------
1 | # Use `WORKSPACE.bazel` instead of bzlmod (`MODULE.bazel`).
2 | common --enable_workspace
3 | common --noenable_bzlmod
4 |
5 | # Use C++17 (required for recent gRPC versions).
6 | build --cxxopt=-std=c++17
7 | build --host_cxxopt=-std=c++17
8 |
--------------------------------------------------------------------------------
/proto/WORKSPACE.bzlmod:
--------------------------------------------------------------------------------
1 | # https://bazel.build/external/migration#workspace.bzlmod
2 | #
3 | # This file is intentionally empty. When bzlmod is enabled and this
4 | # file exists, the contents of WORKSPACE.bazel is ignored. This prevents
5 | # bzlmod builds from unintentionally depending on the WORKSPACE.bazel file.
6 |
--------------------------------------------------------------------------------
/.github/workflows/rust-build.yml:
--------------------------------------------------------------------------------
1 | name: "Rust build"
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 |
8 | jobs:
9 | build:
10 | runs-on: [ubuntu-latest]
11 | steps:
12 | - uses: actions/checkout@v5
13 | - run: cd rust && cargo build
14 | - run: cd rust && cargo test
15 |
--------------------------------------------------------------------------------
/py/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools",
4 | "setuptools_scm[toml]",
5 | "setuptools_scm_git_archive",
6 | "wheel",
7 | ]
8 | build-backend = 'setuptools.build_meta'
9 |
10 | [tool.setuptools_scm]
11 | root = "../"
12 | # use current tag and not next one
13 | version_scheme = "post-release"
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **This is to suggest improvements to the `P4Runtime` specification. For issues regarding a specific implementation, please open an issue with the appropriate repository (e.g. https://github.com/p4lang/behavioral-model or https://github.com/p4lang/PI for bmv2).**
8 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/p4lang/p4runtime
2 |
3 | go 1.20
4 |
5 | require (
6 | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
7 | google.golang.org/grpc v1.56.3
8 | google.golang.org/protobuf v1.33.0
9 | )
10 |
11 | require (
12 | github.com/golang/protobuf v1.5.3 // indirect
13 | golang.org/x/net v0.38.0 // indirect
14 | golang.org/x/sys v0.31.0 // indirect
15 | golang.org/x/text v0.23.0 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report an issue with the code / documents hosted in this repository
4 |
5 | ---
6 |
7 | **This is for reporting issues with the specification only. If you are running into a bug with a specific `P4Runtime` implementation, please open an issue with the appropriate repository (e.g. https://github.com/p4lang/behavioral-model or https://github.com/p4lang/PI for bmv2).**
8 |
--------------------------------------------------------------------------------
/docs/tools/fonts/fix_helvetica.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 |
11 | Helvetica
12 |
13 |
14 | sans-serif
15 |
16 |
17 | ~/.fonts
18 |
19 |
20 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | You can fork the repo and submit a pull request in Github.
2 |
3 | ### Apache CLA
4 |
5 | All developers must have signed the [P4.org](http://p4.org) CLA.
6 |
7 | ### AsciiDoc style checker
8 |
9 | The P4Runtime specification is written using [AsciiDoc](https://docs.asciidoctor.org/).
10 | We provide a lint tool to catch basic formatting issues and try to keep the spec uniform.
11 | The lint tool will be run as part of CI and patches cannot be merged until it returns success. You can
12 | run the lint tool locally with `./tools/asciidoclint.py`.
13 |
--------------------------------------------------------------------------------
/proto/update_google_rpc_status.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # Updates proto/google/rpc/status.proto with the latest version from the
4 | # official upstream repository.
5 | #
6 | # The file is very stable and hasn't changed in many years, but we enforce
7 | # freshness of this copy using a GitHub Actions workflow just in case.
8 |
9 | set -e
10 |
11 | STATUS_PROTO_URL="https://raw.githubusercontent.com/googleapis/googleapis/refs/heads/master/google/rpc/status.proto"
12 | THIS_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
13 |
14 | wget "$STATUS_PROTO_URL" -O "$THIS_DIR/google/rpc/status.proto"
15 |
--------------------------------------------------------------------------------
/.github/workflows/codegen.yml:
--------------------------------------------------------------------------------
1 | name: Check generated code
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - "*-dev"
8 | pull_request:
9 | branches:
10 | - main
11 | - "*-dev"
12 |
13 | jobs:
14 | check-codegen:
15 | runs-on: [ubuntu-latest]
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Compile protobufs
19 | run: |
20 | docker build -t p4runtime-ci -f codegen/Dockerfile .
21 | docker run -t p4runtime-ci /p4runtime/codegen/compile_protos.sh /tmp
22 | - name: Check codegen
23 | run: |
24 | ./CI/check_codegen.sh
25 |
--------------------------------------------------------------------------------
/rust/p4runtime-prost/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "p4runtime-prost"
3 | version = "1.4.0"
4 | edition = "2021"
5 | authors = ["P4 API Working Group "]
6 | description = "P4Runtime Specification - Protobuf message API (Prost)"
7 | categories = ["network-programming"]
8 | keywords = ["p4runtime", "protobuf"]
9 | license = "Apache-2.0"
10 | repository = "https://github.com/p4lang/p4runtime"
11 |
12 | [dependencies]
13 | prost = "0.14"
14 | prost-types = "0.14"
15 |
16 | [build-dependencies]
17 | protoc-prebuilt = "0.3" # To obtain `protoc` binary (the Protobuf compiler).
18 | prost-build = "0.14" # To generate API for Protobuf messages.
19 | walkdir = "2" # To find proto files.
20 |
--------------------------------------------------------------------------------
/bazel/example/using-bzlmod/MODULE.bazel:
--------------------------------------------------------------------------------
1 | bazel_dep(
2 | name = "p4runtime",
3 | repo_name = "com_github_p4lang_p4runtime",
4 | )
5 |
6 | # In your own project, you will likely want to use `http_archive` instead
7 | # of `local_repository` to load p4runtime.
8 | local_path_override(
9 | module_name = "p4runtime",
10 | path = "../../../proto",
11 | )
12 |
13 | # git_override(
14 | # module_name = "p4runtime",
15 | # strip_prefix = "p4runtime-1.4.1/proto",
16 | # urls = ["https://github.com/p4lang/p4runtime/archive/v1.4.1.tar.gz"],
17 | # # sha256 = "",
18 | # )
19 |
20 | bazel_dep(
21 | name = "protobuf",
22 | version = "29.1",
23 | repo_name = "com_google_protobuf",
24 | )
25 |
--------------------------------------------------------------------------------
/.github/workflows/spec.yml:
--------------------------------------------------------------------------------
1 | name: Build spec
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - '*-dev'
8 | pull_request:
9 | branches:
10 | - main
11 | - '*-dev'
12 |
13 | jobs:
14 | asciidoc-lint:
15 | runs-on: [ubuntu-latest]
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Run linter
19 | run: |
20 | ./tools/asciidoclint.py docs/v1/P4Runtime-Spec.adoc
21 |
22 | build-spec:
23 | runs-on: [ubuntu-latest]
24 | steps:
25 | - uses: actions/checkout@v3
26 | - name: Build spec
27 | run: |
28 | make -C docs/tools/
29 | docker run -v `pwd`/docs/v1:/usr/src/p4-spec p4lang/p4rt-asciidoc make build_spec_with_images
30 | ls docs/v1/build
31 |
--------------------------------------------------------------------------------
/.github/workflows/google-rpc-status-synced.yml:
--------------------------------------------------------------------------------
1 | name: Ensure google/rpc/status.proto is synced with upstream.
2 |
3 | on:
4 | pull_request:
5 |
6 | jobs:
7 | check-google-rpc-status-synced:
8 | runs-on: [ubuntu-latest]
9 | steps:
10 | - uses: actions/checkout@v5
11 | - run: ./proto/update_google_rpc_status.sh
12 | - run: |
13 | DIFF=$(git diff proto/google/rpc/status.proto)
14 | if [ -n "$DIFF" ]; then
15 | echo "$DIFF"
16 | echo ""
17 | echo "ERROR: proto/google/rpc/status.proto is not synced with upstream."
18 | echo "Please run ./proto/update_google_rpc_status.sh to fix it."
19 | exit 1
20 | fi
21 | echo "SUCCESS: proto/google/rpc/status.proto is synced with upstream."
22 |
--------------------------------------------------------------------------------
/CI/check_codegen.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eo pipefail
4 |
5 | THIS_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
6 |
7 | pushd "$THIS_DIR/.." >/dev/null
8 |
9 | rm -rf go/*
10 | rm -rf py/p4
11 | ./codegen/update.sh
12 |
13 | diff="$(git status --porcelain go go.mod go.sum)"
14 |
15 | if [ ! -z "$diff" ]; then
16 | echo "The generated Go files are not up-to-date"
17 | echo "You can regenerate them with './codegen/update.sh' and commit the changes"
18 | exit 1
19 | fi
20 |
21 | diff="$(git status --porcelain py)"
22 |
23 | if [ ! -z "$diff" ]; then
24 | echo "The generated Python files are not up-to-date"
25 | echo "You can regenerate them with './codegen/update.sh' and commit the changes"
26 | exit 1
27 | fi
28 |
29 | popd >/dev/null
30 |
--------------------------------------------------------------------------------
/py/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = p4runtime
3 | description = Python bindings for P4Runtime protocol
4 | long_description = file: README.md
5 | long_description_content_type = text/markdown; charset=UTF-8
6 | url = https://github.com/p4lang/p4runtime
7 | author = P4 API Working Group
8 | author_email = p4-api@lists.p4.org
9 | license = Apache-2.0
10 | license_file = LICENSE
11 | classifiers =
12 | License :: OSI Approved :: Apache Software License
13 | Programming Language :: Python
14 | Programming Language :: Python :: 3
15 |
16 | [options]
17 | packages = find:
18 | platforms = any
19 | python_requires = >=3.6
20 | setup_requires =
21 | setuptools_scm
22 | install_requires =
23 | protobuf >= 3.6.1
24 | grpcio >= 1.17.2
25 | googleapis-common-protos >= 1.52
26 |
--------------------------------------------------------------------------------
/bazel/example/using-bzlmod/hello_p4runtime.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "google/protobuf/text_format.h"
4 | #include "p4/config/v1/p4info.pb.h"
5 |
6 | using ::google::protobuf::TextFormat;
7 | using ::p4::config::v1::P4Info;
8 |
9 | int main() {
10 | P4Info p4info;
11 | TextFormat::ParseFromString(R"PROTO(
12 | tables {
13 | preamble {
14 | id: 10
15 | name: "Hello, P4Runtime!"
16 | }
17 | }
18 | )PROTO", &p4info);
19 | p4info.mutable_tables()->at(0).mutable_preamble()->set_id(42);
20 | std::cout << p4info.DebugString();
21 | }
22 |
--------------------------------------------------------------------------------
/bazel/example/using-workspace/hello_p4runtime.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "google/protobuf/text_format.h"
4 | #include "p4/config/v1/p4info.pb.h"
5 |
6 | using ::google::protobuf::TextFormat;
7 | using ::p4::config::v1::P4Info;
8 |
9 | int main() {
10 | P4Info p4info;
11 | TextFormat::ParseFromString(R"PROTO(
12 | tables {
13 | preamble {
14 | id: 10
15 | name: "Hello, P4Runtime!"
16 | }
17 | }
18 | )PROTO", &p4info);
19 | p4info.mutable_tables()->at(0).mutable_preamble()->set_id(42);
20 | std::cout << p4info.DebugString();
21 | }
22 |
--------------------------------------------------------------------------------
/rust/p4runtime-tonic/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "p4runtime-tonic"
3 | version = "1.4.0"
4 | edition = "2021"
5 | authors = ["P4 API Working Group "]
6 | description = "P4Runtime Specification - gRPC service definitions"
7 | categories = ["network-programming"]
8 | keywords = ["p4runtime", "grpc", "tonic"]
9 | license = "Apache-2.0"
10 | repository = "https://github.com/p4lang/p4runtime"
11 |
12 | [dependencies]
13 | p4runtime-prost = { path = "../p4runtime-prost" }
14 | prost = "0.14"
15 | prost-types = "0.14"
16 | tonic = "0.14"
17 | tonic-prost = "0.14"
18 |
19 | [build-dependencies]
20 | # To obtain `protoc` binary (the Protobuf compiler).
21 | protoc-prebuilt = "0.3"
22 | # To generate client/server code for grpc services.
23 | tonic-prost-build = "0.14"
24 | # To find proto files.
25 | walkdir = "2"
26 |
--------------------------------------------------------------------------------
/docs/v1/Makefile:
--------------------------------------------------------------------------------
1 | SPEC=P4Runtime-Spec
2 |
3 | ROUGE_STYLE=github
4 | ROUGE_CSS=style
5 |
6 | all: ${SPEC}.pdf ${SPEC}.html
7 |
8 | folder:
9 | mkdir -p build
10 |
11 | build:
12 |
13 | ${SPEC}.pdf: ${SPEC}.adoc images folder
14 | time asciidoctor-pdf -v \
15 | -a pdf-fontsdir=resources/fonts \
16 | -r asciidoctor-mathematical \
17 | -r asciidoctor-bibtex \
18 | -r asciidoctor-lists \
19 | -a rouge-style=$(ROUGE_STYLE) \
20 | -D build $<
21 |
22 | ${SPEC}.html: ${SPEC}.adoc images folder
23 | time asciidoctor -v \
24 | -r asciidoctor-mathematical \
25 | -r asciidoctor-bibtex \
26 | -r asciidoctor-lists \
27 | -a rouge-css=$(ROUGE_CSS) \
28 | -D build $<
29 |
30 | images:
31 | soffice --convert-to svg --outdir resources/figs resources/figs/*.odg > /dev/null 2>&1
32 | soffice --convert-to png --outdir resources/figs resources/figs/*.odg > /dev/null 2>&1
33 |
34 | build_spec_with_images: images all
35 |
36 | clean:
37 | /bin/rm -rf build resources/figs/*.png resources/figs/*.svg
--------------------------------------------------------------------------------
/docs/tools/README.md:
--------------------------------------------------------------------------------
1 | Dockerfile.asciidoc is used to build a Docker image which we use to render the
2 | P4Runtime specification (HTML & PDF) in CI. The image can also be used locally
3 | to build the specification without having to worry about installing all the
4 | dependencies yourself.
5 |
6 | Only maintainers of this repository need to build the Docker image when a new
7 | image needs to be pushed to dockerhub. Contributors to the specification can
8 | simply pull the image from dockerhub and don't have to worry about building the
9 | image themselves. If you are a maintainer and you need to upload a new version
10 | of the Docker image to to dockerhub, you will need the following commands:
11 | ```bash
12 | docker build -t p4rt-asciidoc -f Dockerfile.asciidoc .
13 | docker tag p4rt-asciidoc p4lang/p4rt-asciidoc:latest
14 | docker push p4lang/p4rt-asciidoc:latest
15 | ```
16 |
17 | Note that you need to have write permissions to the p4lang dockerhub repository
18 | to push the image (and you need to be logged in).
19 |
--------------------------------------------------------------------------------
/codegen/update.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | THIS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
6 |
7 | pushd "$THIS_DIR/.." >/dev/null
8 |
9 | docker build -t p4runtime-ci -f codegen/Dockerfile .
10 |
11 | tmpdir="$(mktemp -d /tmp/p4rt.XXXXXX)"
12 |
13 | docker run --rm \
14 | -v "$tmpdir:/tmp/gen" \
15 | p4runtime-ci /p4runtime/codegen/compile_protos.sh /tmp/gen
16 |
17 | # Go
18 | cp -r "$tmpdir"/go_out/github.com/p4lang/p4runtime/go/* go/
19 |
20 | # Python
21 | cp -r "$tmpdir"/py_out/p4 py/
22 | find py/p4 -type d -exec touch {}/__init__.py \;
23 |
24 | # Cleanup files owned by root user
25 | docker run --rm \
26 | -v "$tmpdir:/tmp/gen" \
27 | p4runtime-ci bash -c "rm -r /tmp/gen/*"
28 |
29 | docker run --rm -u "$(id -u):$(id -g)" \
30 | -e "GOCACHE=/tmp/gocache" \
31 | -e "GOPATH=/tmp/gopath" \
32 | -v "$(pwd):/p4runtime" \
33 | -w /p4runtime \
34 | golang:1.20 bash -c "go mod tidy"
35 |
36 | rm -rf "$tmpdir"
37 |
38 | popd >/dev/null
39 |
--------------------------------------------------------------------------------
/.github/workflows/any-branch-uploads.yml:
--------------------------------------------------------------------------------
1 | name: Any branch uploads
2 |
3 | on:
4 | push:
5 | branches:
6 | - '**'
7 |
8 | jobs:
9 | any-branch-uploads:
10 | if: ${{ github.repository == 'p4lang/p4runtime' }}
11 | runs-on: [ubuntu-latest]
12 | steps:
13 | - uses: actions/checkout@v3
14 | - name: Build spec
15 | run: |
16 | make -C docs/tools/
17 | docker run -v `pwd`/docs/v1:/usr/src/p4-spec p4lang/p4rt-asciidoc make
18 | ls docs/v1/build
19 | - name: Upload spec to S3 if needed
20 | if: ${{ github.actor != 'dependabot[bot]' }}
21 | uses: jakejarvis/s3-sync-action@v0.5.1
22 | with:
23 | args: --acl public-read --follow-symlinks --delete
24 | env:
25 | AWS_S3_BUCKET: 'p4runtime'
26 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
27 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
28 | AWS_REGION: 'us-west-2'
29 | SOURCE_DIR: 'docs/v1/build'
30 | DEST_DIR: ci/${{ github.ref_name }} # only runs for push events
31 |
--------------------------------------------------------------------------------
/codegen/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM p4lang/third-party:latest
2 | LABEL maintainer="P4 API Working Group "
3 | LABEL description="Dockerfile used for CI testing of p4lang/p4runtime"
4 |
5 | # No questions asked during package installation.
6 | ARG DEBIAN_FRONTEND=noninteractive
7 |
8 | RUN apt-get update && \
9 | apt-get install -y --no-install-recommends software-properties-common git curl
10 |
11 | ARG GO_VERSION=1.20.5
12 |
13 | RUN set -eux; \
14 | dpkgArch="$(dpkg --print-architecture)"; \
15 | case "${dpkgArch##*-}" in \
16 | amd64) arch='amd64' ;; \
17 | arm64) arch='arm64' ;; \
18 | *) arch=''; echo >&2; echo >&2 "unsupported architecture '$dpkgArch'"; echo >&2 ; exit 1 ;; \
19 | esac; \
20 | curl -L -o go.tar.gz https://dl.google.com/go/go${GO_VERSION}.linux-${arch}.tar.gz; \
21 | tar -C /usr/local -xzf go.tar.gz; \
22 | rm -f go.tar.gz
23 |
24 | ENV PATH="${PATH}:/usr/local/go/bin:/root/go/bin"
25 |
26 | RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31
27 | RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3
28 |
29 | COPY . /p4runtime/
30 | WORKDIR /p4runtime/
31 |
--------------------------------------------------------------------------------
/proto/MODULE.bazel:
--------------------------------------------------------------------------------
1 | module(
2 | name = "p4runtime",
3 | bazel_compatibility = [">=7.4.1"],
4 | repo_name = "com_github_p4lang_p4runtime",
5 | )
6 |
7 | bazel_dep(name = "bazel_skylib", version = "1.7.1")
8 | bazel_dep(
9 | name = "googleapis",
10 | version = "0.0.0-20240819-fe8ba054a",
11 | repo_name = "com_google_googleapis",
12 | )
13 | bazel_dep(
14 | name = "grpc",
15 | version = "1.68.0",
16 | repo_name = "com_github_grpc_grpc",
17 | )
18 | bazel_dep(
19 | name = "protobuf",
20 | version = "29.1",
21 | repo_name = "com_google_protobuf",
22 | )
23 | bazel_dep(name = "rules_license", version = "1.0.0")
24 | bazel_dep(name = "rules_proto", version = "7.0.2")
25 | bazel_dep(
26 | name = "rules_go",
27 | version = "0.59.0",
28 | repo_name = "io_bazel_rules_go",
29 | )
30 | bazel_dep(name = "gazelle", version = "0.45.0")
31 |
32 | switched_rules = use_extension("@com_google_googleapis//:extensions.bzl", "switched_rules")
33 | switched_rules.use_languages(
34 | cc = True,
35 | go = True,
36 | grpc = True,
37 | python = True,
38 | )
39 | use_repo(switched_rules, "com_google_googleapis_imports")
40 |
--------------------------------------------------------------------------------
/docs/tools/Dockerfile.asciidoc:
--------------------------------------------------------------------------------
1 | FROM ruby:3.3.5
2 | LABEL maintainer="P4 API Working Group "
3 | LABEL description="Dockerfile used for building the asciidoc specification"
4 |
5 | RUN apt-get update && \
6 | apt-get install -y cmake flex bison libglib2.0-dev libcairo2-dev libpango1.0-dev libxml2-dev libwebp-dev libzstd-dev libgdk-pixbuf-2.0-dev time
7 |
8 | RUN apt-get install -y libreoffice && \
9 | gem install asciidoctor && \
10 | echo 'gem: --no-document' > /etc/gemrc && \
11 | gem install nokogiri && \
12 | gem install rghost && \
13 | gem install asciidoctor-diagram && \
14 | gem install asciidoctor-plantuml && \
15 | gem install asciidoctor-pdf --version 2.3.19 && \
16 | gem install asciidoctor-pdf-cjk && \
17 | gem install asciidoctor-lists --version 1.1.2 && \
18 | gem install coderay pygments.rb thread_safe && \
19 | gem install slim && \
20 | gem install concurrent-ruby && \
21 | gem install haml tilt && \
22 | gem install asciidoctor-mathematical && \
23 | gem install asciidoctor-bibtex &&\
24 | git clone https://github.com/rouge-ruby/rouge &&\
25 | cd rouge && \
26 | git log -n 1 | cat && \
27 | gem build rouge.gemspec && \
28 | gem install rouge
29 |
30 | VOLUME ["/usr/src/p4-spec"]
31 | WORKDIR /usr/src/p4-spec
--------------------------------------------------------------------------------
/tools/asciidocint.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "keywords": [
3 | {
4 | "category": "P4Runtime message",
5 | "keywords": [
6 | "WriteRequest",
7 | "WriteResponse",
8 | "ReadRequest",
9 | "ReadResponse",
10 | "SetForwardingPipelineConfigRequest",
11 | "SetForwardingPipelineConfigResponse",
12 | "GetForwardingPipelineConfigRequest",
13 | "GetForwardingPipelineConfigResponse",
14 | "StreamMessageRequest",
15 | "StreamMessageResponse"
16 | ]
17 | },
18 | {
19 | "category": "gRPC error code",
20 | "keywords": [
21 | "CANCELLED",
22 | "UNKNOWN",
23 | "INVALID_ARGUMENT",
24 | "DEADLINE_EXCEEDED",
25 | "NOT_FOUND",
26 | "ALREADY_EXISTS",
27 | "PERMISSION_DENIED",
28 | "UNAUTHENTICATED",
29 | "RESOURCE_EXHAUSTED",
30 | "FAILED_PRECONDITION",
31 | "ABORTED",
32 | "OUT_OF_RANGE",
33 | "UNIMPLEMENTED",
34 | "INTERNAL",
35 | "UNAVAILABLE",
36 | "DATA_LOSS"
37 | ]
38 | }
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/rust/p4runtime-tonic/build.rs:
--------------------------------------------------------------------------------
1 | use std::path::PathBuf;
2 |
3 | fn main() -> Result<(), Box> {
4 | // Define constants.
5 | let protoc_version = "33.0"; // Version of the Protobuf compiler to use.
6 | let proto_root = "../../proto";
7 |
8 | // Set `protoc` binary (the Protobuf compiler).
9 | let (protoc_bin, protoc_include) = protoc_prebuilt::init(protoc_version).unwrap();
10 | std::env::set_var("PROTOC", protoc_bin);
11 | std::env::set_var("PROTOC_INCLUDE", protoc_include);
12 |
13 | // Find all .proto files.
14 | let mut proto_files: Vec = Vec::new();
15 | for entry in walkdir::WalkDir::new(proto_root)
16 | .into_iter()
17 | .filter_map(|e| e.ok())
18 | {
19 | let path = entry.path();
20 | if path.is_file() && path.extension().map_or(false, |ext| ext == "proto") {
21 | println!("cargo:rerun-if-changed={}", path.display());
22 | proto_files.push(path.to_path_buf());
23 | }
24 | }
25 | println!("cargo:rerun-if-changed={}", proto_root);
26 |
27 | // Compile the `.proto` files into Rust code.
28 | tonic_prost_build::configure()
29 | // Tell tonic to use the prost-generated types for the Protobuf messages.
30 | .extern_path(".p4", "::p4runtime_prost::p4")
31 | // Build server and client code for the gRPC service.
32 | .build_server(true)
33 | .build_client(true)
34 | .compile_protos(&proto_files, &[PathBuf::from(proto_root)])?;
35 |
36 | Ok(())
37 | }
38 |
--------------------------------------------------------------------------------
/rust/p4runtime-prost/build.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 | use std::path::PathBuf;
3 |
4 | fn main() -> Result<(), Box> {
5 | // Define constants.
6 | let protoc_version = "33.0"; // Version of the Protobuf compiler to use.
7 | let proto_root = "../../proto";
8 | let out_dir = PathBuf::from(env::var("OUT_DIR").expect("environment variable OUT_DIR not set"));
9 | let descriptor_path = PathBuf::from(out_dir).join("file_descriptor_set.bin");
10 |
11 | // Set `protoc` binary (the Protobuf compiler).
12 | let (protoc_bin, protoc_include) = protoc_prebuilt::init(protoc_version).unwrap();
13 | std::env::set_var("PROTOC", protoc_bin);
14 | std::env::set_var("PROTOC_INCLUDE", protoc_include);
15 |
16 | // Find all .proto files.
17 | let mut proto_files: Vec = Vec::new();
18 | for entry in walkdir::WalkDir::new(proto_root)
19 | .into_iter()
20 | .filter_map(|e| e.ok())
21 | {
22 | let path = entry.path();
23 | if path.is_file() && path.extension().map_or(false, |ext| ext == "proto") {
24 | println!("cargo:rerun-if-changed={}", path.display());
25 | proto_files.push(path.to_path_buf());
26 | }
27 | }
28 | println!("cargo:rerun-if-changed={}", proto_root);
29 |
30 | // Compile the `.proto` files into Rust code.
31 | prost_build::Config::new()
32 | // Tell prost to generate a file descriptor set (for gRPC reflection).
33 | .file_descriptor_set_path(&descriptor_path)
34 | .compile_protos(&proto_files, &[proto_root])?;
35 |
36 | Ok(())
37 | }
38 |
--------------------------------------------------------------------------------
/rust/p4runtime-prost/src/lib.rs:
--------------------------------------------------------------------------------
1 | use prost::Message;
2 | use prost_types::FileDescriptorSet;
3 |
4 | /// The official Prost API for all
5 | /// [P4Runtime Protobuf messages](https://github.com/p4lang/p4runtime/blob/main/proto).
6 | pub mod p4 {
7 | pub mod v1 {
8 | include!(concat!(env!("OUT_DIR"), "/p4.v1.rs"));
9 | }
10 | pub mod config {
11 | pub mod v1 {
12 | include!(concat!(env!("OUT_DIR"), "/p4.config.v1.rs"));
13 | }
14 | }
15 | }
16 |
17 | /// Unofficial Prost API for [`google/rpc/status.proto`](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto).
18 | ///
19 | /// Included as a workaround here since there is currently no official crate providing this API.
20 | pub mod google {
21 | pub mod rpc {
22 | include!(concat!(env!("OUT_DIR"), "/google.rpc.rs"));
23 | }
24 | }
25 |
26 | /// Returns a `FileDescriptorSet` defining all Protobuf messages used by P4Runtime.
27 | ///
28 | /// Enables [gRPC reflection](https://grpc.io/docs/guides/reflection/).
29 | pub fn file_descriptor_set() -> FileDescriptorSet {
30 | let raw_proto: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/file_descriptor_set.bin"));
31 | return FileDescriptorSet::decode(raw_proto).unwrap();
32 | }
33 |
34 | #[cfg(test)]
35 | mod tests {
36 | use super::*;
37 |
38 | #[test]
39 | fn file_descriptor_set_is_not_empty() {
40 | let descriptor_set = file_descriptor_set();
41 | assert!(
42 | !descriptor_set.file.is_empty(),
43 | "FileDescriptorSet is empty"
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/.github/workflows/main-branch-uploads.yml:
--------------------------------------------------------------------------------
1 | name: Main branch uploads
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | main-branch-uploads:
10 | if: ${{ github.repository == 'p4lang/p4runtime' }}
11 | runs-on: [ubuntu-latest]
12 | steps:
13 | - uses: actions/checkout@v3
14 | with:
15 | # fetch all history for all branches and tags
16 | fetch-depth: 0
17 | - name: Build spec
18 | run: |
19 | make -C docs/tools/
20 | docker run -v `pwd`/docs/v1:/usr/src/p4-spec p4lang/p4rt-asciidoc make
21 | ls docs/v1/build
22 | - name: Upload spec to S3
23 | uses: jakejarvis/s3-sync-action@v0.5.1
24 | with:
25 | args: --acl public-read --follow-symlinks --delete
26 | env:
27 | AWS_S3_BUCKET: 'p4runtime'
28 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
29 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
30 | AWS_REGION: 'us-west-2'
31 | SOURCE_DIR: 'docs/v1/build'
32 | DEST_DIR: docs/main
33 | - name: Prepare spec for upload to gh-pages
34 | run: |
35 | git checkout gh-pages
36 | mkdir -p spec
37 | rm -rf spec/main
38 | cp -r docs/v1/build spec/main
39 | - name: Upload spec to gh-pages
40 | uses: EndBug/add-and-commit@v9
41 | with:
42 | add: 'spec'
43 | author_name: 'P4Runtime CI'
44 | author_email: 'p4-api@lists.p4.org'
45 | default_author: github_actions
46 | message: 'Publish spec from Github Actions'
47 | commit: '--amend'
48 | push: 'origin gh-pages --force'
49 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
2 | github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
3 | github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
4 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
6 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
7 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
8 | golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
9 | golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
10 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
11 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
12 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
13 | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
14 | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
15 | google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
16 | google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
17 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
18 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
19 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
20 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
21 |
--------------------------------------------------------------------------------
/proto/WORKSPACE.bazel:
--------------------------------------------------------------------------------
1 | workspace(name = "com_github_p4lang_p4runtime")
2 |
3 | load("//:p4runtime_deps.bzl", "p4runtime_deps")
4 |
5 | p4runtime_deps()
6 |
7 | # -- Transitive dependencies. --------------------------------------------------
8 |
9 | load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
10 |
11 | protobuf_deps()
12 |
13 | load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
14 |
15 | rules_proto_dependencies()
16 |
17 | load("@rules_proto//proto:setup.bzl", "rules_proto_setup")
18 |
19 | rules_proto_setup()
20 |
21 | load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
22 |
23 | rules_proto_toolchains()
24 |
25 | load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
26 |
27 | go_rules_dependencies()
28 |
29 | load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
30 |
31 | switched_rules_by_language(
32 | name = "com_google_googleapis_imports",
33 | cc = True,
34 | go = True,
35 | grpc = True,
36 | python = True,
37 | )
38 |
39 | load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
40 |
41 | grpc_deps()
42 |
43 | load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
44 |
45 | grpc_extra_deps()
46 |
47 | load("@com_github_grpc_grpc//bazel:grpc_python_deps.bzl", "grpc_python_deps")
48 |
49 | grpc_python_deps()
50 |
51 | load("@rules_python//python:pip.bzl", "pip_parse")
52 |
53 | pip_parse(
54 | name = "grpc_python_dependencies",
55 | requirements_lock = "@com_github_grpc_grpc//:requirements.bazel.txt",
56 | )
57 |
58 | load("@grpc_python_dependencies//:requirements.bzl", "install_deps")
59 |
60 | install_deps()
61 |
62 | load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
63 |
64 | bazel_skylib_workspace()
65 |
--------------------------------------------------------------------------------
/codegen/compile_protos.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This ensures that the P4Runtime Protobuf files are correct and compile with
4 | # the protoc compiler (CPP, gRPC, Python and Go).
5 |
6 | if [ "$#" -ne 1 ]; then
7 | echo "Usage: compile_protos.sh "
8 | exit 1
9 | fi
10 |
11 | BUILD_DIR="$1"
12 | PROTOC="$(which protoc)"
13 | if [ "$?" -ne 0 ]; then
14 | echo "Could not find protoc"
15 | exit 2
16 | fi
17 |
18 | echo "Using $PROTOC"
19 |
20 | GRPC_CPP_PLUGIN="$(which grpc_cpp_plugin)"
21 | if [ "$?" -ne 0 ]; then
22 | echo "Could not find CPP protoc plugin"
23 | exit 2
24 | fi
25 | GRPC_PY_PLUGIN="$(which grpc_python_plugin)"
26 | if [ "$?" -ne 0 ]; then
27 | echo "Could not find Python protoc plugin"
28 | exit 2
29 | fi
30 |
31 | set -e
32 |
33 | THIS_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)"
34 | PROTO_DIR="$THIS_DIR/../proto"
35 |
36 | PROTOS="\
37 | $PROTO_DIR/p4/v1/p4data.proto \
38 | $PROTO_DIR/p4/v1/p4runtime.proto \
39 | $PROTO_DIR/p4/config/v1/p4info.proto \
40 | $PROTO_DIR/p4/config/v1/p4types.proto"
41 |
42 | PROTOFLAGS="-I$PROTO_DIR"
43 |
44 | mkdir -p "$BUILD_DIR/cpp_out"
45 | mkdir -p "$BUILD_DIR/grpc_out"
46 | mkdir -p "$BUILD_DIR/py_out"
47 | mkdir -p "$BUILD_DIR/go_out"
48 |
49 | set -o xtrace
50 | $PROTOC $PROTOS --cpp_out "$BUILD_DIR/cpp_out" $PROTOFLAGS
51 | $PROTOC $PROTOS --grpc_out "$BUILD_DIR/grpc_out" --plugin=protoc-gen-grpc="$GRPC_CPP_PLUGIN" $PROTOFLAGS
52 | # With the Python plugin, it seems that I need to use a single command for proto
53 | # + grpc and that the output directory needs to be the same (because the grpc
54 | # plugin inserts code into the proto-generated files). But maybe I am just using
55 | # an old version of the Python plugin.
56 | $PROTOC $PROTOS --python_out "$BUILD_DIR/py_out" $PROTOFLAGS --grpc_out "$BUILD_DIR/py_out" --plugin=protoc-gen-grpc="$GRPC_PY_PLUGIN"
57 |
58 | $PROTOC $PROTOS --go_out="$BUILD_DIR/go_out" --go-grpc_out="$BUILD_DIR/go_out" $PROTOFLAGS
59 |
60 | echo "SUCCESS"
61 |
--------------------------------------------------------------------------------
/proto/google/rpc/status.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2025 Google LLC
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | package google.rpc;
18 |
19 | import "google/protobuf/any.proto";
20 |
21 | option cc_enable_arenas = true;
22 | option go_package = "google.golang.org/genproto/googleapis/rpc/status;status";
23 | option java_multiple_files = true;
24 | option java_outer_classname = "StatusProto";
25 | option java_package = "com.google.rpc";
26 | option objc_class_prefix = "RPC";
27 |
28 | // The `Status` type defines a logical error model that is suitable for
29 | // different programming environments, including REST APIs and RPC APIs. It is
30 | // used by [gRPC](https://github.com/grpc). Each `Status` message contains
31 | // three pieces of data: error code, error message, and error details.
32 | //
33 | // You can find out more about this error model and how to work with it in the
34 | // [API Design Guide](https://cloud.google.com/apis/design/errors).
35 | message Status {
36 | // The status code, which should be an enum value of
37 | // [google.rpc.Code][google.rpc.Code].
38 | int32 code = 1;
39 |
40 | // A developer-facing error message, which should be in English. Any
41 | // user-facing error message should be localized and sent in the
42 | // [google.rpc.Status.details][google.rpc.Status.details] field, or localized
43 | // by the client.
44 | string message = 2;
45 |
46 | // A list of messages that carry the error details. There is a common set of
47 | // message types for APIs to use.
48 | repeated google.protobuf.Any details = 3;
49 | }
50 |
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/LuxiMono/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Bigelow & Holmes Inc and URW++ GmbH Luxi font license
2 |
3 | Luxi fonts copyright (c) 2001 by Bigelow & Holmes Inc. Luxi font instruction
4 | code copyright (c) 2001 by URW++ GmbH. All Rights Reserved. Luxi is a regis-
5 | tered trademark of Bigelow & Holmes Inc.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of these Fonts and associated documentation files (the "Font Software"), to
9 | deal in the Font Software, including without limitation the rights to use,
10 | copy, merge, publish, distribute, sublicense, and/or sell copies of the Font
11 | Software, and to permit persons to whom the Font Software is furnished to do
12 | so, subject to the following conditions:
13 |
14 | The above copyright and trademark notices and this permission notice shall be
15 | included in all copies of one or more of the Font Software.
16 |
17 | The Font Software may not be modified, altered, or added to, and in particu-
18 | lar the designs of glyphs or characters in the Fonts may not be modified nor
19 | may additional glyphs or characters be added to the Fonts. This License
20 | becomes null and void when the Fonts or Font Software have been modified.
21 |
22 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
25 | TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BIGELOW & HOLMES INC. OR URW++
26 | GMBH. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GEN-
27 | ERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN
28 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
29 | INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFT-
30 | WARE.
31 |
32 | Except as contained in this notice, the names of Bigelow & Holmes Inc. and
33 | URW++ GmbH. shall not be used in advertising or otherwise to promote the
34 | sale, use or other dealings in this Font Software without prior written
35 | authorization from Bigelow & Holmes Inc. and URW++ GmbH.
36 |
37 | For further information, contact:
38 |
39 | info@urwpp.de or design@bigelowandholmes.com
40 |
41 |
42 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # P4Runtime specification documents
2 |
3 | ## Inline code with backticks
4 |
5 | Use backticks for:
6 |
7 | * names of Protobuf messages / fields / RPCs / enum symbols
8 | * P4 code
9 | * name of variables when describing examples (pseudo-code or P4)
10 |
11 | Do not use backticks for:
12 |
13 | * PSA extern names
14 | * "P4Runtime" & "P4Info"
15 |
16 | ## What to capitalize?
17 |
18 | * "Protobuf"
19 | * Each significant word in a heading / section name
20 | * PSA extern names
21 |
22 | ## Hexadecimal numbers
23 |
24 | We use lowercase for the letter digits when writing hexadecimal numbers. This is
25 | a very arbitrary decision, purely for the sake of uniformity. Maybe lowercase
26 | letters are easier to type for most people?
27 |
28 | ## Hyphen, en dash and em dash
29 |
30 | Use `-` for the hyphen, `--` for en dash and `—` for em dash.
31 |
32 | ## Document Figures
33 |
34 | Each image in the specification has a corresponding `.odg` file in
35 | `resources/figs/`. These are LibreOffice drawing files. The files are rendered into
36 | `.svg` and `.png` images (for HTML and PDF output, resepectively) at build time,
37 | using the `soffice` command-line tool. The page size for each image should be
38 | adjusted manually by the author ("artist") to just fit the image on the
39 | apparent "page," to minimize padding around the image in the rendered
40 | document. Use the menu item `Format | Page/Size Properties.` See the example
41 | screen shot below. (Do not check the "Fit object to paper format" box - it will
42 | change the object's aspect ratio.)
43 | 
44 |
45 | ## CI upload of built documents
46 |
47 | Github Actions take care of uploading the built HTML version of the spec to
48 | Github. The latest working draft (main branch) can be found
49 | [here](https://p4.org/p4runtime/spec/main/P4Runtime-Spec.html).
50 |
51 | Additionally, you can access the HTML & PDF versions of the spec for any given
52 | branch of this repository by using the following URLs:
53 | * `https://s3-us-west-2.amazonaws.com/p4runtime/ci//P4Runtime-Spec.html`
54 | for the **HTML** version
55 | * `https://s3-us-west-2.amazonaws.com/p4runtime/ci//P4Runtime-Spec.pdf`
56 | for the **PDF** version
57 |
58 | Unfortunately, for security reasons, this does not work for branches in forked
59 | repositories, even for opened pull requests.
60 |
--------------------------------------------------------------------------------
/bazel/example/using-workspace/WORKSPACE.bazel:
--------------------------------------------------------------------------------
1 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
2 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
3 |
4 | # In your own project, you will likely want to use `http_archive` instead
5 | # of `local_repository` to load p4runtime.
6 | local_repository(
7 | name = "com_github_p4lang_p4runtime",
8 | path = "../../../proto",
9 | )
10 | # http_archive(
11 | # name = "com_github_p4lang_p4runtime",
12 | # urls = ["https://github.com/p4lang/p4runtime/archive/v1.4.1.tar.gz"],
13 | # strip_prefix = "p4runtime-1.4.1/proto",
14 | # # sha256 = "",
15 | # )
16 |
17 | load("@com_github_p4lang_p4runtime//:p4runtime_deps.bzl", "p4runtime_deps")
18 |
19 | p4runtime_deps()
20 |
21 | # -- Transitive dependencies of P4Runtime dependencies -------------------------
22 |
23 | load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
24 |
25 | protobuf_deps()
26 |
27 | load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
28 |
29 | rules_proto_dependencies()
30 |
31 | load("@rules_proto//proto:setup.bzl", "rules_proto_setup")
32 |
33 | rules_proto_setup()
34 |
35 | load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
36 |
37 | rules_proto_toolchains()
38 |
39 | load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
40 |
41 | go_rules_dependencies()
42 |
43 | load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
44 |
45 | switched_rules_by_language(
46 | name = "com_google_googleapis_imports",
47 | cc = True,
48 | go = True,
49 | grpc = True,
50 | python = True,
51 | )
52 |
53 | load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
54 |
55 | grpc_deps()
56 |
57 | load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
58 |
59 | grpc_extra_deps()
60 |
61 | load("@com_github_grpc_grpc//bazel:grpc_python_deps.bzl", "grpc_python_deps")
62 |
63 | grpc_python_deps()
64 |
65 | load("@rules_python//python:pip.bzl", "pip_parse")
66 |
67 | pip_parse(
68 | name = "grpc_python_dependencies",
69 | requirements_lock = "@com_github_grpc_grpc//:requirements.bazel.txt",
70 | )
71 |
72 | load("@grpc_python_dependencies//:requirements.bzl", "install_deps")
73 |
74 | install_deps()
75 |
76 | load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
77 |
78 | bazel_skylib_workspace()
79 |
--------------------------------------------------------------------------------
/proto/p4/v1/p4data.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2013-present Barefoot Networks, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | package p4.v1;
18 |
19 | option go_package = "github.com/p4lang/p4runtime/go/p4/v1";
20 |
21 | message P4Data {
22 | oneof data {
23 | bytes bitstring = 1; // for bit, int
24 | P4Varbit varbit = 2; // for varbit
25 | bool bool = 3;
26 | P4StructLike tuple = 4;
27 | P4StructLike struct = 5;
28 | P4Header header = 6;
29 | P4HeaderUnion header_union = 7;
30 | P4HeaderStack header_stack = 8;
31 | P4HeaderUnionStack header_union_stack = 9;
32 | string enum = 10; // safe (non-serializable) enums only
33 | string error = 11;
34 | bytes enum_value = 12; // serializable enums only
35 | }
36 | }
37 |
38 | message P4Varbit {
39 | bytes bitstring = 1;
40 | int32 bitwidth = 2; // dynamic bitwidth of the field
41 | }
42 |
43 | message P4StructLike {
44 | repeated P4Data members = 1;
45 | }
46 |
47 | message P4Header {
48 | // If the header is invalid (is_valid is "false"), then the bitstrings
49 | // repeated field must be empty.
50 | bool is_valid = 1;
51 | repeated bytes bitstrings = 2;
52 | }
53 |
54 | message P4HeaderUnion {
55 | // An empty string indicates that none of the union members are valid and
56 | // valid_header must therefore be unset.
57 | string valid_header_name = 1;
58 | P4Header valid_header = 2;
59 | }
60 |
61 | message P4HeaderStack {
62 | // The length of this repeated field must always be equal to the compile-time
63 | // size of the header stack, which is specified in P4Info.
64 | repeated P4Header entries = 1;
65 | }
66 |
67 | message P4HeaderUnionStack {
68 | // The length of this repeated field must always be equal to the compile-time
69 | // size of the header union stack, which is specified in P4Info.
70 | repeated P4HeaderUnion entries = 1;
71 | }
72 |
--------------------------------------------------------------------------------
/.github/workflows/tag-uploads.yml:
--------------------------------------------------------------------------------
1 | name: Tag uploads
2 |
3 | on:
4 | push:
5 | tags:
6 | - v*
7 |
8 | jobs:
9 | tag-uploads:
10 | if: ${{ github.repository == 'p4lang/p4runtime' }}
11 | runs-on: [ubuntu-latest]
12 | env:
13 | TAG: ${{ github.ref_name }}
14 | steps:
15 | - uses: actions/checkout@v3
16 | with:
17 | # fetch all history for all branches and tags
18 | fetch-depth: 0
19 | - name: Build spec
20 | run: |
21 | make -C docs/tools/
22 | docker run -v `pwd`/docs/v1:/usr/src/p4-spec p4lang/p4rt-asciidoc make
23 | ls docs/v1/build
24 | - name: Upload spec to S3
25 | uses: jakejarvis/s3-sync-action@v0.5.1
26 | with:
27 | args: --acl public-read --follow-symlinks --delete
28 | env:
29 | AWS_S3_BUCKET: 'p4runtime'
30 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
31 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
32 | AWS_REGION: 'us-west-2'
33 | SOURCE_DIR: 'docs/v1/'
34 | DEST_DIR: docs/${{ github.ref_name }}
35 | - name: Prepare spec for upload to gh-pages
36 | run: |
37 | git checkout gh-pages
38 | mkdir -p spec
39 | rm -rf spec/$TAG
40 | cp -r docs/v1/build spec/$TAG
41 | - name: Upload spec to gh-pages
42 | uses: EndBug/add-and-commit@v9
43 | with:
44 | add: 'spec'
45 | author_name: 'P4Runtime CI'
46 | author_email: 'p4-api@lists.p4.org'
47 | default_author: github_actions
48 | message: 'Publish spec from Github Actions'
49 | commit: '--amend'
50 | push: 'origin gh-pages --force'
51 |
52 | publish-to-pypi:
53 | name: Publish a Python distribution to PyPI
54 | if: ${{ github.repository == 'p4lang/p4runtime' }}
55 | runs-on: [ubuntu-latest]
56 | steps:
57 | - uses: actions/checkout@v3
58 | - name: Set up Python
59 | uses: actions/setup-python@v3
60 | with:
61 | python-version: '3.x'
62 | - name: Install pypa/build
63 | run: >-
64 | python -m
65 | pip install
66 | build
67 | --user
68 | - name: Build a binary wheel and a source tarball
69 | working-directory: py
70 | run: >-
71 | python -m
72 | build
73 | --sdist
74 | --wheel
75 | --outdir dist/
76 | .
77 | - name: Publish distribution to PyPI
78 | uses: pypa/gh-action-pypi-publish@release/v1
79 | with:
80 | user: __token__
81 | password: ${{ secrets.PYPI_API_TOKEN }}
82 | packages_dir: py/dist/
83 | skip_existing: true
84 |
--------------------------------------------------------------------------------
/rust/README.md:
--------------------------------------------------------------------------------
1 | # P4Runtime Rust Crates
2 |
3 | This directory contains Rust crates for the P4Runtime API specification.
4 |
5 | ## Usage in Your Project
6 |
7 | Add the following to your `Cargo.toml`:
8 |
9 | **For message types only:**
10 | ```toml
11 | [dependencies]
12 | p4runtime-prost = { git = "https://github.com/p4lang/p4runtime.git" }
13 | ```
14 |
15 | **For gRPC services:**
16 | ```toml
17 | [dependencies]
18 | p4runtime-prost = { git = "https://github.com/p4lang/p4runtime.git" }
19 | p4runtime-tonic = { git = "https://github.com/p4lang/p4runtime.git" }
20 | ```
21 |
22 | ## Crates
23 |
24 | ### `p4runtime-prost`
25 |
26 | Provides Protocol Buffer message types using [prost](https://docs.rs/prost/).
27 | This crate contains only the message definitions and no gRPC service
28 | implementations.
29 |
30 | **Use this crate when:**
31 | - You need to construct/serialize/deserialize P4Runtime messages
32 | - You don't need gRPC client/server functionality
33 | - You want to minimize dependencies (only depends on `prost`)
34 |
35 | **Example:**
36 | ```rust
37 | use p4runtime_prost::p4::v1::WriteRequest;
38 |
39 | let request = WriteRequest {
40 | device_id: 1,
41 | // ... other fields
42 | };
43 | ```
44 |
45 | ### `p4runtime-tonic`
46 |
47 | Provides gRPC service definitions using [tonic](https://docs.rs/tonic/).
48 | This crate depends on `p4runtime-prost` for message types and adds gRPC client
49 | and server implementations.
50 |
51 | **Use this crate when:**
52 | - You need to implement a P4Runtime server
53 | - You need to create a P4Runtime client
54 |
55 | **Example:**
56 | ```rust
57 | use p4runtime_tonic::p4::v1::p4_runtime_client::P4RuntimeClient;
58 |
59 | let mut client = P4RuntimeClient::connect("http://[::1]:50051").await?;
60 | ```
61 |
62 | ## Design
63 |
64 | 1. **Automatic Code Generation**: Code is generated during `cargo build` via
65 | `build.rs` scripts, eliminating the need to run `codegen/` scripts manually.
66 |
67 | 2. **Separate Crates**: Message types and gRPC services are in separate crates,
68 | so users who only need the proto messages don't need to depend on `tonic`.
69 |
70 | 3. **gRPC Reflection**: File descriptors are exported as part of
71 | `p4runtime-prost`, enabling gRPC reflection support.
72 |
73 | ## How can I see the generated code?
74 |
75 | ### Via the documentation
76 |
77 | Simply run
78 | ```
79 | cargo doc --open
80 | ```
81 | to build documentation for the crates and bring it up in your default web
82 | browser. Then, navgiate to the desired object and click "Source".
83 |
84 | ### Using cargo outdir
85 |
86 | First install `cargo-outdir`:
87 | ```
88 | cargo install cargo-outdir
89 | ```
90 | Then navigate to the crate you're interested in, e.g. `cd p4runtime-prost`,
91 | and run
92 | ```
93 | cd $(cargo outdir --no-names)
94 | ```
95 | to navigate to the build directory containing all generated files.
96 |
--------------------------------------------------------------------------------
/proto/p4runtime_deps.bzl:
--------------------------------------------------------------------------------
1 | """Load dependencies needed to compile p4runtime as a 3rd-party consumer."""
2 |
3 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
4 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
5 |
6 | def p4runtime_deps():
7 | """Loads dependencies needed to compile p4runtime."""
8 | if not native.existing_rule("com_google_protobuf"):
9 | http_archive(
10 | name = "com_google_protobuf",
11 | url = "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v28.2.tar.gz",
12 | strip_prefix = "protobuf-28.2",
13 | sha256 = "b2340aa47faf7ef10a0328190319d3f3bee1b24f426d4ce8f4253b6f27ce16db",
14 | )
15 | if not native.existing_rule("rules_proto"):
16 | http_archive(
17 | name = "rules_proto",
18 | sha256 = "6fb6767d1bef535310547e03247f7518b03487740c11b6c6adb7952033fe1295",
19 | strip_prefix = "rules_proto-6.0.2",
20 | url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.2/rules_proto-6.0.2.tar.gz",
21 | )
22 | if not native.existing_rule("io_bazel_rules_go"):
23 | http_archive(
24 | name = "io_bazel_rules_go",
25 | sha256 = "f4a9314518ca6acfa16cc4ab43b0b8ce1e4ea64b81c38d8a3772883f153346b8",
26 | urls = [
27 | "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip",
28 | "https://github.com/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip",
29 | ],
30 | )
31 | if not native.existing_rule("com_google_googleapis"):
32 | git_repository(
33 | name = "com_google_googleapis",
34 | remote = "https://github.com/googleapis/googleapis",
35 | commit = "de509e38d37a2a9d8b95e1ce78831189f4f3c0f4",
36 | )
37 | if not native.existing_rule("com_github_grpc_grpc"):
38 | http_archive(
39 | name = "com_github_grpc_grpc",
40 | url = "https://github.com/grpc/grpc/archive/refs/tags/v1.67.0.tar.gz",
41 | strip_prefix = "grpc-1.67.0",
42 | sha256 = "af0638f73e4452e22e295f8b3f452518234254104713a08497f3d3aaa76733ad",
43 | )
44 | if not native.existing_rule("bazel_skylib"):
45 | http_archive(
46 | name = "bazel_skylib",
47 | sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
48 | urls = [
49 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
50 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
51 | ],
52 | )
53 | if not native.existing_rule("rules_license"):
54 | http_archive(
55 | name = "rules_license",
56 | urls = [
57 | "https://mirror.bazel.build/github.com/bazelbuild/rules_license/releases/download/1.0.0/rules_license-1.0.0.tar.gz",
58 | "https://github.com/bazelbuild/rules_license/releases/download/1.0.0/rules_license-1.0.0.tar.gz",
59 | ],
60 | sha256 = "26d4021f6898e23b82ef953078389dd49ac2b5618ac564ade4ef87cced147b38",
61 | )
62 |
--------------------------------------------------------------------------------
/docs/v1/README.md:
--------------------------------------------------------------------------------
1 | # P4Runtime Specification Version 1
2 |
3 | This directory contains the sources for generating the official P4Runtime
4 | specification document.
5 |
6 | # Markup version
7 |
8 | The markup version uses [AsciiDoc](https://docs.asciidoctor.org/) to produce
9 | HTML and PDF versions of the documentation. Pre-built versions of the
10 | documentation are available on the [P4.org specifications
11 | page](https://p4.org/specs).
12 |
13 |
14 | Files:
15 | - `P4Runtime-Spec.adoc` is the main file.
16 | - resources:
17 | - figs
18 | - `*.odg` - OfficeLibre source drawing file used to export images. These are
19 | bulk-rendered at build time into .svg and .png images via `soffice`
20 | command-line (required in build environment)
21 | - fonts
22 | - `*.ttf` - Type font source file used to export fonts.
23 | - theme:
24 | - `*.yaml` - Describes how PDF P4Runtime specification will be displayed.
25 | - `*.css` - Describes how HTML P4Runtime specification will displayed.
26 | - `*.bib` - Bibliography file that contains a list of bibliographical item, such as articles, books, and theses.
27 | - `Makefile` builds documentation in the build subdirectory
28 |
29 | ## Document Figures
30 |
31 | The P4Runtime specification can be generated on your local machine or via the Docker container. Due to this, the document figure can be rendered using two different approaches
32 |
33 | ### Local machine
34 |
35 | You need to install [LibreOffice](https://nl.libreoffice.org/) on your local machine.
36 |
37 | Each image in the specification has a corresponding `.odg` file under
38 | `resources/figs/`. These are LibreOffice drawing files. The files are rendered into
39 | `.svg` and `.png` images (for HTML and PDF output, resepectively) at build time,
40 | using the `soffice` command-line tool. The page size for each image should be
41 | adjusted manually by the author ("artist") to just fit the image on the
42 | apparrent "page," to minimize padding around the image in the rendered
43 | document. Use the menu item `Format | Page/Size Properties.` See the example
44 | screen shot below. (Do not check the "Fit object to paper format" box - it will
45 | change the object's aspect ratio.)
46 | 
47 |
48 | Commands to convert a image from `.odg` to `.svg` and/or `.png`:
49 | ```
50 | soffice --convert-to svg figure_name.odg
51 | soffice --convert-to png figure_name.odg
52 | ```
53 |
54 | Commands to convert a image `.odg` to `.svg` and/or `.png` and move to `resources/figs/`:
55 |
56 | ```
57 | soffice --convert-to svg --outdir resources/figs/ figure_name.odg
58 | soffice --convert-to png --outdir resources/figs/ figure_name.odg
59 | ```
60 | ### Docker container
61 |
62 | The Docker container, generated from the `p4lang/p4rt-asciidoc:latest` image, does not require
63 | LibreOffice to be installed.
64 |
65 |
66 | ## Building
67 |
68 | The easiest way to render the AsciiDoc specification documentation is to use the
69 | `p4lang/p4rt-asciidoc:latest` Docker` image:
70 |
71 | docker run -v `pwd`/docs/v1:/usr/src/p4-spec p4lang/p4rt-asciidoc:latest make build_spec_with_images
72 |
73 | ### Linux
74 |
75 | You can use the [local installation](https://github.com/p4lang/p4-spec/blob/main/p4-16/spec/install-asciidoctor-linux.sh) method, and you also need to install LibreOffice to render the
76 | images into .svg and .png formats.
77 |
78 | ### MacOS
79 |
80 | We do not yet have instructions for generating PDF and HTML from AsciiDoc source on macOS. You are welcome to contribute documentation for how to do so if you find instructions that work.
81 |
82 | ### Windows
83 |
84 | We do not yet have instructions for generating PDF and HTML from AsciiDoc source on Windows. You are welcome to contribute documentation for how to do so if you find instructions that work.
85 |
--------------------------------------------------------------------------------
/.github/workflows/bazel-build.yml:
--------------------------------------------------------------------------------
1 | name: "Bazel build of protobufs"
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - '*-dev'
8 | pull_request:
9 | branches:
10 | - main
11 | - '*-dev'
12 | schedule:
13 | - cron: "0 0 * * *"
14 |
15 | jobs:
16 | build:
17 |
18 | strategy:
19 | matrix:
20 | # We only test on the oldest version we want to support and latest.
21 | # We trust that things also work for versions in the middle.
22 | os: [ubuntu-22.04, ubuntu-latest]
23 | # See Bazelisk README for legal values.
24 | bazel_version: [7.x, latest]
25 | # Don't abort other runs when one of them fails, to ease debugging.
26 | fail-fast: false
27 |
28 | # The default name would be "build (ubuntu-, )".
29 | # We use a custom name to make it clearer that the second version refers to Bazel.
30 | name: ${{ matrix.os }}, bazel-${{ matrix.bazel_version }}
31 |
32 | runs-on: ${{ matrix.os }}
33 |
34 | env:
35 | # This tells Bazelisk (installed as `bazel`) to use specified version.
36 | # https://github.com/bazelbuild/bazelisk?tab=readme-ov-file#how-does-bazelisk-know-which-bazel-version-to-run
37 | USE_BAZEL_VERSION: ${{ matrix.bazel_version }}
38 | CACHE_KEY: ${{ matrix.os }}_bazel-${{ matrix.bazel_version }}
39 |
40 | steps:
41 | - uses: actions/checkout@v4
42 | with:
43 | submodules: recursive
44 |
45 | - name: Mount bazel cache
46 | uses: actions/cache/restore@v4
47 | with:
48 | # See https://docs.bazel.build/versions/master/output_directories.html
49 | path: "~/.cache/bazel"
50 | # Create a new cache entry whenever Bazel files change.
51 | # See https://docs.github.com/en/actions/guides/caching-dependencies-to-speed-up-workflows
52 | key: ${{ env.CACHE_KEY }}-${{ hashFiles('**/*.bazel*', '**/*.bzl') }}
53 | restore-keys: |
54 | ${{ env.CACHE_KEY }}
55 |
56 | - name: Save start time
57 | uses: josStorer/get-current-time@v2
58 | id: start-time
59 | with:
60 | # Unix timestamp -- seconds since 1970.
61 | format: X
62 |
63 | - name: Build proto/
64 | run: cd proto && bazel build //... && bazel test //...
65 |
66 | - name: Build bazel/example/using-bzlmod/
67 | run: cd bazel/example/using-bzlmod && bazel build //...
68 |
69 | - name: Build bazel/example/using-workspace/
70 | run: cd bazel/example/using-workspace && bazel build //...
71 | # This is a legacy example that doesn't work beyond Bazel 7.x.
72 | if: ${{ env.USE_BAZEL_VERSION == '7.x' }}
73 |
74 | - name: Save end time
75 | # Always save the end time so we can calculate the build duration.
76 | if: always()
77 | uses: josStorer/get-current-time@v2
78 | id: end-time
79 | with:
80 | # Unix timestamp -- seconds since 1970.
81 | format: X
82 |
83 | - name: Calculate build duration
84 | # Always calculate the build duration so we can update the cache if needed.
85 | if: always()
86 | run: |
87 | START=${{ steps.start-time.outputs.formattedTime }}
88 | END=${{ steps.end-time.outputs.formattedTime }}
89 | DURATION=$(( $END - $START ))
90 | echo "duration=$DURATION" | tee "$GITHUB_ENV"
91 |
92 | - name: Compress cache
93 | # Always compress the cache so we can update the cache if needed.
94 | if: always()
95 | run: rm -rf $(bazel info repository_cache)
96 |
97 | - name: Save bazel cache
98 | uses: actions/cache/save@v4
99 | # Only create a new cache entry if we're on the main branch or the build takes >3mins.
100 | #
101 | # NOTE: Even though `always()` evaluates to true, and `true && x == x`,
102 | # the `always() &&` prefix is not redundant! The call to `always()` has a
103 | # side effect, which is to override the default behavior of automagically
104 | # canceling this step if a previous step failed.
105 | # (Don't blame me, blame GitHub Actions!)
106 | if: always() && (github.ref_name == 'main' || env.duration > 180)
107 | with:
108 | path: "~/.cache/bazel"
109 | key: ${{ env.CACHE_KEY }}-${{ hashFiles('**/*.bazel*', '**/*.bzl') }}-${{ github.run_id }}
110 |
--------------------------------------------------------------------------------
/proto/BUILD.bazel:
--------------------------------------------------------------------------------
1 |
2 | load("@bazel_skylib//rules:build_test.bzl", "build_test")
3 | load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
4 | load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
5 | load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
6 | load("@rules_license//rules:license.bzl", "license")
7 | load("@rules_proto//proto:defs.bzl", "proto_library")
8 |
9 | package(
10 | default_visibility = ["//visibility:public"],
11 | default_applicable_licenses = [":license"],
12 | )
13 |
14 | license(
15 | name = "license",
16 | license_kinds = ["@rules_license//licenses/spdx:Apache-2.0"],
17 | license_text = "LICENSE",
18 | )
19 |
20 | exports_files(["LICENSE"])
21 |
22 | proto_library(
23 | name = "p4types_proto",
24 | srcs = ["p4/config/v1/p4types.proto"],
25 | # TODO(github.com/grpc/grpc/issues/20675): strip_import_prefix breaks
26 | # cc_grpc_library. Make proto folder the Bazel root folder as a workaround.
27 | # strip_import_prefix = "proto",
28 | )
29 |
30 | proto_library(
31 | name = "p4data_proto",
32 | srcs = ["p4/v1/p4data.proto"],
33 | # TODO(github.com/grpc/grpc/issues/20675): strip_import_prefix breaks
34 | # cc_grpc_library. Make proto folder the Bazel root folder as a workaround.
35 | # strip_import_prefix = "proto",
36 | )
37 |
38 | proto_library(
39 | name = "p4info_proto",
40 | srcs = ["p4/config/v1/p4info.proto"],
41 | deps = [
42 | ":p4types_proto",
43 | "@com_google_protobuf//:any_proto",
44 | "@com_google_protobuf//:descriptor_proto",
45 | ],
46 | # TODO(github.com/grpc/grpc/issues/20675): strip_import_prefix breaks
47 | # cc_grpc_library. Make proto folder the Bazel root folder as a workaround.
48 | # strip_import_prefix = "proto",
49 | )
50 |
51 | proto_library(
52 | name = "p4runtime_proto",
53 | srcs = ["p4/v1/p4runtime.proto"],
54 | deps = [
55 | ":p4data_proto",
56 | ":p4info_proto",
57 | "@com_google_googleapis//google/rpc:status_proto",
58 | "@com_google_protobuf//:any_proto",
59 | ],
60 | # TODO(github.com/grpc/grpc/issues/20675): strip_import_prefix brakes
61 | # cc_grpc_library. Make proto folder the Bazel root folder as a workaround.
62 | # strip_import_prefix = "proto",
63 | )
64 |
65 | cc_proto_library(
66 | name = "p4types_cc_proto",
67 | deps = [":p4types_proto"],
68 | )
69 |
70 | cc_proto_library(
71 | name = "p4info_cc_proto",
72 | deps = [":p4info_proto"],
73 | )
74 |
75 | cc_proto_library(
76 | name = "p4data_cc_proto",
77 | deps = [":p4data_proto"],
78 | )
79 |
80 | cc_proto_library(
81 | name = "p4runtime_cc_proto",
82 | deps = [":p4runtime_proto"],
83 | )
84 |
85 | py_proto_library(
86 | name = "p4types_py_proto",
87 | deps = [":p4types_proto"],
88 | )
89 |
90 | py_proto_library(
91 | name = "p4info_py_proto",
92 | deps = [":p4info_proto"],
93 | )
94 |
95 | py_proto_library(
96 | name = "p4data_py_proto",
97 | deps = [":p4data_proto"],
98 | )
99 |
100 | py_proto_library(
101 | name = "p4runtime_py_proto",
102 | deps = [":p4runtime_proto"],
103 | )
104 |
105 | go_proto_library(
106 | name = "p4info_go_proto",
107 | importpath = "github.com/p4lang/p4runtime/go/p4/config/v1",
108 | protos = [
109 | ":p4info_proto",
110 | ":p4types_proto",
111 | ],
112 | )
113 |
114 | go_proto_library(
115 | name = "p4runtime_go_proto",
116 | importpath = "github.com/p4lang/p4runtime/go/p4/v1",
117 | protos = [
118 | ":p4data_proto",
119 | ":p4runtime_proto",
120 | ],
121 | deps = [
122 | ":p4info_go_proto",
123 | "@com_google_googleapis//google/rpc:status_go_proto",
124 | ],
125 | )
126 |
127 | cc_grpc_library(
128 | name = "p4runtime_cc_grpc",
129 | srcs = [":p4runtime_proto"],
130 | generate_mocks = True,
131 | grpc_only = True,
132 | deps = [":p4runtime_cc_proto"],
133 | )
134 |
135 | py_grpc_library(
136 | name = "p4runtime_py_grpc",
137 | srcs = [":p4runtime_proto"],
138 | deps = [":p4runtime_py_proto"],
139 | )
140 |
141 | build_test(
142 | name = "proto_build_test",
143 | targets = [
144 | ":p4data_proto",
145 | ":p4info_proto",
146 | ":p4runtime_cc_grpc",
147 | ":p4runtime_proto",
148 | ":p4runtime_py_grpc",
149 | ":p4types_proto",
150 | ],
151 | )
152 |
--------------------------------------------------------------------------------
/docs/v1/resources/fonts/Utopia/LICENSE-utopia.txt:
--------------------------------------------------------------------------------
1 | The agreement below gives the TeX Users Group (TUG) the right to
2 | sublicense, and grant such sublicensees the right to further sublicense,
3 | any or all of the rights enumerated below. TUG hereby does so
4 | sublicense all such rights, irrevocably and in perpetuity, to any and
5 | all interested parties.
6 |
7 | --Karl Berry, TUG President,
8 | on behalf of the TeX Users Group board and members
9 | 17 November 2006
10 | http://tug.org/fonts/utopia
11 |
12 | ------------------------------------------------------------
13 | October 11, 2006
14 |
15 | RE: License to TeX Users Group for the Utopia Typeface
16 |
17 | Adobe Systems Incorporated ("Adobe") hereby grants to the TeX Users
18 | Group and its members a nonexclusive, royalty-free, perpetual license to
19 | the typeface software for the Utopia Regular, Utopia Italic, Utopia Bold
20 | and Utopia bold Italic typefaces, including Adobe Type 1 font programs
21 | for each style (collectively, the "Software") as set forth below.
22 |
23 | Adobe grants the TeX Users Group a license under its copyrights, to use,
24 | reproduce, display and distribute the Software for any purpose and
25 | without fee provided that the following copyright notice appears in all
26 | whole and partial copies of the Software and provided that the following
27 | trademark symbol and attribution appear in all unmodified copies of the
28 | Software:
29 |
30 | Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
31 | (alternatively, @1989, 1991 Adobe Systems Incorporated. All rights reserved.)
32 | Utopia(R)
33 | Utopia is either a registered trademark or trademark of Adobe Systems
34 | Incorporated in the United States and/or other countries. Used under
35 | license.
36 |
37 | Adobe also grants to the TeX Users Group a license to modify the
38 | Software for any purpose and redistribute such modifications, for any
39 | purpose and royalty-free, provided that the modified Software shall not
40 | use the font name(s) or trademark(s), in whole or in part, unless
41 | explicit written permission is granted by Adobe. This restriction
42 | applies to all references stored in the Software for identification
43 | purposes, such as the font menu name and other font description
44 | fields. The TeX Users Group is also permitted to sublicense, and grant
45 | such sublicensees the right to further sublicense, any or all the
46 | foregoing rights through multiple tiers of distribution. The licenses
47 | granted herein are granted in perpetuity and may not be terminated by
48 | either party unless such termination is based on a breach of the terms
49 | and conditions herein stated.
50 |
51 | Adobe retains ownership of the copyright in the Software. The TeX Users
52 | Group agrees that Adobe and its suppliers are the sole and exclusive
53 | owners of all rights, title and interest, including all copyrights,
54 | patents, trademarks, trade names, trade secrets and other intellectual
55 | property rights in the Software. No title or ownership of the Software,
56 | any copies of the Software, or the patent, copyright, trade secret,
57 | trademark, trade name or other proprietary rights contained in the
58 | Software is transferred to the TeX Users Group.
59 |
60 | The Adobe trademarks shall not be used in advertising pertaining to the
61 | distribution of the Software without express prior permission from
62 | Adobe. Any such use shall be in accordance with the Adobe trademark
63 | guidelines, available on the Adobe website at
64 | http://www.adobe.com/misc/pdfs/TM GuideforThirdPartiesFinal.pdf.
65 | If any portion of the Software is changed, it cannot be marketed under
66 | Adobe's trademarks unless Adobe, in its sole discretion, approves by a
67 | prior writing the quality of the resulting implementation.
68 |
69 | The TeX Users Group shall have the right to evaluate the Software
70 | provided by Adobe.
71 |
72 | ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
73 | ANY PURPOSE. IT IS PROVIDED "AS-IS" WITHOUT EXPRESS OR IMPLIED
74 | WARRANTY. ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THE SOFTWARE,
75 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
76 | PARTICULAR PURPOSE, AND NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
77 | EVENT SHALL ADOBE BE LIABLE TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL,
78 | INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN
79 | AN ACTION OF CONTRACT NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION
80 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
81 | SOFTWARE. ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE
82 | SOFTWARE.
83 |
84 | Adobe Document Id: 4400078611
85 |
--------------------------------------------------------------------------------
/docs/v1/resources/theme/references.bib:
--------------------------------------------------------------------------------
1 | @ONLINE { P4RuntimeRepo,
2 | title = "p4lang/p4Runtime repository",
3 | subtitle = "P4Runtime Protobuf definition files and specification",
4 | url = "https://github.com/p4lang/p4runtime"
5 | }
6 |
7 | @ONLINE { gRPC,
8 | title = "gRPC main site",
9 | url = "https://grpc.io"
10 | }
11 |
12 | @ONLINE { Proto,
13 | title = "Protocol buffers main site",
14 | url = "https://developers.google.com/protocol-buffers"
15 | }
16 |
17 | @ONLINE { P4.org,
18 | title = "P4.org main site",
19 | url = "https://p4.org/"
20 | }
21 |
22 | @ONLINE { OpenConfig,
23 | title = "the OpenConfig project",
24 | url = "http://openconfig.net"
25 | }
26 |
27 | @ONLINE { Stratum,
28 | title = "the Stratum project",
29 | url = "https://stratumproject.org/"
30 | }
31 |
32 | @ONLINE { P4ComplexTypes,
33 | title = "Complex types in $P4_{16}$",
34 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-p4-type"
35 | }
36 |
37 | @ONLINE { ProtoDefaults,
38 | title = "Default values for Protobuf 3 ($proto3$) fields",
39 | url = "https://developers.google.com/protocol-buffers/docs/proto3#default"
40 | }
41 |
42 | @ONLINE { PIRepo,
43 | title = "p4lang/PI repository",
44 | subtitle = "Legacy repository for P4Runtime, includes reference implementation",
45 | url = "https://github.com/p4lang/PI"
46 | }
47 |
48 | @ONLINE { P4TableProperties,
49 | title = "Table properties in $P4_{16}$",
50 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-table-props"
51 | }
52 |
53 | @ONLINE { P4ValueSets,
54 | title = "Value Sets in $P4_{16}$",
55 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-value-set"
56 | }
57 |
58 | @ONLINE { P4SelectExpr,
59 | title = "Select expressions in $P4_{16}$",
60 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-select"
61 | }
62 |
63 | @ONLINE { P4Revisions110,
64 | title = "Summary of changes made in $P4_{16}$ version 1.1.0",
65 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-summary-of-changes-made-in-version-110"
66 | }
67 |
68 | @ONLINE { P4Revisions122,
69 | title = "Summary of changes made in $P4_{16}$ version 1.2.2",
70 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.4.html#sec-summary-of-changes-made-in-version-122-released-may-17-2021"
71 | }
72 |
73 | @ONLINE { P4Revisions124,
74 | title = "Summary of changes made in $P4_{16}$ version 1.2.4",
75 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.4.html#sec-summary-of-changes-made-in-version-124"
76 | }
77 |
78 | @ONLINE { P4Spec,
79 | title = "$P4_{16}$ 1.2.1 specification",
80 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html"
81 | }
82 |
83 | @ONLINE { PSA,
84 | title = "Portable Switch Architecture specification (v1.1.0)",
85 | url = "https://p4.org/p4-spec/docs/PSA-v1.1.0.html"
86 | }
87 |
88 | @ONLINE { PNA,
89 | title = "Portable NIC Architecture specification (v0.7)",
90 | url = "https://p4.org/p4-spec/docs/PNA-v0.7.html"
91 | }
92 |
93 | @ONLINE { P4Enums,
94 | title = "Enums in $P4_{16}$",
95 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-enum-types"
96 | }
97 |
98 | @ONLINE { ProtoAny,
99 | title = "the Any Protobuf message",
100 | url = "https://developers.google.com/protocol-buffers/docs/proto3#any"
101 | }
102 |
103 | @ONLINE { ProtoExtension,
104 | title = "Protobuf extension feature",
105 | url = "https://protobuf.dev/programming-guides/editions/#extensions"
106 | }
107 |
108 | @ONLINE { gRPCStatus,
109 | title = "the gRPC $Status$ class",
110 | url = "https://github.com/grpc/grpc/blob/master/include/grpcpp/impl/codegen/status.h"
111 | }
112 |
113 | @ONLINE { gRPCStatusCodes,
114 | title = "the gRPC canonical status codes",
115 | url = "https://developers.google.com/maps-booking/reference/grpc-api/status_codes"
116 | }
117 |
118 | @ONLINE { ProtoStatus,
119 | title = "status.proto",
120 | subtitle = "the Protobuf Status message",
121 | url = "https://github.com/grpc/grpc/blob/master/src/proto/grpc/status/status.proto"
122 | }
123 |
124 | @ONLINE { gRPCErrorDetails,
125 | title = "the gRPC C++ error details library",
126 | url = "https://github.com/grpc/grpc/blob/master/include/grpcpp/support/error_details.h"
127 | }
128 |
129 | @ONLINE { P4APIWGCharter,
130 | title = "P4.org API Working Group Charter",
131 | url = "https://p4.org/p4-spec/docs/P4_API_WG_charter.html"
132 | }
133 |
134 | @ONLINE { P4NewTypes,
135 | title = "Introducing new types in $P4_{16}$",
136 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-newtype"
137 | }
138 |
139 | @ONLINE { APIVersioning,
140 | title = "Google Cloud APIs versioning",
141 | url = "https://cloud.google.com/apis/design/versioning"
142 | }
143 |
144 | @ONLINE { APIVersioningBackwardsCompatibility,
145 | title = "Google Cloud APIs versioning - Backwards-compatibility",
146 | url = "https://cloud.google.com/apis/design/versioning#backwards_compatibility"
147 | }
148 |
149 | @ONLINE { SemVer,
150 | title = "Semantic versioning",
151 | url = "https://semver.org/"
152 | }
153 |
154 | @ONLINE { RFC2698,
155 | title = "A Two Rate Three Color Marker",
156 | url = "https://tools.ietf.org/html/rfc2698"
157 | }
158 |
159 | @ONLINE { RFC2697,
160 | title = "A Single Rate Three Color Marker",
161 | url = "https://tools.ietf.org/html/rfc2697"
162 | }
163 |
164 | @ONLINE { P4MatchTypes,
165 | title = "Match types in P4",
166 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-match-kind-type"
167 | }
168 |
169 | @ONLINE { gRPCStreamC,
170 | title = "gRPC Streaming RPCs in C++",
171 | url = "https://grpc.io/docs/tutorials/basic/c.html#streaming-rpcs"
172 | }
173 |
174 | @ONLINE { gRPCAuth,
175 | title = "gRPC Authentication",
176 | url = "https://grpc.io/docs/guides/auth.html"
177 | }
178 |
179 | @ONLINE { P4ActionAnnotations,
180 | title = "P4 standard annotations on table actions",
181 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-table-action-anno"
182 | }
183 |
184 | @ONLINE { PSAActionSelector,
185 | title = "PSA Action Selector",
186 | url = "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#sec-action-selector"
187 | }
188 |
189 | @ONLINE { PSAEmptyGroupActionAppendix,
190 | title = "PSA Empty Group Action Appendix",
191 | url = "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#appendix-empty-action-selector-groups"
192 | }
193 |
194 | @ONLINE { PSAAtomicityOfControlPlaneOps,
195 | title = "PSA Atomicity of Control Plane Operations",
196 | url = "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#sec-atomicity-of-control-plane-api-operations"
197 | }
198 |
199 | @ONLINE { P4Concurrency,
200 | title = "P4 Concurrency Model",
201 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-concurrency"
202 | }
203 |
204 | @ONLINE { PSATranslation,
205 | title = "PSA Data Plane vs Control Plane Types",
206 | url = "https://p4.org/p4-spec/docs/PSA-v1.1.0.html#sec-data-plane-vs-control-plane-values"
207 | }
208 |
209 | @ONLINE { ProtoMessageDifferencer,
210 | title = "The Protobuf MessageDifferencer in the C++ API",
211 | url = "https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.util.message_differencer"
212 | }
213 |
214 | @ONLINE { ProtoOneOfBackwardsCompatibility,
215 | title = "Protobuf OneOf backwards-compatibility issues",
216 | url = "https://developers.google.com/protocol-buffers/docs/proto3#backwards-compatibility-issues"
217 | }
218 |
219 | @ONLINE { P4Annotations,
220 | title = "P4 Annotations",
221 | url = "https://p4.org/p4-spec/docs/P4-16-v1.2.1.html#sec-annotations"
222 | }
223 |
224 | @ONLINE { v1model,
225 | title = "v1model Architecture Definition",
226 | url = "https://github.com/p4lang/p4c/blob/master/p4include/v1model.p4"
227 | }
228 |
229 | @ONLINE { ArenaAllocation,
230 | title = "C++ Arena Allocation Guide",
231 | url = "https://developers.google.com/protocol-buffers/docs/reference/arenas"
232 | }
233 |
234 | @ONLINE { p4c,
235 | title = "P4_16 reference compiler",
236 | url = "https://github.com/p4lang/p4c"
237 | }
238 |
239 | @ONLINE { p4cTestProgramForConstEntries,
240 | title = "P4_16 reference compiler test program table-entries-ternary-bmv2.p4",
241 | url = "https://github.com/p4lang/p4c/blob/main/testdata/p4_16_samples/table-entries-ternary-bmv2.p4"
242 | }
243 |
--------------------------------------------------------------------------------
/docs/v1/resources/theme/p4-theme.yml:
--------------------------------------------------------------------------------
1 | extends: ~
2 | font:
3 | catalog:
4 | UtopiaStd-Regular:
5 | normal: Utopia/utopia-regular.ttf
6 | bold: Utopia/utopia-bold.ttf
7 | italic: Utopia/utopia-italic.ttf
8 | bold_italic: Utopia/utopia-bolditalic.ttf
9 | LuxiMono:
10 | normal: LuxiMono/luximr.ttf
11 | bold: LuxiMono/luximb.ttf
12 | italic: LuxiMono/luximri.ttf
13 | bold_italic: LuxiMono/luximbi.ttf
14 | OpenSans:
15 | normal: OpenSans/OpenSans-Regular.ttf
16 | bold: OpenSans/OpenSans-Bold.ttf
17 | italic: OpenSans/OpenSans-Italic.ttf
18 | bold_italic: OpenSans/OpenSans-BoldItalic.ttf
19 | page:
20 | layout: portrait
21 | initial_zoom: FitH
22 | margin: [0.5in, 0.67in, 0.67in, 0.67in]
23 | # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress
24 | margin_inner: 0.75in
25 | margin_outer: 0.59in
26 | size: A4
27 | numbering:
28 | start-at: toc
29 | base:
30 | text_align: justify
31 | font_color: 333333
32 | font_family: UtopiaStd-Regular
33 | font_size: 10.5
34 | # line_height_length is really just a vertical spacing variable; it's not actually the height of a line
35 | line_height_length: 12
36 | # The Noto font family has a built-in line height of 1.36
37 | # With this line_height, a line of text will occupy a height of 15.78pt
38 | line_height: $base_line_height_length / 10.5
39 | font_size_large: round($base_font_size * 1.25)
40 | font_size_small: round($base_font_size * 0.85)
41 | font_size_min: $base_font_size * 0.75
42 | font_style: normal
43 | border_color: EEEEEE
44 | border_radius: 4
45 | border_width: 0.5
46 | role:
47 | lead:
48 | font_size: $base_font_size_large
49 | line-through:
50 | text_decoration: line-through
51 | underline:
52 | text_decoration: underline
53 | big:
54 | font_size: 1.2em
55 | small:
56 | font_size: 0.8em
57 | subtitle:
58 | font_color: 999999
59 | font_size: 0.8em
60 | font_style: normal_italic
61 | vertical_rhythm: $base_line_height_length
62 | horizontal_rhythm: $base_line_height_length
63 | link:
64 | font_color: 428BCA
65 | # codespan is currently used for monospaced phrases and table cells
66 | codespan:
67 | font_color: #B12146
68 | font_family: OpenSans
69 | kbd:
70 | background_color: F5F5F5
71 | border_color: CCCCCC
72 | border_offset: 2
73 | border_radius: 2
74 | border_width: 0.5
75 | font_family: $codespan_font_family
76 | separator_content: "\u202f+\u202f\u200b"
77 | mark:
78 | background_color: FFFF00
79 | border_offset: 1
80 | menu:
81 | caret_content: "\u00a0\u203a "
82 | font_style: bold
83 | heading:
84 | font-family: OpenSans
85 | font-color: #262626
86 | font-size: 17
87 | font-style: bold
88 | # h1 is used for part titles (book doctype) or the doctitle (article doctype)
89 | h1_font_size: floor($base_font_size * 2.6)
90 | # h2 is used for chapter titles (book doctype only)
91 | h2_font_size: floor($base_font_size * 2.15)
92 | h3_font_size: round($base_font_size * 1.7)
93 | h4_font_size: $base_font_size_large
94 | h5_font_size: $base_font_size
95 | h6_font_size: $base_font_size_small
96 | # rely on built-in line height in Noto
97 | line_height: 1
98 | margin_top: $vertical_rhythm * 0.4
99 | margin_bottom: $vertical_rhythm * 0.9
100 | min_height_after: auto
101 | chapter:
102 | break-before: auto
103 | title_page:
104 | font-family: OpenSans
105 | font-color: #080808
106 | font-size: 25
107 | font-style: bold
108 | text-align: center
109 | logo:
110 | image: image:logo.png[pdfwidth=3.0in,align=center]
111 | subtitle:
112 | font-family: OpenSans
113 | font-color: #080808
114 | font-size: 15
115 | text-align: center
116 | line_height: 1
117 | revision:
118 | font-family: OpenSans
119 | font-color: #080808
120 | font-size: 10
121 | text-align: center
122 | margin_top: $base_font_size * 1.25
123 | block:
124 | margin_bottom: $vertical_rhythm
125 | caption:
126 | align: left
127 | font_size: $base_font_size * 0.95
128 | font_style: italic
129 | # FIXME perhaps set line_height instead of / in addition to margins?
130 | margin_inside: $vertical_rhythm / 3
131 | margin_outside: 0
132 | abstract:
133 | title:
134 | font-family: UtopiaStd-Regular
135 | font-color: #080808
136 | font-size: 15
137 | font-style: italic
138 | text-align: center
139 | admonition:
140 | column_rule_color: $base_border_color
141 | column_rule_width: $base_border_width
142 | padding: [$vertical_rhythm / 3.0, $horizontal_rhythm, $vertical_rhythm / 3.0, $horizontal_rhythm]
143 | label:
144 | text_transform: uppercase
145 | font_style: bold
146 | quote:
147 | font_size: $base_font_size_large
148 | border_color: $base_border_color
149 | border_width: 0
150 | border_left_width: $horizontal_rhythm / 3
151 | padding: [$vertical_rhythm / 4, $horizontal_rhythm, $vertical_rhythm / 4, $horizontal_rhythm + $quote_border_left_width / 2]
152 | cite:
153 | font_size: $base_font_size_small
154 | font_color: $role_subtitle_font_color
155 | verse:
156 | font_size: $quote_font_size
157 | border_color: $quote_border_color
158 | border_width: $quote_border_width
159 | border_left_width: $quote_border_left_width
160 | padding: $quote_padding
161 | cite:
162 | font_size: $quote_cite_font_size
163 | font_color: $quote_cite_font_color
164 | # code is used for literal, listing, and source blocks and literal table cells
165 | code:
166 | font_color: #fcf3d9
167 | font_family: LuxiMono
168 | font_size: 9
169 | padding: $code_font_size
170 | line_height: 1.25
171 | # line_gap is an experimental property to control how a background color is applied to an inline block element
172 | line_gap: 3.8
173 | background_color: F5F5F5
174 | border_color: CCCCCC
175 | border_radius: $base_border_radius
176 | border_width: 0.75
177 | conum:
178 | font_family: $codespan_font_family
179 | font_color: $codespan_font_color
180 | font_size: $base_font_size
181 | line_height: 4 / 3
182 | glyphs: circled
183 | example:
184 | border_color: $base_border_color
185 | border_radius: $base_border_radius
186 | border_width: 0.75
187 | padding: [$vertical_rhythm, $horizontal_rhythm, $vertical_rhythm, $horizontal_rhythm]
188 | image:
189 | caption:
190 | font-family: UtopiaStd-Regular
191 | font-color: #080808
192 | font-size: 10
193 | font-style: italic
194 | text-align: center
195 | prose:
196 | margin_bottom: $block_margin_bottom
197 | sidebar:
198 | background_color: EEEEEE
199 | border_color: E1E1E1
200 | border_radius: $base_border_radius
201 | border_width: $base_border_width
202 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, $vertical_rhythm, $vertical_rhythm * 1.25]
203 | title:
204 | text_align: center
205 | font_color: $heading_font_color
206 | font_size: $heading_h4_font_size
207 | font_style: $heading_font_style
208 | thematic_break:
209 | border_color: $base_border_color
210 | border_style: solid
211 | border_width: $base_border_width
212 | padding: [$vertical_rhythm * 0.5, 0]
213 | list:
214 | indent: $horizontal_rhythm * 1.5
215 | #marker_font_color: 404040
216 | # NOTE list_item_spacing only applies to list items that do not have complex content
217 | item_spacing: $vertical_rhythm / 2
218 | # Force all indent levels of an unordered list to use the same font
219 | # glyph for all symbols, because the fonts we are using do not have
220 | # definitions for any of the ones that asciidoctor-pdf normally uses.
221 | # If we change our fonts to have definitions for the default code points
222 | # used by asciidoctor-pdf, the 'ulist:' section can be deleted.
223 | ulist:
224 | marker:
225 | square:
226 | content: "\u2022"
227 | circle:
228 | content: "\u2022"
229 | checked:
230 | content: "\u2022"
231 | unchecked:
232 | content: "\u2022"
233 | description_list:
234 | term_font_style: bold
235 | term_spacing: $vertical_rhythm / 4
236 | description_indent: $horizontal_rhythm * 1.25
237 | callout_list:
238 | margin_top_after_code: -$block_margin_bottom / 2
239 | table:
240 | border_color: DDDDDD
241 | border_width: $base_border_width
242 | grid_width: $base_border_width
243 | cell_padding: 3
244 | head:
245 | font_style: bold
246 | border_bottom_width: $base_border_width * 2.5
247 | body:
248 | stripe_background_color: F9F9F9
249 | foot:
250 | background_color: F0F0F0
251 | caption:
252 | text-align: center
253 | end: bottom
254 | toc:
255 | indent: $horizontal_rhythm
256 | font-family: OpenSans
257 | font-color: #01226e
258 | font-size: 10
259 | indent: 20
260 | title:
261 | font-family: OpenSans
262 | font-color: #080808
263 | font-size: 15
264 | font-style: bold
265 | dot-leader:
266 | content: ". "
267 | levels: 2 3 4 5
268 | footnotes:
269 | font_size: round($base_font_size * 0.75)
270 | item_spacing: $list_item_spacing / 2
271 | index:
272 | column_gap: $vertical_rhythm
273 | header:
274 | font_size: $base_font_size_small
275 | line_height: 1
276 | vertical_align: middle
277 | footer:
278 | font_size: 10
279 | font-family: UtopiaStd-Regular
280 | height: 1in
281 | columns: =100%
282 | recto:
283 | center:
284 | content: '{page-number}'
285 | verso:
286 | center:
287 | content: '{page-number}'
288 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # P4Runtime Specification
2 |
3 | This directory contains protobuf files, specifications and related artifacts for
4 | all versions of the P4Runtime API. Documentation and protobuf definitions are
5 | placed into two distinct top-level directories. In each of these directories,
6 | files are organized based on the P4Runtime major version number (e.g. v1) as
7 | follows:
8 | ```
9 | .
10 | ├── docs
11 | │ └── v1 # documentation for P4Runtime v1
12 | ├── proto
13 | │ └── p4
14 | │ ├── config
15 | │ │ └── v1 # p4.config.v1 protobuf package (P4Info message definition)
16 | │ └── v1 # p4.v1 protobuf package (P4Runtime service definition)
17 | ```
18 |
19 | Git tags are used to mark minor and patch release versions.
20 |
21 | ## Reading the latest version of the documentation
22 |
23 | The latest version of the P4Runtime v1 specification is available:
24 | * [here](https://p4.org/p4-spec/docs/p4runtime-spec-working-draft-html-version.html)
25 | in **HTML** format
26 | * [here](https://p4.org/p4-spec/docs/p4runtime-spec-working-draft-pdf-version.html)
27 | in **PDF** format
28 |
29 | It is updated every time a new commit is pushed to the main branch.
30 |
31 | ## Overview
32 |
33 | P4 is a language for programming the data plane of network devices. The
34 | P4Runtime API is a control plane specification for controlling the data plane
35 | elements of a device or program defined by a P4 program. This repository
36 | provides a precise definition of the P4Runtime API via protobuf (.proto) files
37 | and accompanying documentation. The target audience for this includes system
38 | architects and developers who want to write controller applications for P4
39 | devices or switches.
40 |
41 | # Community
42 |
43 | * **Meetings**: the P4.org API Working Group meets every other Friday at
44 | 9:30AM (Pacific Time). Please see the [P4 Working Groups Calendar](https://calendar.google.com/calendar/u/0/embed?src=j4to42rsjqtfks0qb7iah8gous@group.calendar.google.com&ctz=America/Los_Angeles)
45 | for meeting details.
46 | * **Email**: join our [mailing
47 | list](https://lists.p4.org/mailman/listinfo/p4-dev_lists.p4.org) to receive
48 | announcements and stay up-to-date with Working Group activities.
49 | * **Slack**: ask to join the [P4 Slack Workspace] to get (or provide!)
50 | interactive help.
51 |
52 | # Compiling P4Runtime Protobuf files
53 |
54 | ## Build Using Docker
55 |
56 | You can use Docker to run the protoc compiler on the P4Runtime Protobuf files
57 | and generate the Protobuf & gRPC bindings for C++, Python and Go:
58 |
59 | ```
60 | docker build -t p4runtime -f codegen/Dockerfile .
61 | docker run -v :/out/ -t p4runtime /p4runtime/codegen/compile_protos.sh /out/
62 | ```
63 |
64 | This will generate the bindings in the local `` directory. **You need to
65 | provide the absolute path for ``.** The default Docker user is root, so you
66 | may need to change the permissions manually for the generated files after the
67 | `docker run` command exits.
68 |
69 | These commands are the ones used by our CI system to ensure that the Protobuf
70 | files stay semantically valid.
71 |
72 | ## Build Using Bazel 
73 |
74 | The protobufs can also be built using [Bazel](https://bazel.build/).
75 | The Bazel WORKSPACE and BUILD files are located in the [proto folder](proto/).
76 |
77 | To build, run
78 | ```sh
79 | cd proto && bazel build //...
80 | ```
81 |
82 | We run [continuous integration](.github/workflows/ci-build-proto.yml) to ensure
83 | this works with the latest version of Bazel.
84 |
85 | For an example of how to include P4Runtime in your own Bazel project, see
86 | [bazel/example](bazel/example).
87 |
88 | # Modification Policy
89 |
90 | We use the following processes when making changes to the P4Runtime
91 | specification and associated documents. These processes are designed to be
92 | lightweight, to encourage active participation by members of the P4.org
93 | community, while also ensuring that all proposed changes are properly vetted
94 | before they are incorporated into the repository and released to the community.
95 |
96 | ## Core Processes
97 |
98 | * Only members of the P4.org community may propose changes to the P4Runtime
99 | specification, and all contributed changes will be governed by the
100 | Apache-style license specified in the P4.org membership agreement.
101 |
102 | * We will use [semantic versioning](http://semver.org/) to track changes to the
103 | P4Runtime specification: major version numbers track API-incompatible changes;
104 | minor version numbers track backward-compatible changes; and patch versions
105 | make backward-compatible bug fixes. Generally speaking, the P4Runtime working
106 | group co-chairs will typically batch together multiple changes into a single
107 | release, as appropriate.
108 |
109 | ## Detailed Processes
110 |
111 | We now identify detailed processes for three classes of changes. The text below
112 | refers to [key
113 | committers](https://github.com/orgs/p4lang/teams/p4lang-key-committers), a
114 | GitHub team that is authorized to modify the specification according to these
115 | processes.
116 |
117 | 1. **Non-Technical Changes:** Changes that do not affect the definition of the
118 | API can be incorporated via a simple, lightweight review process: the author
119 | creates a pull request against the specification that a key committer must
120 | review and approve. The P4Runtime Working Group does not need to be
121 | explicitly notified. Such changes include improvements to the wording of the
122 | specification document, the addition of examples or figures, typo fixes, and
123 | so on.
124 |
125 | 2. **Technical Bug Fixes:** Any changes that repair an ambiguity or flaw in the
126 | current API specification can also be incorporated via the same lightweight
127 | review process: the author creates a GitHub issue as well as a pull request
128 | against the specification that a key committer must review and approve. The
129 | key committer should use their judgment in deciding if the fix should be
130 | incorporated without broader discussion or if it should be escalated to the
131 | P4Runtime Working Group. In any event, the Working Group should be notified
132 | by email.
133 |
134 | 3. **API Changes** Any change that substantially modifies the definition of the
135 | API, or extends it with new features, must be reviewed by the P4Runtime
136 | Working Group, either in an email discussion or a meeting. We imagine that
137 | such proposals would go through three stages: (i) a preliminary proposal with
138 | text that gives the motivation for the change and examples; (ii) a more
139 | detailed proposal with a discussion of relevant issues including the impact
140 | on existing programs; (iii) a final proposal accompanied by a design
141 | document, a pull request against the specification, and prototype
142 | implementation on a branch of `p4runtime`, and example(s) that illustrate the
143 | change. After approval, the author would create a GitHub issue as well as a
144 | pull request against the specification that a key committer must review and
145 | approve.
146 |
147 | >**Generated protobuf files**: When updating the Protobuf files in a pull request, you will also need to update
148 | the generated Go and Python files, which are hosted in this repository under
149 | [go/](go/) and [py/](py/). This can be done easily **by running `./codegen/update.sh`**,
150 | provided docker is installed and your user is part of the "docker" group
151 | (which means that the `docker` command can be executed without `sudo`).
152 |
153 | ## Use generated P4Runtime library
154 |
155 | ### Go
156 |
157 | To include the P4Runtime Go library to your project, you can add this repository url
158 | to your `go.mod` file, for example:
159 |
160 | ```
161 | module your_module_name
162 |
163 | go 1.13
164 |
165 | require (
166 | github.com/p4lang/p4runtime v1.3.0
167 | )
168 | ```
169 |
170 | ### Python
171 |
172 | To install P4Runtime Python library, use the `pip3` command:
173 |
174 | ```bash
175 | pip3 install p4runtime
176 | # Or specify the version
177 | pip3 install p4runtime==1.3.0
178 | ```
179 |
180 | ### Rust
181 |
182 | See the [rust/README.md](rust/README.md).
183 |
184 | ## Guidelines for using Protocol Buffers (protobuf) in backwards-compatible ways
185 |
186 | P4Runtime generally follows "Live at Head" development principles - new
187 | development happens on the `main` branch and there are no support branches.
188 | New releases are periodically created from the head of `main`.
189 |
190 | P4Runtime follows [semantic versioning](https://semver.org/) for release
191 | numbering, which means changes to the P4Runtime protobuf definitions have
192 | implications on the next release number. The team has tried its best so
193 | far to avoid a major version number bump, but recognizes that one may be
194 | necessary in the future.
195 |
196 | Whenever possible, it is best to introduce new functionality in backward
197 | compatible ways. For example when role config was introduced, an unset
198 | (empty) role configuration implies full pipeline access, which was the
199 | default behavior before the feature was introduced.
200 |
201 | There are no strict rules here for updating P4Runtime protobuf message
202 | definitions, only advice written by those with experience in using
203 | protobuf for applications while they have been extended over
204 | time. They are here for learning and reference:
205 |
206 | * [Updating Proto Definitions Without Updating Code](https://developers.google.com/protocol-buffers/docs/overview#updating-defs)
207 | * [Updating A Message Type](https://developers.google.com/protocol-buffers/docs/proto3#updating)
208 | * [Backwards-compatibility issues in `oneof` fields](https://developers.google.com/protocol-buffers/docs/proto3#backwards-compatibility_issues)
209 | * [API design guide](https://cloud.google.com/apis/design)
210 |
211 | Some brief points, but not the full story:
212 |
213 | * Do not change or reuse field numbers.
214 | * Be careful when changing types.
215 | * You can deprecate fields, but do not remove them (and make sure that
216 | you continue to support them) until you are sure that all clients
217 | and servers are updated.
218 |
219 |
220 | [P4 Slack Workspace]: https://p4-lang.slack.com/join/shared_invite/enQtODA0NzY4Mjc5MTExLTRlMWVmN2I5ZTY4MTAzMDI3MGQ1OTZjM2ZmM2Q1MWE2YzZjYTQ2ZWMyMGUyYjQ2ZmIxMjFjZDE4ZThiN2ZkZWI
221 |
--------------------------------------------------------------------------------
/proto/p4/config/v1/p4types.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2013-present Barefoot Networks, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | package p4.config.v1;
18 |
19 | option go_package = "github.com/p4lang/p4runtime/go/p4/config/v1";
20 |
21 | // P4 type specs ---------------------------------------------------------------
22 |
23 | // From the P4_16 spec:
24 | /* |--------------------|--------------------------------------------|
25 | * | | Container type |
26 | * | Element type |-----------|--------------|-----------------|
27 | * | | header | header_union | struct or tuple |
28 | * |--------------------|-----------|--------------|-----------------|
29 | * | bit | allowed | error | allowed |
30 | * | int | allowed | error | allowed |
31 | * | varbit | allowed | error | allowed |
32 | * | int | error | error | error |
33 | * | void | error | error | error |
34 | * | error | error | error | allowed |
35 | * | match_kind | error | error | error |
36 | * | bool | error | error | allowed |
37 | * | enum | allowed* | error | allowed |
38 | * | header | error | allowed | allowed |
39 | * | header stack | error | error | allowed |
40 | * | header_union | error | error | allowed |
41 | * | struct | error | error | allowed |
42 | * | tuple | error | error | allowed |
43 | * |--------------------|-----------|--------------|-----------------|
44 | *
45 | * *if serializable
46 | */
47 |
48 | // These P4 types (struct, header_type, header_union and enum) are guaranteed to
49 | // have a fully-qualified name (e.g. you cannot use an anonymous struct to
50 | // declare a variable like in C). Instead of duplicating the type spec for these
51 | // every time the type is used, we include the type spec once in this P4TypeInfo
52 | // message and refer to the types by name in the P4DataTypeSpec message. We also
53 | // support annotations for these type specs which can be useful, e.g. to
54 | // identify well-known headers (such as ipv4).
55 | message P4TypeInfo {
56 | map structs = 1;
57 | map headers = 2;
58 | map header_unions = 3;
59 | map enums = 4;
60 | P4ErrorTypeSpec error = 5;
61 | map serializable_enums = 6;
62 | map new_types = 7;
63 | }
64 |
65 | // Describes a P4_16 type.
66 | message P4DataTypeSpec {
67 | oneof type_spec {
68 | P4BitstringLikeTypeSpec bitstring = 1;
69 | P4BoolType bool = 2;
70 | P4TupleTypeSpec tuple = 3;
71 | P4NamedType struct = 4;
72 | P4NamedType header = 5;
73 | P4NamedType header_union = 6;
74 | P4HeaderStackTypeSpec header_stack = 7;
75 | P4HeaderUnionStackTypeSpec header_union_stack = 8;
76 | P4NamedType enum = 9;
77 | P4ErrorType error = 10;
78 | P4NamedType serializable_enum = 11;
79 | P4NamedType new_type = 12;
80 | }
81 | }
82 |
83 | message P4NamedType {
84 | string name = 1;
85 | }
86 |
87 | // Empty message as no type information needed, just used as a placeholder in
88 | // the oneof to identify boolean types.
89 | message P4BoolType { }
90 |
91 | message P4ErrorType { }
92 |
93 | message P4BitstringLikeTypeSpec {
94 | oneof type_spec {
95 | P4BitTypeSpec bit = 1; // bit
96 | P4IntTypeSpec int = 2; // int
97 | P4VarbitTypeSpec varbit = 3; // varbit
98 | }
99 | // Useful to identify well-known types, such as IP address or Ethernet MAC
100 | // address.
101 | repeated string annotations = 4;
102 | // Optional. If present, the location of `annotations[i]` is given by
103 | // `annotation_locations[i]`.
104 | repeated SourceLocation annotation_locations = 5;
105 | repeated StructuredAnnotation structured_annotations = 6;
106 | }
107 |
108 | message P4BitTypeSpec {
109 | int32 bitwidth = 1;
110 | }
111 |
112 | message P4IntTypeSpec {
113 | int32 bitwidth = 1;
114 | }
115 |
116 | message P4VarbitTypeSpec {
117 | int32 max_bitwidth = 1;
118 | }
119 |
120 | // From the P4_16 spec: "A tuple is similar to a struct, in that it holds
121 | // multiple values. Unlike a struct type, tuples have no named fields."
122 | message P4TupleTypeSpec {
123 | repeated P4DataTypeSpec members = 1;
124 | }
125 |
126 | message P4StructTypeSpec {
127 | message Member {
128 | string name = 1;
129 | P4DataTypeSpec type_spec = 2;
130 | }
131 | repeated Member members = 1;
132 | repeated string annotations = 2;
133 | // Optional. If present, the location of `annotations[i]` is given by
134 | // `annotation_locations[i]`.
135 | repeated SourceLocation annotation_locations = 3;
136 | repeated StructuredAnnotation structured_annotations = 4;
137 | }
138 |
139 | message P4HeaderTypeSpec {
140 | message Member {
141 | string name = 1;
142 | P4BitstringLikeTypeSpec type_spec = 2;
143 | }
144 | repeated Member members = 1;
145 | repeated string annotations = 2;
146 | // Optional. If present, the location of `annotations[i]` is given by
147 | // `annotation_locations[i]`.
148 | repeated SourceLocation annotation_locations = 3;
149 | repeated StructuredAnnotation structured_annotations = 4;
150 | }
151 |
152 | message P4HeaderUnionTypeSpec {
153 | message Member {
154 | string name = 1;
155 | P4NamedType header = 2;
156 | }
157 | repeated Member members = 1;
158 | repeated string annotations = 2;
159 | // Optional. If present, the location of `annotations[i]` is given by
160 | // `annotation_locations[i]`.
161 | repeated SourceLocation annotation_locations = 3;
162 | repeated StructuredAnnotation structured_annotations = 4;
163 | }
164 |
165 | message P4HeaderStackTypeSpec {
166 | P4NamedType header = 1;
167 | int32 size = 2;
168 | }
169 |
170 | message P4HeaderUnionStackTypeSpec {
171 | P4NamedType header_union = 1;
172 | int32 size = 2;
173 | }
174 |
175 | message KeyValuePair {
176 | string key = 1;
177 | Expression value = 2;
178 | }
179 |
180 | message KeyValuePairList {
181 | repeated KeyValuePair kv_pairs = 1;
182 | }
183 |
184 | message Expression {
185 | oneof value {
186 | string string_value = 1;
187 | int64 int64_value = 2;
188 | bool bool_value = 3;
189 | }
190 | }
191 |
192 | message ExpressionList {
193 | repeated Expression expressions = 1;
194 | }
195 |
196 | message StructuredAnnotation {
197 | string name = 1;
198 | oneof body {
199 | ExpressionList expression_list = 2;
200 | KeyValuePairList kv_pair_list = 3;
201 | }
202 | // Optional. Location of the '@' symbol of this annotation in the source code.
203 | SourceLocation source_location = 4;
204 | }
205 |
206 | // Location of code relative to a given source file.
207 | message SourceLocation {
208 | // Path to the source file (absolute or relative to the working directory).
209 | string file = 1;
210 | // Line and column numbers within the source file, 1-based.
211 | int32 line = 2;
212 | int32 column = 3;
213 | }
214 |
215 | // For "safe" enums with no underlying representation and no member integer
216 | // values.
217 | message P4EnumTypeSpec {
218 | message Member {
219 | string name = 1;
220 | repeated string annotations = 2;
221 | // Optional. If present, the location of `annotations[i]` is given by
222 | // `annotation_locations[i]`.
223 | repeated SourceLocation annotation_locations = 4;
224 | repeated StructuredAnnotation structured_annotations = 3;
225 | }
226 | repeated Member members = 1;
227 | repeated string annotations = 2;
228 | // Optional. If present, the location of `annotations[i]` is given by
229 | // `annotation_locations[i]`.
230 | repeated SourceLocation annotation_locations = 4;
231 | repeated StructuredAnnotation structured_annotations = 3;
232 | }
233 |
234 | // For serializable (or "unsafe") enums, which have an underlying type. Note
235 | // that as per the P4_16 specification, the underlying representation can only
236 | // be a bit type.
237 | message P4SerializableEnumTypeSpec {
238 | message Member {
239 | string name = 1;
240 | bytes value = 2;
241 | repeated string annotations = 3;
242 | // Optional. If present, the location of `annotations[i]` is given by
243 | // `annotation_locations[i]`.
244 | repeated SourceLocation annotation_locations = 5;
245 | repeated StructuredAnnotation structured_annotations = 4;
246 | }
247 | P4BitTypeSpec underlying_type = 1;
248 | repeated Member members = 2;
249 | repeated string annotations = 3;
250 | // Optional. If present, the location of `annotations[i]` is given by
251 | // `annotation_locations[i]`.
252 | repeated SourceLocation annotation_locations = 5;
253 | repeated StructuredAnnotation structured_annotations = 4;
254 | }
255 |
256 | // Similar to an enum, but there is always one and only one instance per P4
257 | // program.
258 | message P4ErrorTypeSpec {
259 | repeated string members = 1;
260 | }
261 |
262 | message P4NewTypeTranslation {
263 | message SdnString {}
264 |
265 | // the URI uniquely identifies the translation in order to enable the
266 | // P4Runtime agent to perform value-mapping appropriately when required. It is
267 | // recommended that the URI includes at least the P4 architecture name and the
268 | // type name.
269 | string uri = 1;
270 |
271 | // The object is either represented as an unsigned integer with a bitwidth of
272 | // `sdn_bitwidth`, or as a string.
273 | oneof sdn_type {
274 | int32 sdn_bitwidth = 2;
275 | SdnString sdn_string = 3;
276 | }
277 | }
278 |
279 | // New types introduced with the "type" keyword
280 | message P4NewTypeSpec {
281 | oneof representation {
282 | // if no @p4runtime_translation annotation present
283 | P4DataTypeSpec original_type = 1;
284 | // if @p4runtime_translation annotation present
285 | P4NewTypeTranslation translated_type = 2;
286 | }
287 | // for other annotations (not @p4runtime_translation)
288 | repeated string annotations = 3;
289 | // Optional. If present, the location of `annotations[i]` is given by
290 | // `annotation_locations[i]`.
291 | repeated SourceLocation annotation_locations = 5;
292 | repeated StructuredAnnotation structured_annotations = 4;
293 | }
294 |
295 | // End of P4 type specs --------------------------------------------------------
296 |
--------------------------------------------------------------------------------
/tools/asciidoclint.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # Copyright 2024
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 |
18 |
19 | # DISCLAIMER: This is a work in progress. This linter was written specifically
20 | # for the P4Runtime specification document and may not be useful for other
21 | # AsciiDoc documents, as it may be making some assumptions as to how the document
22 | # was written.
23 |
24 |
25 |
26 |
27 | import argparse
28 | from collections import namedtuple
29 | import json
30 | import os.path
31 | import re
32 | import sys
33 | import traceback
34 |
35 |
36 | DEFAULT_CONF = 'asciidocint.conf.json'
37 | LINE_WRAP_LENGTH = 80
38 |
39 |
40 | parser = argparse.ArgumentParser(description='Lint tool for Asciidoc code')
41 | parser.add_argument('files', metavar='FILE', type=str, nargs='+',
42 | help='Input files')
43 | parser.add_argument('--conf', type=str,
44 | help='Configuration file for lint tool')
45 |
46 |
47 | class AsciidocFmtError(Exception):
48 | def __init__(self, filename, lineno, description):
49 | self.filename = filename
50 | self.lineno = lineno
51 | self.description = description
52 |
53 | def __str__(self):
54 | return "Unexpected Asciidoc code in file {} at line {}: {}".format(
55 | self.filename, self.lineno, self.description)
56 |
57 |
58 | class LintState:
59 | def __init__(self):
60 | self.errors_cnt = 0
61 |
62 | def error(self, filename, lineno, line, description):
63 | # TODO: print line later?
64 | print("Error in file {} at line {}: {}.".format(filename, lineno, description))
65 | self.errors_cnt += 1
66 |
67 |
68 | lint_state = LintState()
69 |
70 |
71 | class LintConf:
72 | class BadConfException(Exception):
73 | def __init__(self, what):
74 | self.what = what
75 |
76 | def __str__(self):
77 | return self.what
78 |
79 |
80 | def __init__(self):
81 | self.keywords = {}
82 |
83 | def build_from(self, conf_fp):
84 | try:
85 | conf_d = json.load(conf_fp)
86 | for entry in conf_d['keywords']:
87 | category = entry['category']
88 | for keyword in entry['keywords']:
89 | if keyword in self.keywords:
90 | raise LintConf.BadConfException(
91 | "Keyword '{}' is present multiple times in configuration".format(
92 | keyword))
93 | self.keywords[keyword] = category
94 | except json.JSONDecodeError:
95 | print("Provided configuration file is not a valid JSON file")
96 | sys.exit(1)
97 | except KeyError:
98 | print("Provided JSON configuration file has missing attributes")
99 | traceback.print_exc()
100 | sys.exit(1)
101 | except LintConf.BadConfException as e:
102 | print(str(e))
103 | sys.exit(1)
104 |
105 |
106 | lint_conf = LintConf()
107 |
108 |
109 | class Context:
110 | """A context is an object that is used to determine whether a specific "checker" (check_*
111 | method) should visit a given line."""
112 |
113 | def enter(self, line, filename, lineno):
114 | """Called before visiting a line.
115 | Returns True iff the checker should visit the given line.
116 | """
117 | return True
118 |
119 | def exit(self, line, filename, lineno):
120 | """Called after visiting a line."""
121 | pass
122 |
123 |
124 | class ContextSkipBlocks(Context):
125 | """A context used to only visit Asciidoc code outside of blocks."""
126 |
127 | Block = namedtuple('Block', ['num_tildes', 'name'])
128 |
129 | def __init__(self):
130 | self.p_block = re.compile('^ *(?P~+) *(?:(?PBegin|End)(?: +))?(?P\w+)?')
131 | self.blocks_stack = []
132 |
133 | def enter(self, line, filename, lineno):
134 | m = self.p_block.match(line)
135 | if m:
136 | num_tildes = len(m.group("tildes"))
137 | has_begin = m.group("cmd") == "Begin"
138 | has_end = m.group("cmd") == "End"
139 | blockname = m.group("name")
140 |
141 | if has_begin:
142 | self.blocks_stack.append(self.Block(num_tildes, blockname))
143 | return False
144 | if has_end:
145 | if not self.blocks_stack:
146 | raise AsciidocFmtError(filename, lineno, "Block end line but no block was begun")
147 | expected = self.blocks_stack.pop()
148 | if num_tildes != expected.num_tildes or blockname != expected.name:
149 | raise AsciidocFmtError(
150 | filename, lineno,
151 | "Block end line does not match last visited block begin line")
152 | return False
153 | if blockname is None:
154 | if not self.blocks_stack:
155 | raise AsciidocFmtError(filename, lineno, "Block end line but no block was begun")
156 | expected = self.blocks_stack.pop()
157 | if num_tildes != expected.num_tildes:
158 | raise AsciidocFmtError(
159 | filename, lineno,
160 | "Block end line does not match last visited block begin line")
161 | return False
162 | self.blocks_stack.append(self.Block(num_tildes, blockname))
163 | return False
164 | if self.blocks_stack:
165 | return False
166 | return True
167 |
168 |
169 | # TODO: would "skip metadata" be more generic?
170 | class ContextAfterTitle(Context):
171 | """A context used to visit only Asciidoc code after the [TITLE] block element.
172 | """
173 |
174 | def __init__(self, *args):
175 | self.title_found = False
176 | self.p_title = re.compile('^ *\[TITLE\] *$')
177 |
178 | def enter(self, line, filename, lineno):
179 | if self.title_found:
180 | return True
181 | self.title_found = self.p_title.match(line) is not None
182 | return False
183 |
184 |
185 | class ContextSkipHeadings(Context):
186 | """A context used to skip headings (lines starting with #)."""
187 |
188 | def __init__(self, *args):
189 | self.p_headings = re.compile('^ *#')
190 |
191 | def enter(self, line, filename, lineno):
192 | return self.p_headings.match(line) is None
193 |
194 |
195 | class ContextCompose(Context):
196 | """A special context used to combine an arbitrary number of contexts."""
197 |
198 | def __init__(self, *args):
199 | self.contexts = list(args)
200 |
201 | def enter(self, line, filename, lineno):
202 | res = True
203 | for c in self.contexts:
204 | # we use a short-circuit on purpose, if a context returns False we do not even enter
205 | # subsequent contexts. This has some implications on how contexts are used.
206 | res = res and c.enter(line, filename, lineno)
207 | return res
208 |
209 | def exit(self, line, filename, lineno):
210 | for c in self.contexts:
211 | c.exit(line, filename, lineno)
212 |
213 |
214 | def foreach_line(path, context, fn):
215 | """Iterate over every line in the file. For each line, call fn iff the enter method of the
216 | provided context returns True."""
217 | lineno = 1
218 | with open(path, 'r') as f:
219 | for line in f:
220 | if context.enter(line, path, lineno):
221 | fn(line, lineno)
222 | lineno += 1
223 | context.exit(line, path, lineno)
224 |
225 |
226 | def check_line_wraps(path):
227 | def check(line, lineno):
228 | if "http" in line: # TODO: we can probably do better than this
229 | return
230 | if len(line) > LINE_WRAP_LENGTH + 1: # +1 for the newline characted
231 | lint_state.error(path, lineno, line,
232 | "is more than {} characters long".format(LINE_WRAP_LENGTH))
233 |
234 | foreach_line(path,
235 | ContextCompose(ContextAfterTitle(), ContextSkipBlocks(), ContextSkipHeadings()),
236 | check)
237 |
238 |
239 | def check_trailing_whitespace(path):
240 | def check(line, lineno):
241 | if len(line) >= 2 and line[-2].isspace():
242 | lint_state.error(path, lineno, line, "trailing whitespace")
243 |
244 | foreach_line(path, Context(), check)
245 |
246 |
247 | def check_keywords(path):
248 | def check(line, lineno):
249 | for word in line.split():
250 | if word not in lint_conf.keywords:
251 | continue
252 | category = lint_conf.keywords[word]
253 | lint_state.error(
254 | path, lineno, line,
255 | "'{}' is a known keyword ({}), highlight it with backticks".format(word, category))
256 |
257 | foreach_line(path, ContextCompose(ContextAfterTitle(), ContextSkipBlocks()), check)
258 |
259 |
260 | def process_one(path):
261 | check_line_wraps(path)
262 | check_trailing_whitespace(path)
263 | check_keywords(path)
264 |
265 |
266 | def main():
267 | args = parser.parse_args()
268 |
269 | for f in args.files:
270 | if not os.path.isfile(f):
271 | print("'{}' is not a valid file path".format(f))
272 | sys.exit(1)
273 | _, ext = os.path.splitext(f)
274 | if ext != ".adoc":
275 | print("'{}' does not have an .mdk extension")
276 | sys.exit(1)
277 |
278 | conf_path = None
279 | if args.conf is not None:
280 | if not os.path.isfile(args.conf):
281 | print("'{}' is not a valid file path".format(args.conf))
282 | sys.exit(1)
283 | conf_path = args.conf
284 | elif os.path.isfile(DEFAULT_CONF): # search working directory
285 | conf_path = DEFAULT_CONF
286 | else: # search directory of Python script
287 | this_dir = os.path.dirname(os.path.abspath(__file__))
288 | path = os.path.join(this_dir, DEFAULT_CONF)
289 | if os.path.isfile(path):
290 | conf_path = path
291 |
292 | if conf_path is not None:
293 | with open(conf_path, 'r') as conf_fp:
294 | lint_conf.build_from(conf_fp)
295 |
296 | for f in args.files:
297 | try:
298 | process_one(f)
299 | except AsciidocFmtError as e:
300 | print(e)
301 |
302 | errors_cnt = lint_state.errors_cnt
303 | print("**********")
304 | print("Errors found: {}".format(errors_cnt))
305 | rc = 0 if errors_cnt == 0 else 2
306 | sys.exit(rc)
307 |
308 |
309 | if __name__ == '__main__':
310 | main()
311 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/proto/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/py/p4/v1/p4runtime_pb2_grpc.py:
--------------------------------------------------------------------------------
1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
2 | """Client and server classes corresponding to protobuf-defined services."""
3 | import grpc
4 |
5 | from p4.v1 import p4runtime_pb2 as p4_dot_v1_dot_p4runtime__pb2
6 |
7 |
8 | class P4RuntimeStub(object):
9 | """Missing associated documentation comment in .proto file."""
10 |
11 | def __init__(self, channel):
12 | """Constructor.
13 |
14 | Args:
15 | channel: A grpc.Channel.
16 | """
17 | self.Write = channel.unary_unary(
18 | '/p4.v1.P4Runtime/Write',
19 | request_serializer=p4_dot_v1_dot_p4runtime__pb2.WriteRequest.SerializeToString,
20 | response_deserializer=p4_dot_v1_dot_p4runtime__pb2.WriteResponse.FromString,
21 | )
22 | self.Read = channel.unary_stream(
23 | '/p4.v1.P4Runtime/Read',
24 | request_serializer=p4_dot_v1_dot_p4runtime__pb2.ReadRequest.SerializeToString,
25 | response_deserializer=p4_dot_v1_dot_p4runtime__pb2.ReadResponse.FromString,
26 | )
27 | self.SetForwardingPipelineConfig = channel.unary_unary(
28 | '/p4.v1.P4Runtime/SetForwardingPipelineConfig',
29 | request_serializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigRequest.SerializeToString,
30 | response_deserializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigResponse.FromString,
31 | )
32 | self.GetForwardingPipelineConfig = channel.unary_unary(
33 | '/p4.v1.P4Runtime/GetForwardingPipelineConfig',
34 | request_serializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigRequest.SerializeToString,
35 | response_deserializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigResponse.FromString,
36 | )
37 | self.StreamChannel = channel.stream_stream(
38 | '/p4.v1.P4Runtime/StreamChannel',
39 | request_serializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageRequest.SerializeToString,
40 | response_deserializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageResponse.FromString,
41 | )
42 | self.Capabilities = channel.unary_unary(
43 | '/p4.v1.P4Runtime/Capabilities',
44 | request_serializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesRequest.SerializeToString,
45 | response_deserializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesResponse.FromString,
46 | )
47 |
48 |
49 | class P4RuntimeServicer(object):
50 | """Missing associated documentation comment in .proto file."""
51 |
52 | def Write(self, request, context):
53 | """Update one or more P4 entities on the target.
54 | """
55 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
56 | context.set_details('Method not implemented!')
57 | raise NotImplementedError('Method not implemented!')
58 |
59 | def Read(self, request, context):
60 | """Read one or more P4 entities from the target.
61 | """
62 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
63 | context.set_details('Method not implemented!')
64 | raise NotImplementedError('Method not implemented!')
65 |
66 | def SetForwardingPipelineConfig(self, request, context):
67 | """Sets the P4 forwarding-pipeline config.
68 | """
69 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
70 | context.set_details('Method not implemented!')
71 | raise NotImplementedError('Method not implemented!')
72 |
73 | def GetForwardingPipelineConfig(self, request, context):
74 | """Gets the current P4 forwarding-pipeline config.
75 | """
76 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
77 | context.set_details('Method not implemented!')
78 | raise NotImplementedError('Method not implemented!')
79 |
80 | def StreamChannel(self, request_iterator, context):
81 | """Represents the bidirectional stream between the controller and the
82 | switch (initiated by the controller), and is managed for the following
83 | purposes:
84 | - connection initiation through client arbitration
85 | - indicating switch session liveness: the session is live when switch
86 | sends a positive client arbitration update to the controller, and is
87 | considered dead when either the stream breaks or the switch sends a
88 | negative update for client arbitration
89 | - the controller sending/receiving packets to/from the switch
90 | - streaming of notifications from the switch
91 | """
92 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
93 | context.set_details('Method not implemented!')
94 | raise NotImplementedError('Method not implemented!')
95 |
96 | def Capabilities(self, request, context):
97 | """Missing associated documentation comment in .proto file."""
98 | context.set_code(grpc.StatusCode.UNIMPLEMENTED)
99 | context.set_details('Method not implemented!')
100 | raise NotImplementedError('Method not implemented!')
101 |
102 |
103 | def add_P4RuntimeServicer_to_server(servicer, server):
104 | rpc_method_handlers = {
105 | 'Write': grpc.unary_unary_rpc_method_handler(
106 | servicer.Write,
107 | request_deserializer=p4_dot_v1_dot_p4runtime__pb2.WriteRequest.FromString,
108 | response_serializer=p4_dot_v1_dot_p4runtime__pb2.WriteResponse.SerializeToString,
109 | ),
110 | 'Read': grpc.unary_stream_rpc_method_handler(
111 | servicer.Read,
112 | request_deserializer=p4_dot_v1_dot_p4runtime__pb2.ReadRequest.FromString,
113 | response_serializer=p4_dot_v1_dot_p4runtime__pb2.ReadResponse.SerializeToString,
114 | ),
115 | 'SetForwardingPipelineConfig': grpc.unary_unary_rpc_method_handler(
116 | servicer.SetForwardingPipelineConfig,
117 | request_deserializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigRequest.FromString,
118 | response_serializer=p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigResponse.SerializeToString,
119 | ),
120 | 'GetForwardingPipelineConfig': grpc.unary_unary_rpc_method_handler(
121 | servicer.GetForwardingPipelineConfig,
122 | request_deserializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigRequest.FromString,
123 | response_serializer=p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigResponse.SerializeToString,
124 | ),
125 | 'StreamChannel': grpc.stream_stream_rpc_method_handler(
126 | servicer.StreamChannel,
127 | request_deserializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageRequest.FromString,
128 | response_serializer=p4_dot_v1_dot_p4runtime__pb2.StreamMessageResponse.SerializeToString,
129 | ),
130 | 'Capabilities': grpc.unary_unary_rpc_method_handler(
131 | servicer.Capabilities,
132 | request_deserializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesRequest.FromString,
133 | response_serializer=p4_dot_v1_dot_p4runtime__pb2.CapabilitiesResponse.SerializeToString,
134 | ),
135 | }
136 | generic_handler = grpc.method_handlers_generic_handler(
137 | 'p4.v1.P4Runtime', rpc_method_handlers)
138 | server.add_generic_rpc_handlers((generic_handler,))
139 |
140 |
141 | # This class is part of an EXPERIMENTAL API.
142 | class P4Runtime(object):
143 | """Missing associated documentation comment in .proto file."""
144 |
145 | @staticmethod
146 | def Write(request,
147 | target,
148 | options=(),
149 | channel_credentials=None,
150 | call_credentials=None,
151 | insecure=False,
152 | compression=None,
153 | wait_for_ready=None,
154 | timeout=None,
155 | metadata=None):
156 | return grpc.experimental.unary_unary(request, target, '/p4.v1.P4Runtime/Write',
157 | p4_dot_v1_dot_p4runtime__pb2.WriteRequest.SerializeToString,
158 | p4_dot_v1_dot_p4runtime__pb2.WriteResponse.FromString,
159 | options, channel_credentials,
160 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
161 |
162 | @staticmethod
163 | def Read(request,
164 | target,
165 | options=(),
166 | channel_credentials=None,
167 | call_credentials=None,
168 | insecure=False,
169 | compression=None,
170 | wait_for_ready=None,
171 | timeout=None,
172 | metadata=None):
173 | return grpc.experimental.unary_stream(request, target, '/p4.v1.P4Runtime/Read',
174 | p4_dot_v1_dot_p4runtime__pb2.ReadRequest.SerializeToString,
175 | p4_dot_v1_dot_p4runtime__pb2.ReadResponse.FromString,
176 | options, channel_credentials,
177 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
178 |
179 | @staticmethod
180 | def SetForwardingPipelineConfig(request,
181 | target,
182 | options=(),
183 | channel_credentials=None,
184 | call_credentials=None,
185 | insecure=False,
186 | compression=None,
187 | wait_for_ready=None,
188 | timeout=None,
189 | metadata=None):
190 | return grpc.experimental.unary_unary(request, target, '/p4.v1.P4Runtime/SetForwardingPipelineConfig',
191 | p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigRequest.SerializeToString,
192 | p4_dot_v1_dot_p4runtime__pb2.SetForwardingPipelineConfigResponse.FromString,
193 | options, channel_credentials,
194 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
195 |
196 | @staticmethod
197 | def GetForwardingPipelineConfig(request,
198 | target,
199 | options=(),
200 | channel_credentials=None,
201 | call_credentials=None,
202 | insecure=False,
203 | compression=None,
204 | wait_for_ready=None,
205 | timeout=None,
206 | metadata=None):
207 | return grpc.experimental.unary_unary(request, target, '/p4.v1.P4Runtime/GetForwardingPipelineConfig',
208 | p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigRequest.SerializeToString,
209 | p4_dot_v1_dot_p4runtime__pb2.GetForwardingPipelineConfigResponse.FromString,
210 | options, channel_credentials,
211 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
212 |
213 | @staticmethod
214 | def StreamChannel(request_iterator,
215 | target,
216 | options=(),
217 | channel_credentials=None,
218 | call_credentials=None,
219 | insecure=False,
220 | compression=None,
221 | wait_for_ready=None,
222 | timeout=None,
223 | metadata=None):
224 | return grpc.experimental.stream_stream(request_iterator, target, '/p4.v1.P4Runtime/StreamChannel',
225 | p4_dot_v1_dot_p4runtime__pb2.StreamMessageRequest.SerializeToString,
226 | p4_dot_v1_dot_p4runtime__pb2.StreamMessageResponse.FromString,
227 | options, channel_credentials,
228 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
229 |
230 | @staticmethod
231 | def Capabilities(request,
232 | target,
233 | options=(),
234 | channel_credentials=None,
235 | call_credentials=None,
236 | insecure=False,
237 | compression=None,
238 | wait_for_ready=None,
239 | timeout=None,
240 | metadata=None):
241 | return grpc.experimental.unary_unary(request, target, '/p4.v1.P4Runtime/Capabilities',
242 | p4_dot_v1_dot_p4runtime__pb2.CapabilitiesRequest.SerializeToString,
243 | p4_dot_v1_dot_p4runtime__pb2.CapabilitiesResponse.FromString,
244 | options, channel_credentials,
245 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
246 |
--------------------------------------------------------------------------------
/go/p4/v1/p4runtime_grpc.pb.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2016, Google Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
16 | // versions:
17 | // - protoc-gen-go-grpc v1.3.0
18 | // - protoc v3.18.1
19 | // source: p4/v1/p4runtime.proto
20 |
21 | // This package and its contents are a work-in-progress.
22 |
23 | package v1
24 |
25 | import (
26 | context "context"
27 | grpc "google.golang.org/grpc"
28 | codes "google.golang.org/grpc/codes"
29 | status "google.golang.org/grpc/status"
30 | )
31 |
32 | // This is a compile-time assertion to ensure that this generated file
33 | // is compatible with the grpc package it is being compiled against.
34 | // Requires gRPC-Go v1.32.0 or later.
35 | const _ = grpc.SupportPackageIsVersion7
36 |
37 | const (
38 | P4Runtime_Write_FullMethodName = "/p4.v1.P4Runtime/Write"
39 | P4Runtime_Read_FullMethodName = "/p4.v1.P4Runtime/Read"
40 | P4Runtime_SetForwardingPipelineConfig_FullMethodName = "/p4.v1.P4Runtime/SetForwardingPipelineConfig"
41 | P4Runtime_GetForwardingPipelineConfig_FullMethodName = "/p4.v1.P4Runtime/GetForwardingPipelineConfig"
42 | P4Runtime_StreamChannel_FullMethodName = "/p4.v1.P4Runtime/StreamChannel"
43 | P4Runtime_Capabilities_FullMethodName = "/p4.v1.P4Runtime/Capabilities"
44 | )
45 |
46 | // P4RuntimeClient is the client API for P4Runtime service.
47 | //
48 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
49 | type P4RuntimeClient interface {
50 | // Update one or more P4 entities on the target.
51 | Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error)
52 | // Read one or more P4 entities from the target.
53 | Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (P4Runtime_ReadClient, error)
54 | // Sets the P4 forwarding-pipeline config.
55 | SetForwardingPipelineConfig(ctx context.Context, in *SetForwardingPipelineConfigRequest, opts ...grpc.CallOption) (*SetForwardingPipelineConfigResponse, error)
56 | // Gets the current P4 forwarding-pipeline config.
57 | GetForwardingPipelineConfig(ctx context.Context, in *GetForwardingPipelineConfigRequest, opts ...grpc.CallOption) (*GetForwardingPipelineConfigResponse, error)
58 | // Represents the bidirectional stream between the controller and the
59 | // switch (initiated by the controller), and is managed for the following
60 | // purposes:
61 | // - connection initiation through client arbitration
62 | // - indicating switch session liveness: the session is live when switch
63 | // sends a positive client arbitration update to the controller, and is
64 | // considered dead when either the stream breaks or the switch sends a
65 | // negative update for client arbitration
66 | // - the controller sending/receiving packets to/from the switch
67 | // - streaming of notifications from the switch
68 | StreamChannel(ctx context.Context, opts ...grpc.CallOption) (P4Runtime_StreamChannelClient, error)
69 | Capabilities(ctx context.Context, in *CapabilitiesRequest, opts ...grpc.CallOption) (*CapabilitiesResponse, error)
70 | }
71 |
72 | type p4RuntimeClient struct {
73 | cc grpc.ClientConnInterface
74 | }
75 |
76 | func NewP4RuntimeClient(cc grpc.ClientConnInterface) P4RuntimeClient {
77 | return &p4RuntimeClient{cc}
78 | }
79 |
80 | func (c *p4RuntimeClient) Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error) {
81 | out := new(WriteResponse)
82 | err := c.cc.Invoke(ctx, P4Runtime_Write_FullMethodName, in, out, opts...)
83 | if err != nil {
84 | return nil, err
85 | }
86 | return out, nil
87 | }
88 |
89 | func (c *p4RuntimeClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (P4Runtime_ReadClient, error) {
90 | stream, err := c.cc.NewStream(ctx, &P4Runtime_ServiceDesc.Streams[0], P4Runtime_Read_FullMethodName, opts...)
91 | if err != nil {
92 | return nil, err
93 | }
94 | x := &p4RuntimeReadClient{stream}
95 | if err := x.ClientStream.SendMsg(in); err != nil {
96 | return nil, err
97 | }
98 | if err := x.ClientStream.CloseSend(); err != nil {
99 | return nil, err
100 | }
101 | return x, nil
102 | }
103 |
104 | type P4Runtime_ReadClient interface {
105 | Recv() (*ReadResponse, error)
106 | grpc.ClientStream
107 | }
108 |
109 | type p4RuntimeReadClient struct {
110 | grpc.ClientStream
111 | }
112 |
113 | func (x *p4RuntimeReadClient) Recv() (*ReadResponse, error) {
114 | m := new(ReadResponse)
115 | if err := x.ClientStream.RecvMsg(m); err != nil {
116 | return nil, err
117 | }
118 | return m, nil
119 | }
120 |
121 | func (c *p4RuntimeClient) SetForwardingPipelineConfig(ctx context.Context, in *SetForwardingPipelineConfigRequest, opts ...grpc.CallOption) (*SetForwardingPipelineConfigResponse, error) {
122 | out := new(SetForwardingPipelineConfigResponse)
123 | err := c.cc.Invoke(ctx, P4Runtime_SetForwardingPipelineConfig_FullMethodName, in, out, opts...)
124 | if err != nil {
125 | return nil, err
126 | }
127 | return out, nil
128 | }
129 |
130 | func (c *p4RuntimeClient) GetForwardingPipelineConfig(ctx context.Context, in *GetForwardingPipelineConfigRequest, opts ...grpc.CallOption) (*GetForwardingPipelineConfigResponse, error) {
131 | out := new(GetForwardingPipelineConfigResponse)
132 | err := c.cc.Invoke(ctx, P4Runtime_GetForwardingPipelineConfig_FullMethodName, in, out, opts...)
133 | if err != nil {
134 | return nil, err
135 | }
136 | return out, nil
137 | }
138 |
139 | func (c *p4RuntimeClient) StreamChannel(ctx context.Context, opts ...grpc.CallOption) (P4Runtime_StreamChannelClient, error) {
140 | stream, err := c.cc.NewStream(ctx, &P4Runtime_ServiceDesc.Streams[1], P4Runtime_StreamChannel_FullMethodName, opts...)
141 | if err != nil {
142 | return nil, err
143 | }
144 | x := &p4RuntimeStreamChannelClient{stream}
145 | return x, nil
146 | }
147 |
148 | type P4Runtime_StreamChannelClient interface {
149 | Send(*StreamMessageRequest) error
150 | Recv() (*StreamMessageResponse, error)
151 | grpc.ClientStream
152 | }
153 |
154 | type p4RuntimeStreamChannelClient struct {
155 | grpc.ClientStream
156 | }
157 |
158 | func (x *p4RuntimeStreamChannelClient) Send(m *StreamMessageRequest) error {
159 | return x.ClientStream.SendMsg(m)
160 | }
161 |
162 | func (x *p4RuntimeStreamChannelClient) Recv() (*StreamMessageResponse, error) {
163 | m := new(StreamMessageResponse)
164 | if err := x.ClientStream.RecvMsg(m); err != nil {
165 | return nil, err
166 | }
167 | return m, nil
168 | }
169 |
170 | func (c *p4RuntimeClient) Capabilities(ctx context.Context, in *CapabilitiesRequest, opts ...grpc.CallOption) (*CapabilitiesResponse, error) {
171 | out := new(CapabilitiesResponse)
172 | err := c.cc.Invoke(ctx, P4Runtime_Capabilities_FullMethodName, in, out, opts...)
173 | if err != nil {
174 | return nil, err
175 | }
176 | return out, nil
177 | }
178 |
179 | // P4RuntimeServer is the server API for P4Runtime service.
180 | // All implementations must embed UnimplementedP4RuntimeServer
181 | // for forward compatibility
182 | type P4RuntimeServer interface {
183 | // Update one or more P4 entities on the target.
184 | Write(context.Context, *WriteRequest) (*WriteResponse, error)
185 | // Read one or more P4 entities from the target.
186 | Read(*ReadRequest, P4Runtime_ReadServer) error
187 | // Sets the P4 forwarding-pipeline config.
188 | SetForwardingPipelineConfig(context.Context, *SetForwardingPipelineConfigRequest) (*SetForwardingPipelineConfigResponse, error)
189 | // Gets the current P4 forwarding-pipeline config.
190 | GetForwardingPipelineConfig(context.Context, *GetForwardingPipelineConfigRequest) (*GetForwardingPipelineConfigResponse, error)
191 | // Represents the bidirectional stream between the controller and the
192 | // switch (initiated by the controller), and is managed for the following
193 | // purposes:
194 | // - connection initiation through client arbitration
195 | // - indicating switch session liveness: the session is live when switch
196 | // sends a positive client arbitration update to the controller, and is
197 | // considered dead when either the stream breaks or the switch sends a
198 | // negative update for client arbitration
199 | // - the controller sending/receiving packets to/from the switch
200 | // - streaming of notifications from the switch
201 | StreamChannel(P4Runtime_StreamChannelServer) error
202 | Capabilities(context.Context, *CapabilitiesRequest) (*CapabilitiesResponse, error)
203 | mustEmbedUnimplementedP4RuntimeServer()
204 | }
205 |
206 | // UnimplementedP4RuntimeServer must be embedded to have forward compatible implementations.
207 | type UnimplementedP4RuntimeServer struct {
208 | }
209 |
210 | func (UnimplementedP4RuntimeServer) Write(context.Context, *WriteRequest) (*WriteResponse, error) {
211 | return nil, status.Errorf(codes.Unimplemented, "method Write not implemented")
212 | }
213 | func (UnimplementedP4RuntimeServer) Read(*ReadRequest, P4Runtime_ReadServer) error {
214 | return status.Errorf(codes.Unimplemented, "method Read not implemented")
215 | }
216 | func (UnimplementedP4RuntimeServer) SetForwardingPipelineConfig(context.Context, *SetForwardingPipelineConfigRequest) (*SetForwardingPipelineConfigResponse, error) {
217 | return nil, status.Errorf(codes.Unimplemented, "method SetForwardingPipelineConfig not implemented")
218 | }
219 | func (UnimplementedP4RuntimeServer) GetForwardingPipelineConfig(context.Context, *GetForwardingPipelineConfigRequest) (*GetForwardingPipelineConfigResponse, error) {
220 | return nil, status.Errorf(codes.Unimplemented, "method GetForwardingPipelineConfig not implemented")
221 | }
222 | func (UnimplementedP4RuntimeServer) StreamChannel(P4Runtime_StreamChannelServer) error {
223 | return status.Errorf(codes.Unimplemented, "method StreamChannel not implemented")
224 | }
225 | func (UnimplementedP4RuntimeServer) Capabilities(context.Context, *CapabilitiesRequest) (*CapabilitiesResponse, error) {
226 | return nil, status.Errorf(codes.Unimplemented, "method Capabilities not implemented")
227 | }
228 | func (UnimplementedP4RuntimeServer) mustEmbedUnimplementedP4RuntimeServer() {}
229 |
230 | // UnsafeP4RuntimeServer may be embedded to opt out of forward compatibility for this service.
231 | // Use of this interface is not recommended, as added methods to P4RuntimeServer will
232 | // result in compilation errors.
233 | type UnsafeP4RuntimeServer interface {
234 | mustEmbedUnimplementedP4RuntimeServer()
235 | }
236 |
237 | func RegisterP4RuntimeServer(s grpc.ServiceRegistrar, srv P4RuntimeServer) {
238 | s.RegisterService(&P4Runtime_ServiceDesc, srv)
239 | }
240 |
241 | func _P4Runtime_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
242 | in := new(WriteRequest)
243 | if err := dec(in); err != nil {
244 | return nil, err
245 | }
246 | if interceptor == nil {
247 | return srv.(P4RuntimeServer).Write(ctx, in)
248 | }
249 | info := &grpc.UnaryServerInfo{
250 | Server: srv,
251 | FullMethod: P4Runtime_Write_FullMethodName,
252 | }
253 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
254 | return srv.(P4RuntimeServer).Write(ctx, req.(*WriteRequest))
255 | }
256 | return interceptor(ctx, in, info, handler)
257 | }
258 |
259 | func _P4Runtime_Read_Handler(srv interface{}, stream grpc.ServerStream) error {
260 | m := new(ReadRequest)
261 | if err := stream.RecvMsg(m); err != nil {
262 | return err
263 | }
264 | return srv.(P4RuntimeServer).Read(m, &p4RuntimeReadServer{stream})
265 | }
266 |
267 | type P4Runtime_ReadServer interface {
268 | Send(*ReadResponse) error
269 | grpc.ServerStream
270 | }
271 |
272 | type p4RuntimeReadServer struct {
273 | grpc.ServerStream
274 | }
275 |
276 | func (x *p4RuntimeReadServer) Send(m *ReadResponse) error {
277 | return x.ServerStream.SendMsg(m)
278 | }
279 |
280 | func _P4Runtime_SetForwardingPipelineConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
281 | in := new(SetForwardingPipelineConfigRequest)
282 | if err := dec(in); err != nil {
283 | return nil, err
284 | }
285 | if interceptor == nil {
286 | return srv.(P4RuntimeServer).SetForwardingPipelineConfig(ctx, in)
287 | }
288 | info := &grpc.UnaryServerInfo{
289 | Server: srv,
290 | FullMethod: P4Runtime_SetForwardingPipelineConfig_FullMethodName,
291 | }
292 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
293 | return srv.(P4RuntimeServer).SetForwardingPipelineConfig(ctx, req.(*SetForwardingPipelineConfigRequest))
294 | }
295 | return interceptor(ctx, in, info, handler)
296 | }
297 |
298 | func _P4Runtime_GetForwardingPipelineConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
299 | in := new(GetForwardingPipelineConfigRequest)
300 | if err := dec(in); err != nil {
301 | return nil, err
302 | }
303 | if interceptor == nil {
304 | return srv.(P4RuntimeServer).GetForwardingPipelineConfig(ctx, in)
305 | }
306 | info := &grpc.UnaryServerInfo{
307 | Server: srv,
308 | FullMethod: P4Runtime_GetForwardingPipelineConfig_FullMethodName,
309 | }
310 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
311 | return srv.(P4RuntimeServer).GetForwardingPipelineConfig(ctx, req.(*GetForwardingPipelineConfigRequest))
312 | }
313 | return interceptor(ctx, in, info, handler)
314 | }
315 |
316 | func _P4Runtime_StreamChannel_Handler(srv interface{}, stream grpc.ServerStream) error {
317 | return srv.(P4RuntimeServer).StreamChannel(&p4RuntimeStreamChannelServer{stream})
318 | }
319 |
320 | type P4Runtime_StreamChannelServer interface {
321 | Send(*StreamMessageResponse) error
322 | Recv() (*StreamMessageRequest, error)
323 | grpc.ServerStream
324 | }
325 |
326 | type p4RuntimeStreamChannelServer struct {
327 | grpc.ServerStream
328 | }
329 |
330 | func (x *p4RuntimeStreamChannelServer) Send(m *StreamMessageResponse) error {
331 | return x.ServerStream.SendMsg(m)
332 | }
333 |
334 | func (x *p4RuntimeStreamChannelServer) Recv() (*StreamMessageRequest, error) {
335 | m := new(StreamMessageRequest)
336 | if err := x.ServerStream.RecvMsg(m); err != nil {
337 | return nil, err
338 | }
339 | return m, nil
340 | }
341 |
342 | func _P4Runtime_Capabilities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
343 | in := new(CapabilitiesRequest)
344 | if err := dec(in); err != nil {
345 | return nil, err
346 | }
347 | if interceptor == nil {
348 | return srv.(P4RuntimeServer).Capabilities(ctx, in)
349 | }
350 | info := &grpc.UnaryServerInfo{
351 | Server: srv,
352 | FullMethod: P4Runtime_Capabilities_FullMethodName,
353 | }
354 | handler := func(ctx context.Context, req interface{}) (interface{}, error) {
355 | return srv.(P4RuntimeServer).Capabilities(ctx, req.(*CapabilitiesRequest))
356 | }
357 | return interceptor(ctx, in, info, handler)
358 | }
359 |
360 | // P4Runtime_ServiceDesc is the grpc.ServiceDesc for P4Runtime service.
361 | // It's only intended for direct use with grpc.RegisterService,
362 | // and not to be introspected or modified (even as a copy)
363 | var P4Runtime_ServiceDesc = grpc.ServiceDesc{
364 | ServiceName: "p4.v1.P4Runtime",
365 | HandlerType: (*P4RuntimeServer)(nil),
366 | Methods: []grpc.MethodDesc{
367 | {
368 | MethodName: "Write",
369 | Handler: _P4Runtime_Write_Handler,
370 | },
371 | {
372 | MethodName: "SetForwardingPipelineConfig",
373 | Handler: _P4Runtime_SetForwardingPipelineConfig_Handler,
374 | },
375 | {
376 | MethodName: "GetForwardingPipelineConfig",
377 | Handler: _P4Runtime_GetForwardingPipelineConfig_Handler,
378 | },
379 | {
380 | MethodName: "Capabilities",
381 | Handler: _P4Runtime_Capabilities_Handler,
382 | },
383 | },
384 | Streams: []grpc.StreamDesc{
385 | {
386 | StreamName: "Read",
387 | Handler: _P4Runtime_Read_Handler,
388 | ServerStreams: true,
389 | },
390 | {
391 | StreamName: "StreamChannel",
392 | Handler: _P4Runtime_StreamChannel_Handler,
393 | ServerStreams: true,
394 | ClientStreams: true,
395 | },
396 | },
397 | Metadata: "p4/v1/p4runtime.proto",
398 | }
399 |
--------------------------------------------------------------------------------
/docs/v1/guidance-for-generating-p4info.md:
--------------------------------------------------------------------------------
1 | # Guidance for generating P4Info messages
2 |
3 |
4 | ## Recommendations for URIs in `p4runtime_translation` annotations
5 |
6 | For the use of P4Runtime major version 1 with the PSA architecture,
7 | all URIs for `p4runtime_translation` annotations defined in the psa.p4
8 | include file will be of this form:
9 |
10 | p4.org/psa/v1/
11 |
12 | No other organization should use URIs beginning with `p4.org`. They
13 | are reserved for use by the `p4.org` organization.
14 |
15 | It is recommended that another organization that wishes to use the
16 | `p4runtime_translation` annotation for types defined in an
17 | architecture they create, other than PSA, will be of this form:
18 |
19 | //
20 |
21 | For example, `mycompany.com/our_arch/PortId`. The organization should
22 | document its rules for such URIs.
23 |
24 | For P4_16 `type` definitions for which P4Runtime translation is
25 | desired, where the `type` is not defined within an architecture, but
26 | in the user's P4 code, we recommend using a URI of this form:
27 |
28 | ///
29 |
30 | Where here the `domain_name` is that of the organization or individual
31 | who developed or owns the P4 program, and the `` element is
32 | optional. Again, the organization or individual should form and
33 | document a policy for how they form such URIs. For example, they may
34 | create libraries of P4 code containing widely used types and
35 | translations for them, and wish to include an element in the URI
36 | representing the name of the library, its major version, etc.
37 |
38 |
39 | ## Handling P4_16 `type` and the `p4runtime_translation` annotation
40 |
41 | The P4Runtime v1.4 specification restricts the types that it supports
42 | for the following kinds of things:
43 |
44 | + table search key fields, defined in the P4Info message in a
45 | `MatchField` message
46 | + fields of a `ValueSet`, also defined in the P4Info message in a
47 | `MatchField` message
48 | + parameters specified by the control plane for a table action,
49 | defined in the P4Info message in a `Param` message
50 | + metadata fields in a header sent from data plane to controller, or
51 | from controller to the data plane, defined in the P4Info message in
52 | a `Metadata` message (the `type_name` field was added to `Metadata`
53 | messages in P4Runtime version 1.1.0).
54 |
55 | Later in this section, we will use the term "constrained value" for
56 | brevity, instead of repeating all of the kinds of objects listed
57 | above. For such values, the P4Runtime specification v1.4 supports all
58 | of the following types, but currently no others:
59 |
60 | + `bit`
61 | + an `enum` with an underlying type of `bit`, also called a
62 | serializable `enum` (TBD whether all of the pieces needed to make
63 | this work are actually supported for P4Runtime 1.4)
64 | + a `typedef` or `type` name that, when "followed back" to the lowest
65 | base type, is one of the above. (As of the P4_16 language
66 | specification version 1.2.1, it is not required to support a `type`
67 | definition with a serializable `enum` as its base type. See
68 | [p4runtime issue
69 | #192](https://github.com/p4lang/p4runtime/issues/192).)
70 |
71 | P4Info `MatchField`, `Param`, and `Metadata` messages may optionally
72 | contain the following two fields:
73 |
74 | + `int32 bitwidth`
75 | + `P4NamedType type_name`
76 |
77 | Below we will describe what values these fields should have.
78 |
79 | Consider a single constrained value `x`. Create a list of types
80 | `type_list(x)` using the pseudocode shown below.
81 |
82 | ```
83 | type_list(x) {
84 | tlist = []; // tlist initialized to empty list
85 | T = declared type of object x in the P4 program;
86 | while (true) {
87 | if (T is declared as "type B T") {
88 | tlist = tlist + [T]; // append T to end of tlist
89 | T = B;
90 | } else if (T is declared as "typedef B T") {
91 | T = B;
92 | } else {
93 | tlist = tlist + [T]; // append T to end of tlist
94 | return tlist;
95 | }
96 | }
97 | }
98 | ```
99 |
100 | Note that `type_list(x)` always starts with zero or more `type` names,
101 | and always ends with one type that is neither a `type` nor `typedef`
102 | name, e.g. `bit`, a header type, struct type, etc. It never
103 | contains the name of a type declared using `typedef`. P4Runtime v1.4
104 | only supports `p4runtime_translation` annotations on `type`
105 | definitions. If any such annotations occur on a `typedef` definition,
106 | they should be ignored.
107 |
108 | The `p4c` compiler signals an error if you attempt to create a cycle
109 | of type names. In order to create such a cycle, the first `type` or
110 | `typedef` that appears in the program would have to refer to a later
111 | type name, and this is not allowed.
112 |
113 | If the last type is not `bit` or `enum bit`, that is an error
114 | for P4Runtime v1.4. The "base" type must always be one of those for
115 | every constrained value.
116 |
117 |
118 | ### `type_name` field
119 |
120 | Let `first_type` be the first element of the list `type_list(x)`.
121 |
122 | If `first_type` is a `type` name (i.e. not `bit` or `enum bit`),
123 | then the value of the P4Info `type_name` field should be `{name =
124 | "first_type_name"}`, where `first_type_name` is the name of
125 | `first_type`.
126 |
127 | Otherwise, the `type_name` field should be unset in the P4info
128 | message.
129 |
130 |
131 | ### `bitwidth` field
132 |
133 | If `first_type` is a `type` name, _and_ if the `type` definition for
134 | this type has a `p4runtime_translation(uri_string, )` annotation in
135 | the source code, then the P4Info `bitwidth` field should follow these
136 | rules:
137 |
138 | * if `` is `n`, where `n` is a positive integer, then the `bitwidth`
139 | field should be assigned the value `n`
140 | * if `` is `bit`, where `W` is a postive integer, then the
141 | `bitwidth` field should be assigned value `W`
142 | * if `` is `string`, then the `bitwidth` field should be unset
143 | (which in Protobuf version 3 is the same as setting it explicitly to
144 | 0)
145 | * all other cases for `` are illegal
146 |
147 | Otherwise, `bitwidth` should be equal to `W` where `bit` or `enum
148 | bit` is the last element of `type_list(x)`.
149 |
150 | Note that all type names that are present as the value of a
151 | `type_name` field anywhere in a P4Info message must contain an entry
152 | describing it in the `type_info` field of the P4Info message. Thus
153 | this `bitwidth` value could be considered redundant information, since
154 | it can be derived from the description of the type contained within
155 | the `type_info` field. However, it is considered worth keeping this
156 | small amount of redundancy for simplicity of interpreting the messages
157 | that contain these `bitwidth` fields, without having to find the value
158 | elsewhere in the P4Info message.
159 |
160 |
161 | ## Example 1: field with simple `bit` type
162 |
163 | ```
164 | bit<10> f1;
165 |
166 | type_list(f1) -> [bit<10>]
167 |
168 | type_name: left unset in P4Info message
169 | bitwidth: 10
170 | ```
171 |
172 | Based on the P4 code snippet above, there is no need to describe any
173 | type inside of the `type_info` field of the P4Info message, because
174 | there are no named types in this code.
175 |
176 |
177 | ## Example 2: field with a type defined via `type`, simplest possible case
178 |
179 | ```
180 | type bit<7> MyCustomType_t;
181 | MyCustomType_t f2;
182 |
183 | type_list(f2) -> [MyCustomType_t, bit<7>]
184 |
185 | type_name: "MyCustomType_t"
186 |
187 | Reason: T2_t is the first type name in type_list(f2)
188 |
189 | bitwidth: 7
190 |
191 | Reason: Type MyCustomType_t is the first type name in
192 | type_list(f2), but it has no p4runtime_translation on it. Use the
193 | width 7 from bit<7>, the last element of type_list(f2).
194 | ```
195 |
196 | Based on the P4 code snippet above (copied below for easy reference),
197 | the value below starting with `type_info {` should be in the P4Info
198 | message describing the program, because of the `type` definitions.
199 |
200 | ```
201 | type bit<7> MyCustomType_t;
202 | MyCustomType_t f2;
203 | ```
204 |
205 | ```
206 | type_info {
207 | new_types {
208 | key: "MyCustomType_t"
209 | value {
210 | original_type {
211 | bitstring {
212 | bit {
213 | bitwidth: 7
214 | }
215 | }
216 | }
217 | }
218 | }
219 | }
220 | ```
221 |
222 | Type `MyCustomType_t` is described via an `original_type` message,
223 | because the definition of `MyCustomType_t` in the program does not
224 | have a `p4runtime_translation` annotation.
225 |
226 |
227 | ## Example 3: field with a type defined via `type`, with no annotation
228 |
229 | It is not clear whether there are strong use cases for declaring a
230 | `type` based upon another `type` in a P4_16 program. However,
231 | currently the P4_16 language and `p4c` compiler allow it, so it seems
232 | to be a good idea to have predictable rules to follow for what the
233 | P4Info message contents should be, and how the resulting system should
234 | behave.
235 |
236 | The basic design described here tries to keep things fairly
237 | straightforward to explain and understand, if a P4_16 program does so.
238 |
239 | If a constrained value `f` has a `type` name as the first element of
240 | the list `type_list(f)`, then that type name is used for `f`,
241 | regardless of whether it has a `p4runtime_translation` annotation.
242 |
243 | In the absence of such an annotation on that `type`, no P4runtime
244 | translation is done for that type, _even if a later type in
245 | `type_list(x)` does have such an annotation_.
246 |
247 | Below is an example of a P4 code snippet that demonstrates one
248 | example, but I do _not_ claim that it is useful for any actual
249 | production P4 program to be written this way (until and unless some
250 | demonstrates a reason why it would be useful).
251 |
252 | ```
253 | typedef bit<10> T1uint_t;
254 | @p4runtime_translation("mycompany.com/myco_p4lib/v1/T1_t", 32)
255 | type T1uint_t T1_t;
256 | type T1_t T2_t;
257 | T2_t f3;
258 | ```
259 |
260 | Note that starting with P4Runtime v1.2.0, the following syntax for the
261 | `p4runtime_translation` is equivalent (and preferred):
262 | ```
263 | @p4runtime_translation("mycompany.com/myco_p4lib/v1/T1_t", bit<32>)
264 | type T1uint_t T1_t;
265 | ```
266 |
267 | ```
268 | Execution trace for call to type_list(f3):
269 | tlist = []
270 | T = declared type of object f3 in the P4 program = T2_t
271 | Evaluate condition (T2_t is declared as "type B T") -> true,
272 | because T2_t is declared as "type T1_t T2_t"
273 | tlist = tlist + [T] -> tlist=[T2_t]
274 | T = B = T1_t
275 | Evaluate condition (T1_t is declared as "type B T") -> true,
276 | because T1_t is declared as "type T1uint_t T1_t"
277 | tlist = tlist + [T] -> tlist=[T2_t, T1_t]
278 | T = B = T1uint_t
279 | Evaluate condition (T1uint_t is declared as "type B T") -> false
280 | Evaluate condition (T1uint_t is declared as "typedef B T") -> true,
281 | because T1uint_t is declared as "typedef bit<10> T1uint_t"
282 | T = B = bit<10>
283 | Evaluate condition (bit<10> is declared as "type B T") -> false
284 | Evaluate condition (bit<10> is declared as "typedef B T") -> false
285 | tlist = tlist + [T] -> tlist=[T2_t, T1_t, bit<10>]
286 | return tlist
287 |
288 | type_list(f3) -> [T2_t, T1_t, bit<10>]
289 |
290 | type_name: "T2_t"
291 |
292 | Reason: T2_t is the first type name in type_list(f3)
293 |
294 | bitwidth: 10
295 |
296 | Reason: Type T2_t is the first type name in type_list(f3), but it
297 | has no p4runtime_translation on it, so even though T1_t does, that
298 | is ignored. Use the width 10 from bit<10>, the last element of
299 | type_list(f3).
300 | ```
301 |
302 | Based on the P4 code snippet above (copied below for easy reference),
303 | the value below starting with `type_info {` should be in the P4Info
304 | message describing the program, because of the `type` definitions.
305 | There is never anything put into a P4Info message because of `typedef`
306 | definitions in a P4 program.
307 |
308 | Note that the bit width of 10 appears in the P4Info message for any
309 | `type`s "built on top of" a `bit<10>`, _unless that type has its own
310 | `p4runtime_translation` annotation_.
311 |
312 | ```
313 | typedef bit<10> T1uint_t;
314 | @p4runtime_translation("mycompany.com/myco_p4lib/v1/T1_t", 32)
315 | type T1uint_t T1_t;
316 | type T1_t T2_t;
317 | T2_t f3;
318 | ```
319 |
320 | ```
321 | type_info {
322 | new_types {
323 | key: "T2_t"
324 | value {
325 | original_type {
326 | bitstring {
327 | bit {
328 | bitwidth: 10
329 | }
330 | }
331 | }
332 | }
333 | }
334 | }
335 | ```
336 |
337 | Type `T2_t` is described via an `original_type` message, because the
338 | definition of `T2_t` in the program, `type T1_t T2_t`, does not have a
339 | `p4runtime_translation` annotation.
340 |
341 | Based on the P4 code snippet above, there is no reason to include a
342 | description for the type `T1_t` in the P4Info message. If there were
343 | some other variable other than `f3` in the program declared with type
344 | `T1_t`, and that variable caused the type name `T1_t` to be included
345 | in the P4Info message, then the following description for type `T1_t`
346 | must be included in the `type_info` field.
347 |
348 | ```
349 | type_info {
350 | new_types {
351 | key: "T1_t"
352 | value {
353 | translated_type {
354 | uri: "mycompany.com/myco_p4lib/v1/T1_t"
355 | sdn_bitwidth: 32
356 | }
357 | }
358 | }
359 | }
360 | ```
361 |
362 | Type `T1_t` is described via a `translated_type` message, because the
363 | definition of `T1_t` in the program, `type T1uint T1_t`, has a
364 | `p4runtime_translation` annotation.
365 |
366 |
367 | ## Example 4: field with a type defined via `type`, with `p4runtime_translation` annotation
368 |
369 | This example is very similar to Example 3, except that all three `type`
370 | definitions have a `p4runtime_translation` annotation.
371 |
372 | ```
373 | @p4runtime_translation("mycompany.com/myco_p4lib/v1/T1_t", 32)
374 | type bit<10> T1_t;
375 | @p4runtime_translation("mycompany.com/myco_p4lib/v1/T2_t", 18)
376 | type T1_t T2_t;
377 | T2_t f4;
378 |
379 | type_list(f4) -> [T2_t, T1_t, bit<10>]
380 |
381 | type_name: "T2_t"
382 |
383 | Reason: T2_t is the first type name in type_list(f4)
384 |
385 | bitwidth: 18
386 |
387 | Reason: Type T2_t is the first type name in type_list(f4), and it
388 | has a p4runtime_translation annotation on it. Use the width 18
389 | that is the second parameter of that annotation.
390 | ```
391 |
392 | The contents of the `type_info` field of the P4Info message should be
393 | as follows. For the code snippet above, there is no reason to include
394 | a description of the type `T1_t`. The description of type `T1_t` is
395 | shown below for the sake of an example, but it only needs to be
396 | included in the P4Info message if there is a reference to type `T1_t`
397 | somewhere in the P4Info message.
398 |
399 | ```
400 | type_info {
401 | new_types {
402 | key: "T1_t"
403 | value {
404 | translated_type {
405 | uri: "mycompany.com/myco_p4lib/v1/T1_t"
406 | sdn_bitwidth: 32
407 | }
408 | }
409 | }
410 | new_types {
411 | key: "T2_t"
412 | value {
413 | translated_type {
414 | uri: "mycompany.com/myco_p4lib/v1/T2_t"
415 | sdn_bitwidth: 18
416 | }
417 | }
418 | }
419 | }
420 | ```
421 |
422 | Note that both types `T1_t` and `T2_t` are described via
423 | `translated_type` messages, because they both have a
424 | `p4runtime_translation` annotation.
425 |
426 |
427 | ## Example 5: field with serializable `enum` type
428 |
429 | See [p4runtime issue
430 | #192](https://github.com/p4lang/p4runtime/issues/192).
431 |
432 | ```
433 | enum bit<10> enum1_t {
434 | A = 1,
435 | B = 2
436 | }
437 |
438 | enum1_t f5;
439 |
440 | type_list(f1) -> [enum1_t]
441 |
442 | type_name: see discussion below
443 | bitwidth: 10
444 | ```
445 |
446 | It seems pretty clear that `bitwidth` should be 10 bits for field
447 | `f5`.
448 |
449 | However, what about `type_name`?
450 |
451 | Should `type_name` be unset? If so, there is the disadvantage that
452 | the control plane software has no indication that field `f5` is of
453 | type `enum1_t`. As far as it could tell from the P4Info message, it
454 | is declared as type `bit<10>`. This is not necessarily a fatal flaw,
455 | but it is a loss of potentially useful information in the P4Info
456 | message.
457 |
458 | Should `type_name` be `"enum1_t"`, and then `"enum1_t"` should be
459 | described within the `type_info` field of the message?
460 |
461 | As of early June 2020, `p4c` does not support users defining their
462 | own `type` definitions with a serializable `enum` like `enum1_t` as
463 | the base type. The disadvantage with this situation is that there is
464 | no way to define a serializable `enum` type for a constrained value,
465 | and also have `p4runtime_translation` annotated on a `type` with the
466 | serializable `enum` as its underlying type.
467 |
468 | If `p4c` ever does support defining a `type` with a serializable
469 | `enum` as its underlying type, with an optional
470 | `p4runtime_translation` annotation, then we should think about how
471 | that should be represented in a P4Info message, and add an example of
472 | it here.
473 |
--------------------------------------------------------------------------------
/proto/p4/config/v1/p4info.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2013-present Barefoot Networks, Inc.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | import "google/protobuf/any.proto";
18 | import "p4/config/v1/p4types.proto";
19 |
20 | // This package and its contents are a work-in-progress.
21 |
22 | package p4.config.v1;
23 |
24 | option go_package = "github.com/p4lang/p4runtime/go/p4/config/v1";
25 |
26 | message P4Info {
27 | PkgInfo pkg_info = 1;
28 | repeated Table tables = 2;
29 | repeated Action actions = 3;
30 | repeated ActionProfile action_profiles = 4;
31 | repeated Counter counters = 5;
32 | repeated DirectCounter direct_counters = 6;
33 | repeated Meter meters = 7;
34 | repeated DirectMeter direct_meters = 8;
35 | repeated ControllerPacketMetadata controller_packet_metadata = 9;
36 | repeated ValueSet value_sets = 10;
37 | repeated Register registers = 11;
38 | repeated Digest digests = 12;
39 | repeated Extern externs = 100;
40 | P4TypeInfo type_info = 200;
41 | }
42 |
43 | message Documentation {
44 | // A brief description of something, e.g. one sentence
45 | string brief = 1;
46 | // A more verbose description of something. Multiline is accepted. Markup
47 | // format (if any) is TBD.
48 | string description = 2;
49 | }
50 |
51 | // Used to describe the required properties of the underlying platform.
52 | // Added in v1.4.0
53 | message PlatformProperties {
54 | // The minimum number of multicast entries (i.e. multicast groups) that the
55 | // platform is required to support. If 0, there are no requirements.
56 | int32 multicast_group_table_size = 1;
57 | // The minimum number of replicas that the platform is required to support
58 | // across all groups. If 0, there are no requirements.
59 | int32 multicast_group_table_total_replicas = 2;
60 | // The number of replicas that the platform is required to support per
61 | // group/entry. If 0, `multicast_group_table_total_replicas` should be used.
62 | // Must be no larger than `multicast_group_table_total_replicas`.
63 | int32 multicast_group_table_max_replicas_per_entry = 3;
64 | }
65 |
66 | // Top-level package documentation describing the forwarding pipeline config
67 | // Can be used to manage multiple P4 packages.
68 | message PkgInfo {
69 | // a definitive name for this configuration, e.g. switch.p4_v1.0
70 | string name = 1;
71 | // configuration version, free-format string
72 | string version = 2;
73 | // brief and detailed descriptions
74 | Documentation doc = 3;
75 | // Miscellaneous metadata, free-form; a way to extend PkgInfo
76 | repeated string annotations = 4;
77 | // Optional. If present, the location of `annotations[i]` is given by
78 | // `annotation_locations[i]`.
79 | repeated SourceLocation annotation_locations = 10;
80 | // the target architecture, e.g. "psa"
81 | string arch = 5;
82 | // organization which produced the configuration, e.g. "p4.org"
83 | string organization = 6;
84 | // contact info for support,e.g. "tech-support@acme.org"
85 | string contact = 7;
86 | // url for more information, e.g.
87 | // "http://support.p4.org/ref/p4/switch.p4_v1.0"
88 | string url = 8;
89 | // Miscellaneous metadata, structured; a way to extend PkgInfo
90 | repeated StructuredAnnotation structured_annotations = 9;
91 | // If set, specifies the properties that the underlying platform should have.
92 | // If the platform does not conform to these properties, the server should
93 | // reject the P4Info when used with a SetForwardingPipelineConfigRequest.
94 | // Added in 1.4.0
95 | PlatformProperties platform_properties = 11;
96 | }
97 |
98 | // wrapping the enum in a message to avoid name collisions in C++, where "enum
99 | // values are siblings of their type, not children of it"
100 | message P4Ids {
101 | // ids are allocated in such a way that it is possible based on an id to
102 | // deduce the resource type (e.g. table, action, counter, ...). The
103 | // most-significant byte of the 32-bit id encodes the resource type. The
104 | // purpose of this enum is to define which value is used as the
105 | // most-significant byte for each resource type. The P4 compiler must use
106 | // these values when allocating ids for P4 objects. Other users of P4Info can
107 | // refer to this enum to identify a resource type based on its id.
108 | enum Prefix {
109 | UNSPECIFIED = 0;
110 |
111 | // P4 language built-ins
112 | ACTION = 0x01;
113 | TABLE = 0x02;
114 | VALUE_SET = 0x03;
115 | CONTROLLER_HEADER = 0x04;
116 |
117 | // PSA externs
118 | PSA_EXTERNS_START = 0x10;
119 | ACTION_PROFILE = 0x11;
120 | COUNTER = 0x12;
121 | DIRECT_COUNTER = 0x13;
122 | METER = 0x14;
123 | DIRECT_METER = 0x15;
124 | REGISTER = 0x16;
125 | DIGEST = 0x17;
126 |
127 | // externs for other architectures (vendor extensions)
128 | OTHER_EXTERNS_START = 0x80;
129 |
130 | // max value for an unsigned 8-bit byte
131 | MAX = 0xff;
132 | // requires protoc >= 3.5.0
133 | // reserved 0x100 to max;
134 | }
135 | }
136 |
137 | message Preamble {
138 | // ids share the same number-space; e.g. table ids cannot overlap with counter
139 | // ids. Even though this is irrelevant to this proto definition, the ids are
140 | // allocated in such a way that it is possible based on an id to deduce the
141 | // resource type (e.g. table, action, counter, ...). This means that code
142 | // using these ids can detect if the wrong resource type is used
143 | // somewhere. This also means that ids of different types can be mixed
144 | // (e.g. direct resource list for a table) without ambiguity. Note that id 0
145 | // is reserved and means "invalid id".
146 | uint32 id = 1;
147 | // fully qualified name of the P4 object, e.g. c1.c2.ipv4_lpm
148 | string name = 2;
149 | // an alias (alternative name) for the P4 object, probably shorter than its
150 | // fully qualified name. The only constraint is for it to be unique with
151 | // respect to other P4 objects of the same type. By default, the compiler uses
152 | // the shortest suffix of the name that uniquely identifies the object. For
153 | // example if the P4 program contains two tables with names s.c1.t and s.c2.t,
154 | // the default aliases will respectively be c1.t and c2.t. In the future, the
155 | // P4 programmer may also be able to override the default alias for any P4
156 | // object (TBD).
157 | string alias = 3;
158 | repeated string annotations = 4;
159 | // Optional. If present, the location of `annotations[i]` is given by
160 | // `annotation_locations[i]`.
161 | repeated SourceLocation annotation_locations = 7;
162 | // Documentation of the entity
163 | Documentation doc = 5;
164 | repeated StructuredAnnotation structured_annotations = 6;
165 | }
166 |
167 | // used to group all extern instances of the same type in one message
168 | message Extern {
169 | // the extern_type_id is unique for a given architecture and must be in the
170 | // range [0x81, 0xfe].
171 | uint32 extern_type_id = 1;
172 | string extern_type_name = 2;
173 | repeated ExternInstance instances = 3;
174 | }
175 |
176 | message ExternInstance {
177 | Preamble preamble = 1;
178 | // specific to the extern type, declared in a separate vendor-specific proto
179 | // file
180 | google.protobuf.Any info = 2;
181 | }
182 |
183 | message MatchField {
184 | uint32 id = 1;
185 | string name = 2;
186 | repeated string annotations = 3;
187 | // Optional. If present, the location of `annotations[i]` is given by
188 | // `annotation_locations[i]`.
189 | repeated SourceLocation annotation_locations = 10;
190 | int32 bitwidth = 4;
191 | enum MatchType {
192 | UNSPECIFIED = 0;
193 | EXACT = 2;
194 | LPM = 3;
195 | TERNARY = 4;
196 | RANGE = 5;
197 | OPTIONAL = 6;
198 | }
199 | oneof match {
200 | MatchType match_type = 5;
201 | // used for architecture-specific match types which are not part of the core
202 | // P4 language or of the PSA architecture.
203 | string other_match_type = 7;
204 | }
205 | // Documentation of the match field
206 | Documentation doc = 6;
207 | // unset if not user-defined type
208 | P4NamedType type_name = 8;
209 | repeated StructuredAnnotation structured_annotations = 9;
210 | }
211 |
212 | // A TableActionCall references a particular action id and executes the
213 | // action with the supplied list of arguments.
214 | // Arguments are matched to the id of the respective action parameter.
215 | // TableActionCalls may be used as the default action call of a table implementation.
216 | // Added in 1.4.0.
217 | message TableActionCall {
218 | uint32 action_id = 1;
219 | message Argument {
220 | uint32 param_id = 2;
221 | bytes value = 3;
222 | }
223 | repeated Argument arguments = 4;
224 | }
225 |
226 | message Table {
227 | Preamble preamble = 1;
228 | repeated MatchField match_fields = 2;
229 | // even when the table is indirect (see implementation_id) below, this field
230 | // includes all possible actions for the table; by using ActionRef instead of
231 | // a repeated field of action ids, each action reference in a P4 table is able
232 | // to have its own annotations
233 | repeated ActionRef action_refs = 3;
234 | // 0 (default value) means that the table does not have a const default action
235 | uint32 const_default_action_id = 4;
236 | // The initial default action of the table. This can be overridden at runtime.
237 | // Added in 1.4.0.
238 | TableActionCall initial_default_action = 5;
239 | // P4 id of the "implementation" for this table (e.g. action profile id); 0
240 | // (default value) means that the table is a regular (direct) match table. As
241 | // of today, only action profiles are supported but other table
242 | // implementations may be added in the future
243 | uint32 implementation_id = 6;
244 | // ids of the direct resources (if any) attached to this table; for now this
245 | // includes only direct counters and direct meters, but other resources may be
246 | // added in the future
247 | repeated uint32 direct_resource_ids = 7;
248 | int64 size = 8; // max number of entries in table
249 | // this enum can be extended in the future with other behaviors, such as
250 | // "HARD_EVICTION"
251 | enum IdleTimeoutBehavior {
252 | NO_TIMEOUT = 0;
253 | NOTIFY_CONTROL = 1;
254 | }
255 | // is idle timeout supported for this table?
256 | IdleTimeoutBehavior idle_timeout_behavior = 9;
257 | // True if and only if the table's entries are immutable,
258 | // i.e. defined using the 'const entries' table property in the P4
259 | // source code, and thus entries cannot be deleted, modified, or
260 | // inserted at run time.
261 | bool is_const_table = 10;
262 | // True if and only if the table has initial entries defined using
263 | // the 'entries' table property in the P4 source code, either with
264 | // or without the 'const' qualifier on 'entries', and there is at
265 | // least one entry in that list. This field is false if the list of
266 | // entries is empty in the P4 source code.
267 | // Added in 1.4.0.
268 | bool has_initial_entries = 11;
269 | // architecture-specific table properties which are not part of the core P4
270 | // language or of the PSA architecture.
271 | google.protobuf.Any other_properties = 100;
272 | }
273 |
274 | // used to list all possible actions in a Table
275 | message ActionRef {
276 | uint32 id = 1;
277 | enum Scope {
278 | TABLE_AND_DEFAULT = 0;
279 | TABLE_ONLY = 1;
280 | DEFAULT_ONLY = 2;
281 | }
282 | Scope scope = 3;
283 | repeated string annotations = 2;
284 | // Optional. If present, the location of `annotations[i]` is given by
285 | // `annotation_locations[i]`.
286 | repeated SourceLocation annotation_locations = 5;
287 | repeated StructuredAnnotation structured_annotations = 4;
288 | }
289 |
290 | message Action {
291 | Preamble preamble = 1;
292 | message Param {
293 | uint32 id = 1;
294 | string name = 2;
295 | repeated string annotations = 3;
296 | // Optional. If present, the location of `annotations[i]` is given by
297 | // `annotation_locations[i]`.
298 | repeated SourceLocation annotation_locations = 8;
299 | int32 bitwidth = 4;
300 | // Documentation of the Param.
301 | Documentation doc = 5;
302 | // unset if not user-defined type.
303 | P4NamedType type_name = 6;
304 | repeated StructuredAnnotation structured_annotations = 7;
305 | }
306 | repeated Param params = 2;
307 | }
308 |
309 | message ActionProfile {
310 | Preamble preamble = 1;
311 | // the ids of the tables sharing this action profile
312 | repeated uint32 table_ids = 2;
313 | // true iff the action profile used dynamic selection
314 | bool with_selector = 3;
315 | // max number of member entries across all groups if the action profile does
316 | // not have a selector. Otherwise, semantics as specified by
317 | // `selector_size_semantics` below.
318 | int64 size = 4;
319 | // 0 if the action profile does not have a selector. Otherwise, semantics as
320 | // specified by `selector_size_semantics` below.
321 | int32 max_group_size = 5;
322 |
323 | // indicates that `size` and `max_group_size` represent the maximum sum of
324 | // weights that can be present across all selector groups and within a
325 | // single selector group respectively.
326 | // Added in v1.4.0.
327 | message SumOfWeights {}
328 |
329 | // indicates that `size` and `max_group_size` represent the maximum number
330 | // of members that can be present across all selector groups and within a
331 | // single selector group respectively.
332 | // Added in v1.4.0.
333 | message SumOfMembers {
334 | // the maximum weight of each individual member in a group.
335 | int32 max_member_weight = 1;
336 | }
337 |
338 | // specifies the semantics of `size` and `max_group_size` above.
339 | oneof selector_size_semantics {
340 | // group size is the sum of the group's weights.
341 | // Added in v1.4.0.
342 | SumOfWeights sum_of_weights = 6;
343 | // group size is the sum of the group's members.
344 | // Added in v1.4.0.
345 | SumOfMembers sum_of_members = 7;
346 | }
347 |
348 | // Dictates whether the controller can specify weights for groups programmed
349 | // in this ActionProfile. If `weights_disallowed` is true, then all weights
350 | // must be absent. Unset (false) in action profiles without selectors.
351 | // Added in v1.5.0.
352 | bool weights_disallowed = 8;
353 | }
354 |
355 | message CounterSpec {
356 | // Corresponds to 'type' constructor parameter for Counter / DirectCounter in
357 | // PSA
358 | enum Unit {
359 | UNSPECIFIED = 0;
360 | BYTES = 1;
361 | PACKETS = 2;
362 | BOTH = 3;
363 | }
364 | Unit unit = 1;
365 | }
366 |
367 | message Counter {
368 | Preamble preamble = 1;
369 | CounterSpec spec = 2;
370 | // number of entries in the counter array
371 | int64 size = 3;
372 | // unset if index is not user-defined type
373 | P4NamedType index_type_name = 4;
374 | }
375 |
376 | message DirectCounter {
377 | Preamble preamble = 1;
378 | CounterSpec spec = 2;
379 | // the id of the table to which the counter is attached
380 | uint32 direct_table_id = 3;
381 | }
382 |
383 | message MeterSpec {
384 | // Corresponds to 'type' constructor parameter for Meter / DirectMeter in PSA
385 | enum Unit {
386 | UNSPECIFIED = 0;
387 | BYTES = 1;
388 | PACKETS = 2;
389 | }
390 | // Used to restrict the MeterConfigs that can be used to instantiate the
391 | // meter.
392 | // Added in 1.4.0.
393 | enum Type {
394 | // As described in RFC 2698, allows meters to use two rates to split packets
395 | // into three potential colors.
396 | // MeterConfigs on table entries using this meter type MUST have `eburst ==
397 | // 0` (i.e. unset).
398 | TWO_RATE_THREE_COLOR = 0;
399 | // As described in RFC 2697, allows meters to use one rate with an Excess
400 | // Burst Size (EBS) to split packets into three potential colors.
401 | // MeterConfigs on table entries using this meter type MUST have
402 | // `cir == pir && cburst == pburst`.
403 | SINGLE_RATE_THREE_COLOR = 1;
404 | // A simplified version of RFC 2697, restricting meters to using a single
405 | // rate to split packets into only RED or GREEN, by not providing an Excess
406 | // Burst Size (EBS).
407 | // MeterConfigs on table entries using this meter type MUST have
408 | // `cir == pir && cburst == pburst && eburst == 0` (i.e. unset).
409 | SINGLE_RATE_TWO_COLOR = 2;
410 | }
411 | Unit unit = 1;
412 | // Added in 1.4.0.
413 | Type type = 2;
414 | }
415 |
416 | message Meter {
417 | Preamble preamble = 1;
418 | MeterSpec spec = 2;
419 | // number of entries in the meter array
420 | int64 size = 3;
421 | // unset if index is not user-defined type
422 | P4NamedType index_type_name = 4;
423 | }
424 |
425 | message DirectMeter {
426 | Preamble preamble = 1;
427 | MeterSpec spec = 2;
428 | // the id of the table to which the meter is attached
429 | uint32 direct_table_id = 3;
430 | }
431 |
432 | // Any metadata associated with controller Packet-IO (Packet-In or Packet-Out)
433 | // is modeled as P4 headers carrying special annotations
434 | // @controller_header("packet_out") and @controller_header("packet_in")
435 | // respectively. There can be at most one header each with these annotations.
436 | // This message captures the info contained within these special headers,
437 | // and used in p4runtime.proto to supply the metadata.
438 | message ControllerPacketMetadata {
439 | // preamble.name and preamble.id will specify header type ("packet_out" or
440 | // "packet_in" for now).
441 | Preamble preamble = 1;
442 | message Metadata {
443 | uint32 id = 1;
444 | // This is the name of the header field (not fully-qualified), similar
445 | // to e.g. Action.Param.name.
446 | string name = 2;
447 | repeated string annotations = 3;
448 | // Optional. If present, the location of `annotations[i]` is given by
449 | // `annotation_locations[i]`.
450 | repeated SourceLocation annotation_locations = 7;
451 | int32 bitwidth = 4;
452 | // unset if not user-defined type
453 | P4NamedType type_name = 5;
454 | repeated StructuredAnnotation structured_annotations = 6;
455 | }
456 | // Ordered based on header layout.
457 | // This is a constraint on the generator of this P4Info.
458 | repeated Metadata metadata = 2;
459 | }
460 |
461 | message ValueSet {
462 | Preamble preamble = 1;
463 | repeated MatchField match = 2;
464 | // number of entries in the value_set, as per the P4 constructor call.
465 | int32 size = 3;
466 | }
467 |
468 | message Register {
469 | Preamble preamble = 1;
470 | P4DataTypeSpec type_spec = 2;
471 | int32 size = 3;
472 | // unset if index is not user-defined type
473 | P4NamedType index_type_name = 4;
474 | }
475 |
476 | message Digest {
477 | Preamble preamble = 1;
478 | P4DataTypeSpec type_spec = 2;
479 | }
480 |
--------------------------------------------------------------------------------