Exercise for L2 multicast (#288)
This commit is contained in:
parent
b8baba5df5
commit
590f4ff6f2
4
exercises/multicast/Makefile
Normal file
4
exercises/multicast/Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
BMV2_SWITCH_EXE = simple_switch_grpc
|
||||||
|
TOPO = sig-topo/topology.json
|
||||||
|
|
||||||
|
include ../../utils/Makefile
|
After Width: | Height: | Size: 97 B |
154
exercises/multicast/README.md
Normal file
154
exercises/multicast/README.md
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
# Implementing Multicast
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The objective of this exercise is to write a P4 program that multicasts packets
|
||||||
|
to a group of ports.
|
||||||
|
|
||||||
|
|
||||||
|
Upon receiving an Ethernet packet, the switch looks up the output port based on
|
||||||
|
the destination MAC address. If it is a miss, the switch broadcast packets on
|
||||||
|
ports belonging to a multicast group (if ingress port appears in the group, the
|
||||||
|
packet will be dropped in the egress pipeline).
|
||||||
|
|
||||||
|
|
||||||
|
Your switch will have a single table, which the control plane will populate with
|
||||||
|
static rules. Each rule will map an Ethernet MAC address to the output port. We
|
||||||
|
have already defined the control plane rules, so you only need to implement the
|
||||||
|
data plane logic of your P4 program.
|
||||||
|
|
||||||
|
We will use the linear topology for this exercise. It is a single switch that
|
||||||
|
connects four hosts as follow:
|
||||||
|
|
||||||
|
h1 h2
|
||||||
|
| |
|
||||||
|
---------------------------- s1
|
||||||
|
| |
|
||||||
|
h3 h4
|
||||||
|
|
||||||
|
Our P4 program will be written for the V1Model architecture implemented on
|
||||||
|
P4.org's bmv2 software switch. The architecture file for the V1Model can be
|
||||||
|
found at: /usr/local/share/p4c/p4include/v1model.p4. This file describes the
|
||||||
|
interfaces of the P4 programmable elements in the architecture, the supported
|
||||||
|
externs, as well as the architecture's standard metadata fields. We encourage
|
||||||
|
you to take a look at it.
|
||||||
|
|
||||||
|
> **Spoiler alert:** There is a reference solution in the `solution`
|
||||||
|
> sub-directory. Feel free to compare your implementation to the
|
||||||
|
> reference.
|
||||||
|
|
||||||
|
## Step 1: Run the (incomplete) starter code
|
||||||
|
|
||||||
|
The directory with this README also contains a skeleton P4 program,
|
||||||
|
`multicast.p4`, which initially drops all packets. Your job will be to extend
|
||||||
|
this skeleton program to properly forward Ethernet packets.
|
||||||
|
|
||||||
|
Before that, let's compile the incomplete `multicast.p4` and bring up a switch
|
||||||
|
in Mininet to test its behavior.
|
||||||
|
|
||||||
|
1. In your shell, run:
|
||||||
|
```bash
|
||||||
|
make run
|
||||||
|
```
|
||||||
|
This will:
|
||||||
|
* compile `multicast.p4`, and
|
||||||
|
* start the sig-topo in Mininet and configure all switches with
|
||||||
|
the appropriate P4 program + table entries, and
|
||||||
|
* configure all hosts with the commands listed in
|
||||||
|
[pod-topo/topology.json](./pod-topo/topology.json)
|
||||||
|
|
||||||
|
2. You should now see a Mininet command prompt. Try to ping between
|
||||||
|
hosts in the topology:
|
||||||
|
```bash
|
||||||
|
mininet> h1 ping h2
|
||||||
|
mininet> pingall
|
||||||
|
```
|
||||||
|
3. Type `exit` to leave each xterm and the Mininet command line.
|
||||||
|
Then, to stop mininet:
|
||||||
|
```bash
|
||||||
|
make stop
|
||||||
|
```
|
||||||
|
And to delete all pcaps, build files, and logs:
|
||||||
|
```bash
|
||||||
|
make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
The ping failed because each switch is programmed according to `multicast.p4`,
|
||||||
|
which drops all packets on arrival. Your job is to extend this file so it
|
||||||
|
forwards packets.
|
||||||
|
|
||||||
|
### A note about the control plane
|
||||||
|
|
||||||
|
A P4 program defines a packet-processing pipeline, but the rules within each
|
||||||
|
table are inserted by the control plane. When a rule matches a packet, its
|
||||||
|
action is invoked with parameters supplied by the control plane as part of the
|
||||||
|
rule.
|
||||||
|
|
||||||
|
In this exercise, we have already implemented the control plane logic for you.
|
||||||
|
As part of bringing up the Mininet instance, the `make run` command will install
|
||||||
|
packet-processing rules in the tables of each switch. These are defined in the
|
||||||
|
`sX-runtime.json` files, where `X` corresponds to the switch number.
|
||||||
|
|
||||||
|
**Important:** We use P4Runtime to install the control plane rules. The
|
||||||
|
content of files `sX-runtime.json` refer to specific names of tables, keys, and
|
||||||
|
actions, as defined in the P4Info file produced by the compiler (look for the
|
||||||
|
file `build/basic.p4.p4info.txt` after executing `make run`). Any changes in the P4
|
||||||
|
program that add or rename tables, keys, or actions will need to be reflected in
|
||||||
|
these `sX-runtime.json` files.
|
||||||
|
|
||||||
|
## Step 2: Implement L2 Multicast
|
||||||
|
|
||||||
|
The `multicast.p4` file contains a skeleton P4 program with key pieces of logic
|
||||||
|
replaced by `TODO` comments. Your implementation should follow the structure
|
||||||
|
given in this file---replace each `TODO` with logic implementing the missing
|
||||||
|
piece.
|
||||||
|
|
||||||
|
A complete `multicast.p4` will contain the following components:
|
||||||
|
|
||||||
|
1. Header type definitions for Ethernet (`ethernet_t`)
|
||||||
|
2. An action to drop a packet, using `mark_to_drop()`.
|
||||||
|
3. **TODO:** An action (called `multicast`) that sends multiple copies of packets
|
||||||
|
to a group of output ports.
|
||||||
|
4. **TODO:** Add the `multicast` action to the list of available actions
|
||||||
|
5. **TODO:** Set `multicast` as default action for table `mac_lookup`
|
||||||
|
|
||||||
|
## Step 3: Run your solution
|
||||||
|
|
||||||
|
Follow the instructions from Step 1. This time, you should be able to
|
||||||
|
successfully ping between `h1`, `h2` and `h3` but not `h4` in the topology.
|
||||||
|
|
||||||
|
6. **TODO:** Add port 4 to the multicast group in file `sig-topo/s1-runtime.json`
|
||||||
|
|
||||||
|
### Food for thought
|
||||||
|
|
||||||
|
Other questions to consider:
|
||||||
|
- How would you enhance your program to respond to ARP requests?
|
||||||
|
- How would you enhance your program to support MAC learning from the controller?
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
|
||||||
|
There are several problems that might manifest as you develop your program:
|
||||||
|
|
||||||
|
1. `multicast.p4` might fail to compile. In this case, `make run` will
|
||||||
|
report the error emitted from the compiler and halt.
|
||||||
|
|
||||||
|
2. `multicast.p4` might compile but fail to support the control plane rules in
|
||||||
|
the `s1-runtime.json` file that `make run` tries to install using P4Runtime. In
|
||||||
|
this case, `make run` will report errors if control plane rules cannot be
|
||||||
|
installed. Use these error messages to fix your `multicast.p4` implementation.
|
||||||
|
|
||||||
|
3. `multicast.p4` might compile, and the control plane rules might be installed,
|
||||||
|
but the switch might not process packets in the desired way. The `logs/sX.log`
|
||||||
|
files contain detailed logs that describing how each switch processes each
|
||||||
|
packet. The output is detailed and can help pinpoint logic errors in your
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
#### Cleaning up Mininet
|
||||||
|
|
||||||
|
In the latter two cases above, `make run` may leave a Mininet instance
|
||||||
|
running in the background. Use the following command to clean up
|
||||||
|
these instances:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make stop
|
||||||
|
```
|
3
exercises/multicast/disable_ipv6.sh
Executable file
3
exercises/multicast/disable_ipv6.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
|
||||||
|
sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
|
149
exercises/multicast/multicast.p4
Normal file
149
exercises/multicast/multicast.p4
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/* -*- P4_16 -*- */
|
||||||
|
#include <core.p4>
|
||||||
|
#include <v1model.p4>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** H E A D E R S ***********************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
typedef bit<9> egressSpec_t;
|
||||||
|
typedef bit<48> macAddr_t;
|
||||||
|
typedef bit<32> ip4Addr_t;
|
||||||
|
|
||||||
|
|
||||||
|
header ethernet_t {
|
||||||
|
macAddr_t dstAddr;
|
||||||
|
macAddr_t srcAddr;
|
||||||
|
bit<16> etherType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct metadata {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct headers {
|
||||||
|
ethernet_t ethernet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** P A R S E R ***********************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
parser MyParser(packet_in packet,
|
||||||
|
out headers hdr,
|
||||||
|
inout metadata meta,
|
||||||
|
inout standard_metadata_t standard_metadata) {
|
||||||
|
|
||||||
|
state start {
|
||||||
|
transition parse_ethernet;
|
||||||
|
}
|
||||||
|
|
||||||
|
state parse_ethernet {
|
||||||
|
packet.extract(hdr.ethernet);
|
||||||
|
transition select(hdr.ethernet.etherType) {
|
||||||
|
default : accept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
************ C H E C K S U M V E R I F I C A T I O N *************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||||
|
apply { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
************** I N G R E S S P R O C E S S I N G *******************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyIngress(inout headers hdr,
|
||||||
|
inout metadata meta,
|
||||||
|
inout standard_metadata_t standard_metadata) {
|
||||||
|
|
||||||
|
action drop() {
|
||||||
|
mark_to_drop(standard_metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: define `multicast` action to multicast packets to group 1
|
||||||
|
// Hint: Check v1model for multicast group
|
||||||
|
|
||||||
|
action mac_forward(egressSpec_t port) {
|
||||||
|
standard_metadata.egress_spec = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
table mac_lookup {
|
||||||
|
key = {
|
||||||
|
hdr.ethernet.dstAddr : exact;
|
||||||
|
}
|
||||||
|
actions = {
|
||||||
|
// TODO: add `multicast` action to the list of available actions
|
||||||
|
mac_forward;
|
||||||
|
drop;
|
||||||
|
}
|
||||||
|
size = 1024;
|
||||||
|
// TODO : replace default drop action by multicast
|
||||||
|
default_action = drop;
|
||||||
|
}
|
||||||
|
apply {
|
||||||
|
if (hdr.ethernet.isValid())
|
||||||
|
mac_lookup.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************** E G R E S S P R O C E S S I N G *******************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyEgress(inout headers hdr,
|
||||||
|
inout metadata meta,
|
||||||
|
inout standard_metadata_t standard_metadata) {
|
||||||
|
|
||||||
|
action drop() {
|
||||||
|
mark_to_drop(standard_metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
apply {
|
||||||
|
// Prune multicast packet to ingress port to preventing loop
|
||||||
|
if (standard_metadata.egress_port == standard_metadata.ingress_port)
|
||||||
|
drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
************* C H E C K S U M C O M P U T A T I O N **************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
|
||||||
|
apply {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** D E P A R S E R *******************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyDeparser(packet_out packet, in headers hdr) {
|
||||||
|
apply {
|
||||||
|
packet.emit(hdr.ethernet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** S W I T C H *******************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
V1Switch(
|
||||||
|
MyParser(),
|
||||||
|
MyVerifyChecksum(),
|
||||||
|
MyIngress(),
|
||||||
|
MyEgress(),
|
||||||
|
MyComputeChecksum(),
|
||||||
|
MyDeparser()
|
||||||
|
) main;
|
66
exercises/multicast/sig-topo/s1-runtime.json
Normal file
66
exercises/multicast/sig-topo/s1-runtime.json
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"target": "bmv2",
|
||||||
|
"p4info": "build/multicast.p4.p4info.txt",
|
||||||
|
"bmv2_json": "build/multicast.json",
|
||||||
|
"table_entries": [
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:01:11"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:02:22"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:03:33"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:04:44"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"multicast_group_entries" : [
|
||||||
|
{
|
||||||
|
"multicast_group_id" : 1,
|
||||||
|
"replicas" : [
|
||||||
|
{
|
||||||
|
"egress_port" : 1,
|
||||||
|
"instance" : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egress_port" : 2,
|
||||||
|
"instance" : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egress_port" : 3,
|
||||||
|
"instance" : 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
exercises/multicast/sig-topo/topology.json
Normal file
18
exercises/multicast/sig-topo/topology.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"hosts": {
|
||||||
|
"h1": {"ip": "10.0.0.1/24", "mac": "08:00:00:00:01:11",
|
||||||
|
"commands":["ip route add 10.0.0.0/24 dev eth0"]},
|
||||||
|
"h2": {"ip": "10.0.0.2/24", "mac": "08:00:00:00:02:22",
|
||||||
|
"commands":["ip route add 10.0.0.0/24 dev eth0"]},
|
||||||
|
"h3": {"ip": "10.0.0.3/24", "mac": "08:00:00:00:03:33",
|
||||||
|
"commands":["ip route add 10.0.0.0/24 dev eth0"]},
|
||||||
|
"h4": {"ip": "10.0.0.4/24", "mac": "08:00:00:00:04:44",
|
||||||
|
"commands":["ip route add 10.0.0.0/24 dev eth0"]}
|
||||||
|
},
|
||||||
|
"switches": {
|
||||||
|
"s1": { "runtime_json" : "sig-topo/s1-runtime.json" }
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
["h1", "s1-p1"], ["h2", "s1-p2"], ["h3", "s1-p3"], ["h4", "s1-p4"]
|
||||||
|
]
|
||||||
|
}
|
149
exercises/multicast/solution/multicast.p4
Normal file
149
exercises/multicast/solution/multicast.p4
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/* -*- P4_16 -*- */
|
||||||
|
#include <core.p4>
|
||||||
|
#include <v1model.p4>
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** H E A D E R S ***********************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
typedef bit<9> egressSpec_t;
|
||||||
|
typedef bit<48> macAddr_t;
|
||||||
|
typedef bit<32> ip4Addr_t;
|
||||||
|
|
||||||
|
|
||||||
|
header ethernet_t {
|
||||||
|
macAddr_t dstAddr;
|
||||||
|
macAddr_t srcAddr;
|
||||||
|
bit<16> etherType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct metadata {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct headers {
|
||||||
|
ethernet_t ethernet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** P A R S E R ***********************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
parser MyParser(packet_in packet,
|
||||||
|
out headers hdr,
|
||||||
|
inout metadata meta,
|
||||||
|
inout standard_metadata_t standard_metadata) {
|
||||||
|
|
||||||
|
state start {
|
||||||
|
transition parse_ethernet;
|
||||||
|
}
|
||||||
|
|
||||||
|
state parse_ethernet {
|
||||||
|
packet.extract(hdr.ethernet);
|
||||||
|
transition select(hdr.ethernet.etherType) {
|
||||||
|
default : accept;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
************ C H E C K S U M V E R I F I C A T I O N *************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
|
||||||
|
apply { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
************** I N G R E S S P R O C E S S I N G *******************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyIngress(inout headers hdr,
|
||||||
|
inout metadata meta,
|
||||||
|
inout standard_metadata_t standard_metadata) {
|
||||||
|
|
||||||
|
action drop() {
|
||||||
|
mark_to_drop(standard_metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
action multicast() {
|
||||||
|
standard_metadata.mcast_grp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
action mac_forward(egressSpec_t port) {
|
||||||
|
standard_metadata.egress_spec = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
table mac_lookup {
|
||||||
|
key = {
|
||||||
|
hdr.ethernet.dstAddr : exact;
|
||||||
|
}
|
||||||
|
actions = {
|
||||||
|
multicast;
|
||||||
|
mac_forward;
|
||||||
|
drop;
|
||||||
|
}
|
||||||
|
size = 1024;
|
||||||
|
default_action = multicast;
|
||||||
|
}
|
||||||
|
apply {
|
||||||
|
if (hdr.ethernet.isValid())
|
||||||
|
mac_lookup.apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
**************** E G R E S S P R O C E S S I N G *******************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyEgress(inout headers hdr,
|
||||||
|
inout metadata meta,
|
||||||
|
inout standard_metadata_t standard_metadata) {
|
||||||
|
|
||||||
|
action drop() {
|
||||||
|
mark_to_drop(standard_metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
apply {
|
||||||
|
// Prune multicast packet to ingress port to preventing loop
|
||||||
|
if (standard_metadata.egress_port == standard_metadata.ingress_port)
|
||||||
|
drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
************* C H E C K S U M C O M P U T A T I O N **************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
|
||||||
|
apply {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** D E P A R S E R *******************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
control MyDeparser(packet_out packet, in headers hdr) {
|
||||||
|
apply {
|
||||||
|
packet.emit(hdr.ethernet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
*********************** S W I T C H *******************************
|
||||||
|
*************************************************************************/
|
||||||
|
|
||||||
|
V1Switch(
|
||||||
|
MyParser(),
|
||||||
|
MyVerifyChecksum(),
|
||||||
|
MyIngress(),
|
||||||
|
MyEgress(),
|
||||||
|
MyComputeChecksum(),
|
||||||
|
MyDeparser()
|
||||||
|
) main;
|
70
exercises/multicast/solution/s1-runtime.json
Normal file
70
exercises/multicast/solution/s1-runtime.json
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"target": "bmv2",
|
||||||
|
"p4info": "build/multicast.p4.p4info.txt",
|
||||||
|
"bmv2_json": "build/multicast.json",
|
||||||
|
"table_entries": [
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:01:11"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:02:22"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:03:33"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table": "MyIngress.mac_lookup",
|
||||||
|
"match": {
|
||||||
|
"hdr.ethernet.dstAddr": "08:00:00:00:04:44"
|
||||||
|
},
|
||||||
|
"action_name": "MyIngress.mac_forward",
|
||||||
|
"action_params": {
|
||||||
|
"port": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"multicast_group_entries" : [
|
||||||
|
{
|
||||||
|
"multicast_group_id" : 1,
|
||||||
|
"replicas" : [
|
||||||
|
{
|
||||||
|
"egress_port" : 1,
|
||||||
|
"instance" : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egress_port" : 2,
|
||||||
|
"instance" : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egress_port" : 3,
|
||||||
|
"instance" : 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"egress_port" : 4,
|
||||||
|
"instance" : 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user