979fa69ab8
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
179 lines
5.8 KiB
Markdown
179 lines
5.8 KiB
Markdown
## 🏎️ GP4: Generalized P4
|
||
|
||
"P4 is a high-level language for programming protocol-independent packet processors"[^1] and it is awesome. The language is robust and includes many features that make writing
|
||
|
||
- _packet_ parsing pipelines easy to write,
|
||
- _packet_ transformation pipelines easy to write,
|
||
- _packet_ routing pipelines easy to write.
|
||
|
||
The adjacent ecosystem is great, too: There are now myriad tools available that make it possible to write applications to configure the _packet_ parsing, transformation and routing pipelines written in P4.
|
||
|
||
For example, a developer could use P4 to write code that parses raw bytes received from the network into a structured representation of headers/payloads used to transmit those bytes. A developer could use P4 to write a tool that designates the fields of the parsed packet that a network administrator could name when definining configuration for modifying (or not) a parsed packet and defining configuration about how (even _if_) to route the packet. In such a scenario, the system administrator might use a CLI and write
|
||
|
||
```console
|
||
PI CLI> table_add ipv4_lpm 10.0.0.1/24 => set_nhop 10.0.0.1 1
|
||
```
|
||
|
||
which the system running the P4 code written by the developer could read when making a routing decision. Later, if the system administrator wanted to change the way packets were routed, they could use the CLI and write
|
||
|
||
|
||
```console
|
||
PI CLI> table_add ipv4_lpm 10.0.0.1/24 => set_nhop 10.0.0.2 1
|
||
```
|
||
|
||
and the system running the P4 code written by the developer would immediately start to route _packets_ differently.
|
||
|
||
So, why is _packet_ highlighted?
|
||
|
||
|
||
Because we believe that thinking about P4 in exactly the way described above -- after dropping the word _packet_ -- makes it a perfect system for building general-purpose parsing, transformation and routing pipelines. Although there are many ways such tools could be used, we believe that a generalized P4 system would be a perfect candidate for writing online, streaming ETL pipelines (c.f., [Apache Kafka](https://kafka.apache.org/)) or log filter/classification pipelines (c.f., [Sigma](https://sigmahq.io/)).
|
||
|
||
Our goal is to build generalized P4 (GP4): The best of P4 and a little more.
|
||
|
||
Please join us!
|
||
|
||
[^1]: Pat Bosshart, Dan Daly, Glen Gibb, Martin Izzard, Nick McKeown, Jennifer Rexford, Cole Schlesinger, Dan Talayco, Amin Vahdat, George Varghese, and David Walker. 2014. P4: programming protocol-independent packet processors. SIGCOMM Comput. Commun. Rev. 44, 3 (July 2014), 87–95. https://doi.org/10.1145/2656877.2656890
|
||
|
||
### Benefits
|
||
|
||
1. Reuse the extensive existing work from the P4 community.
|
||
2. ... more coming soon.
|
||
|
||
### Status
|
||
|
||
Very, very alpha:
|
||
|
||
1. Limited parts of the language can be parsed.
|
||
2. Limited programs can be evaluated.
|
||
|
||
As an example of what can be parsed and evaluated, here is a fairly complex P4 program cobbled together from our unit tests:
|
||
|
||
```P4
|
||
control simple(bool x, bool y) {
|
||
action a(int z) {
|
||
z = false;
|
||
}
|
||
table t {
|
||
key = {
|
||
x: exact;
|
||
y: exact;
|
||
}
|
||
}
|
||
};
|
||
struct Testing {
|
||
bool yesno;
|
||
int count;
|
||
};
|
||
parser main_parser() {
|
||
state start {
|
||
Testing ts;
|
||
ts.count = 1;
|
||
transition select (ts.count) {
|
||
0: accept;
|
||
_: reject;
|
||
};
|
||
}
|
||
};
|
||
```
|
||
|
||
Please check back often!
|
||
|
||
### Building
|
||
|
||
#### Requirements And Basic Build
|
||
|
||
This project uses [code item macros (`CodeItemMacros`)](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0397-freestanding-declaration-macros.md#future-directions) which
|
||
are an experimental feature in Swift and not [_available in production_](https://github.com/swiftlang/swift/blob/1ba5ae105876b15914688cdf8431fd390651296e/include/swift/Basic/Features.def).
|
||
|
||
Therefore, to compile this project, you must be using a non-production version of the compiler.
|
||
|
||
With that caveat noted, building can be done with `swift build`:
|
||
|
||
```console
|
||
$ swift build
|
||
```
|
||
|
||
### Contributing
|
||
|
||
We would _love_ your help! Contributions are very welcome!
|
||
|
||
#### Coding Style
|
||
|
||
Here are the style guidelines that we are _trying_ to maintain:
|
||
- variables are in `snake_case`.
|
||
- types are in `CamelCase`.
|
||
|
||
Of course, we want to follow the formatter, too: see [below](#checking-format).
|
||
|
||
#### Commit Messages
|
||
|
||
We will try to maintain the following headline format for commit messages:
|
||
|
||
```
|
||
<component>: <subcomponent>: <change>
|
||
```
|
||
|
||
where `<component>` is one of:
|
||
|
||
1. `grammar`: For the tree-sitter-based grammar.
|
||
2. `compiler`: For the Swift-based P4 compiler of tree-sitter-based-parser parsed programs into AST.
|
||
3. `runtime`: For the Swift-based P4 interpreter.
|
||
4. `common`: For any Swift-based components common to the entire project (and macros).
|
||
5. `documentation`: For any documentation updates.
|
||
6. `testing`: For Swift-based tests.
|
||
7. `cli`: For Cli components.
|
||
7. `codegen`: For code generation components.
|
||
|
||
where `<subcomponent>` can be more free-form and `<change>` is a pithy description of the changes in the commit.
|
||
|
||
#### Notes To Self
|
||
|
||
While coding, it may be useful to leave ourselves notes. Every note is formatted like:
|
||
|
||
|
||
```Swift
|
||
/// NOTE<: optional note text>
|
||
```
|
||
|
||
where `NOTE` can be:
|
||
|
||
1. `TODO`: Remind us `TODO` something.
|
||
2. `ASSUME`: Remind us that we are making an assumption.
|
||
3. `NB`: Remind us that we need to remember something when reading this code.
|
||
|
||
#### Testing
|
||
|
||
To run the P4RSE tests:
|
||
|
||
```console
|
||
$ swift test
|
||
```
|
||
|
||
To run the parser tests, from the `tree-sitter-p4` directory:
|
||
```console
|
||
$ npx tree-sitter test
|
||
```
|
||
|
||
#### Generating Documentation
|
||
|
||
To build the documentation:
|
||
|
||
```console
|
||
$ swift package generate-documentation
|
||
```
|
||
|
||
To preview the generated documentation:
|
||
```console
|
||
$ swift package swift package --disable-sandbox preview-documentation --target <some target>
|
||
```
|
||
|
||
For more information, see the [documentation for the Swift-DocC plugin](https://swiftlang.github.io/swift-docc-plugin/documentation/swiftdoccplugin/).
|
||
|
||
#### Checking Format
|
||
|
||
To check the format:
|
||
|
||
```console
|
||
$ swift-format --recursive -i Sources/
|
||
```
|