Skip to content

Pipeline

Steffen Lindner edited this page Apr 15, 2019 · 1 revision

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;

Packet parser

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;
}

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.

BIER

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;
    }
}

IPv4

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;
}

Topology and IGMP

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;
}

Checksum

The checksum control block, defined in src/components/checksum.p4 defines the verifyChecksum control and the createChecksum control needed for the V1Switch.

Ingress

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.

Egress

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.

Deparser

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.