-
Notifications
You must be signed in to change notification settings - Fork 2
Pipeline
The standard V1Switch
pipeline contains the packet parser, a checksum verification, the ingress and egress flow, a checksum creation and a deparser.
V1Switch(
packetParser(),
verifyChecksum(),
ingress(),
egress(),
createChecksum(),
deparser()
) main;
The packet parser is the first step of the V1Switch
pipeline, defined in src/components/parser.p4
. It starts with the start state
and extracts the headers of the packet according to the given transitions.
state start {
transition parse_ethernet;
}
The first step is always the parse_ethernet
state. The ethernet header gets extracted and according to the etherType
other headers get parsed.
state parse_ethernet {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
TYPE_IPV4 : parse_ipv4;
TYPE_BIER : parse_bier;
TYPE_TOP_DISCOVER: parse_topology_discover;
default : accept;
}
}
Based on the protocol numbers, defined in src/components/headers.p4
, either IPv4
, BIER
or Topology
gets parsed.
The parse_bier
routine extracts the outer bier header and, according to the protocol field, the inner ipv4 header.
state parse_bier {
packet.extract(hdr.bier.next);
transition select(hdr.bier.Proto) {
TYPE_IPV4: parse_ipv4_inner;
default: accept;
}
}
The parse_ipv4
and parse_ipv4_inner
routines extract the outer and inner ipv4 header.
state parse_ipv4 {
packet.extract(hdr.ipv4);
transition select(hdr.ipv4.protocol) {
TYPE_IP_BIER: parse_bier;
TYPE_IP_IGMP: parse_igmp;
default: accept;
}
}
Based on the protocol field the bier header or the igmp header gets parsed.
state parse_ipv4_inner {
packet.extract(hdr.ipv4_inner);
transition accept;
}
The parse_topology_discover
and parse_igmp
routines extract the topology header and igmp header.
state parse_topology_discover {
packet.extract(hdr.topology);
transition accept;
}
state parse_igmp {
packet.extract(hdr.igmp);
transition accept;
}
The checksum control block, defined in src/components/checksum.p4
defines the verifyChecksum
control and the createChecksum
control needed for the V1Switch
.
The ingress control flow, defined in src/components/ingress.p4
, is the entry point for the user defined control blocks, e.g. BIER and IPv4.
control ingress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
Port() port_c;
Bier() bier_c; // bier control block
IPv4() ipv4_c; // ipv4 control block
TopologyDiscovery() topology_c; // topology control block
apply {
port_c.apply(hdr, meta, standard_metadata); // apply port status table, init port meta data
if (hdr.ethernet.etherType == TYPE_BIER) { // its a bier packet
bier_c.apply(hdr, meta, standard_metadata); // apply bier control
}
else if(hdr.ethernet.etherType == TYPE_IPV4) { // its a ipv4 packet
ipv4_c.apply(hdr, meta, standard_metadata); // apply ipv4 control
}
else if(hdr.ethernet.etherType == TYPE_TOP_DISCOVER) { // its a topology discovery packet
topology_c.apply(hdr, meta, standard_metadata);
}
}
}
At the beginning the port control block is applied. This control block initializes the port metadata information which is used later to distinguish a normal entry from a backup entry.
The ingress control flow applies, depending on the etherType
, the BIER control block, the IPv4 control block or the Topology control block.
The egress control flow, defined in src/components/egress.p4
, mainly handles cloned packets.
control egress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
Bier() bier_c;
Mac() mac_c;
apply {
if ((hdr.ethernet.etherType == TYPE_BIER) && standard_metadata.instance_type == PKT_INSTANCE_TYPE_INGRESS_CLONE) { // its a cloned bier packet
bier_c.apply(hdr, meta, standard_metadata); // apply bier control for cloned packets
}
mac_c.apply(hdr, meta, standard_metadata); // set layer 2 addresses if rules are set
}
}
If a cloned packet enters the egress flow, the corresponding control block gets applied (bier). Afterwards the mac control block gets applied, which changes the layer 2 addresses.
The last step in the pipeline is the so called Deparser
. The Deparser
adds the corresponding headers on the outgoing packets. Only valid headers are emitted.
control deparser(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.topology);
packet.emit(hdr.ipv4);
packet.emit(hdr.igmp);
packet.emit(hdr.bier);
packet.emit(hdr.ipv4_inner);
}
}
For a newly encapsulated BIER packet, the outer ipv4 header hdr.ipv4
is not valid and thus the outgoing packet does not have an outer ipv4 header.