546 lines
16 KiB
Plaintext
546 lines
16 KiB
Plaintext
/*
|
|
* Copyright 2020-present Nehal Baganal
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <core.p4>
|
|
#include <tna.p4>
|
|
#include "header.p4"
|
|
#include "CoDel.p4"
|
|
|
|
parser SwitchIngressParser(packet_in packet, out headers_t hdr, out my_metadata_t meta, out ingress_intrinsic_metadata_t ig_intr_md) {
|
|
|
|
state start {
|
|
packet.extract(ig_intr_md);
|
|
packet.advance(PORT_METADATA_SIZE);
|
|
transition parse_ethernet;
|
|
}
|
|
state parse_ethernet{
|
|
packet.extract(hdr.ethernet);
|
|
transition select(hdr.ethernet.etherType) {
|
|
ether_type_t.IPV4: parse_ipv4;
|
|
default: accept;
|
|
}
|
|
}
|
|
|
|
state parse_ipv4 {
|
|
packet.extract(hdr.ipv4);
|
|
transition select(hdr.ipv4.frag_offset, hdr.ipv4.protocol, hdr.ipv4.ihl){
|
|
(0, ip_proto_t.ICMP, 5) : parse_icmp;
|
|
(0, ip_proto_t.TCP, 5) : parse_tcp;
|
|
(0, ip_proto_t.UDP, 5) : parse_udp;
|
|
( _, _, _ ) : accept;
|
|
}
|
|
}
|
|
|
|
|
|
state parse_tcp {
|
|
packet.extract(hdr.tcp);
|
|
//tcp_checksum.subtract({hdr.tcp.checksum});
|
|
transition select(hdr.tcp.data_offset){
|
|
4w0x5: parse_tcp_no_opt;
|
|
4w0x6: parse_tcp_opt_32b;
|
|
4w0x7: parse_tcp_opt_64b;
|
|
4w0x8: parse_tcp_opt_96b;
|
|
4w0x9: parse_tcp_opt_128b;
|
|
4w0xA: parse_tcp_opt_160b;
|
|
4w0xB: parse_tcp_opt_192b;
|
|
4w0xC: parse_tcp_opt_224b;
|
|
4w0xD: parse_tcp_opt_256b;
|
|
4w0xE: parse_tcp_opt_288b;
|
|
4w0xF: parse_tcp_opt_320b;
|
|
default: accept;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
state parse_tcp_no_opt {
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_32b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_64b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_96b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_128b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_160b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_192b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_224b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
|
|
state parse_tcp_opt_256b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
packet.extract(hdr.tcp_opt[7]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_288b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
packet.extract(hdr.tcp_opt[7]);
|
|
packet.extract(hdr.tcp_opt[8]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
|
|
state parse_tcp_opt_320b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
packet.extract(hdr.tcp_opt[7]);
|
|
packet.extract(hdr.tcp_opt[8]);
|
|
packet.extract(hdr.tcp_opt[9]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_my_tstamp {
|
|
//packet.extract(hdr.my_tstamp);
|
|
//tcp_checksum.subtract({hdr.my_tstamp.drop_tstamp_high});
|
|
//tcp_checksum.subtract({hdr.my_tstamp.drop_tstamp_low});
|
|
//tcp_checksum.subtract_all_and_deposit(meta.bridged_metadata.temp_tcp_checksum);
|
|
|
|
transition accept;
|
|
}
|
|
|
|
|
|
|
|
state parse_icmp {
|
|
packet.extract(hdr.icmp);
|
|
transition accept;
|
|
}
|
|
|
|
state parse_udp {
|
|
packet.extract(hdr.udp);
|
|
transition accept;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
control SwitchIngress(
|
|
inout headers_t hdr,
|
|
inout my_metadata_t meta,
|
|
in ingress_intrinsic_metadata_t ig_intr_md,
|
|
in ingress_intrinsic_metadata_from_parser_t ig_intr_parser_md,
|
|
inout ingress_intrinsic_metadata_for_deparser_t ig_intr_md_for_dprsr,
|
|
inout ingress_intrinsic_metadata_for_tm_t ig_intr_tm_md) {
|
|
|
|
action send(bit<9> egress_port) {
|
|
ig_intr_tm_md.ucast_egress_port = egress_port;
|
|
}
|
|
|
|
|
|
table t_l1_forwarding {
|
|
key = {
|
|
hdr.ipv4.dst_addr : exact; //ig_intr_md.ingress_port : exact;
|
|
}
|
|
actions = {
|
|
send;
|
|
}
|
|
size = 64;
|
|
}
|
|
|
|
|
|
|
|
apply {
|
|
|
|
t_l1_forwarding.apply();
|
|
ig_intr_tm_md.qid = 0;
|
|
meta.bridged_metadata.setValid();
|
|
meta.bridged_metadata.ingress_tstamp = ig_intr_parser_md.global_tstamp;
|
|
meta.bridged_metadata.ingress_port = hdr.ipv4.protocol;
|
|
meta.bridged_metadata.drop_counter_result = hdr.ipv4.ihl;
|
|
meta.bridged_metadata.temp_frag_offset = hdr.ipv4.frag_offset;
|
|
}
|
|
}
|
|
|
|
control SwitchIngressDeparser(packet_out packet, inout headers_t hdr, in my_metadata_t meta, in ingress_intrinsic_metadata_for_deparser_t ig_dprsr_md) {
|
|
|
|
//Checksum() ipv4_checksum;
|
|
//Checksum() tcp_checksum;
|
|
|
|
apply {
|
|
/* if (hdr.ipv4.isValid()) {
|
|
hdr.ipv4.hdr_checksum = ipv4_checksum.update({
|
|
hdr.ipv4.version,
|
|
hdr.ipv4.ihl,
|
|
hdr.ipv4.diffserv,
|
|
hdr.ipv4.ECN,
|
|
hdr.ipv4.total_len,
|
|
hdr.ipv4.identification,
|
|
hdr.ipv4.flags,
|
|
hdr.ipv4.frag_offset,
|
|
hdr.ipv4.ttl,
|
|
hdr.ipv4.protocol,
|
|
hdr.ipv4.hdr_checksum,
|
|
hdr.ipv4.src_addr,
|
|
hdr.ipv4.dst_addr
|
|
});
|
|
}
|
|
|
|
if (hdr.tcp.isValid()) {
|
|
hdr.tcp.checksum = tcp_checksum.update({
|
|
hdr.tcp.src_port,
|
|
hdr.tcp.dst_port,
|
|
hdr.tcp.seq_no,
|
|
hdr.tcp.ack_no,
|
|
hdr.tcp.data_offset,
|
|
hdr.tcp.res,
|
|
hdr.tcp.CWR,
|
|
hdr.tcp.ECE,
|
|
hdr.tcp.URG,
|
|
hdr.tcp.ACK,
|
|
hdr.tcp.PSH,
|
|
hdr.tcp.RST,
|
|
hdr.tcp.SYN,
|
|
hdr.tcp.FIN,
|
|
hdr.tcp.window,
|
|
hdr.tcp.checksum,
|
|
hdr.tcp.urgent_ptr,
|
|
hdr.my_tstamp.drop_flag,
|
|
hdr.my_tstamp.drop_tstamp_high,
|
|
hdr.my_tstamp.drop_tstamp_low
|
|
});
|
|
}*/
|
|
|
|
packet.emit(meta.bridged_metadata);
|
|
packet.emit(hdr);
|
|
}
|
|
|
|
}
|
|
|
|
parser SwitchEgressParser(packet_in packet, out headers_t hdr, out my_metadata_t meta, out egress_intrinsic_metadata_t eg_intr_md) {
|
|
|
|
state start {
|
|
packet.extract(eg_intr_md);
|
|
packet.extract(meta.bridged_metadata);
|
|
transition parse_ethernet;
|
|
}
|
|
state parse_ethernet{
|
|
packet.extract(hdr.ethernet);
|
|
transition select(hdr.ethernet.etherType) {
|
|
ether_type_t.IPV4: parse_ipv4;
|
|
default: accept;
|
|
}
|
|
}
|
|
state parse_ipv4 {
|
|
packet.extract(hdr.ipv4);
|
|
transition select(hdr.ipv4.frag_offset, hdr.ipv4.protocol, hdr.ipv4.ihl){
|
|
(0, ip_proto_t.TCP, 5) : parse_tcp;
|
|
//(0, ip_proto_t.ICMP, 5) : parse_icmp;
|
|
//(0, ip_proto_t.UDP, 5) : parse_udp;
|
|
( _, _, _ ) : accept;
|
|
}
|
|
}
|
|
|
|
|
|
state parse_icmp {
|
|
packet.extract(hdr.icmp);
|
|
transition accept;
|
|
}
|
|
|
|
state parse_tcp {
|
|
packet.extract(hdr.tcp);
|
|
//tcp_checksum.subtract({hdr.tcp.checksum});
|
|
transition select(hdr.tcp.data_offset){
|
|
4w0x5: parse_tcp_no_opt;
|
|
4w0x6: parse_tcp_opt_32b;
|
|
4w0x7: parse_tcp_opt_64b;
|
|
4w0x8: parse_tcp_opt_96b;
|
|
4w0x9: parse_tcp_opt_128b;
|
|
4w0xA: parse_tcp_opt_160b;
|
|
4w0xB: parse_tcp_opt_192b;
|
|
4w0xC: parse_tcp_opt_224b;
|
|
4w0xD: parse_tcp_opt_256b;
|
|
4w0xE: parse_tcp_opt_288b;
|
|
4w0xF: parse_tcp_opt_320b;
|
|
default: accept;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
state parse_tcp_no_opt {
|
|
transition parse_my_tstamp;
|
|
}
|
|
state parse_tcp_opt_32b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_64b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_96b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_128b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_160b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_192b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_224b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
|
|
state parse_tcp_opt_256b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
packet.extract(hdr.tcp_opt[7]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
state parse_tcp_opt_288b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
packet.extract(hdr.tcp_opt[7]);
|
|
packet.extract(hdr.tcp_opt[8]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
|
|
state parse_tcp_opt_320b {
|
|
packet.extract(hdr.tcp_opt[0]);
|
|
packet.extract(hdr.tcp_opt[1]);
|
|
packet.extract(hdr.tcp_opt[2]);
|
|
packet.extract(hdr.tcp_opt[3]);
|
|
packet.extract(hdr.tcp_opt[4]);
|
|
packet.extract(hdr.tcp_opt[5]);
|
|
packet.extract(hdr.tcp_opt[6]);
|
|
packet.extract(hdr.tcp_opt[7]);
|
|
packet.extract(hdr.tcp_opt[8]);
|
|
packet.extract(hdr.tcp_opt[9]);
|
|
transition parse_my_tstamp;
|
|
}
|
|
|
|
|
|
state parse_my_tstamp {
|
|
//packet.extract(hdr.my_tstamp);
|
|
//tcp_checksum.subtract({hdr.my_tstamp.drop_tstamp_high});
|
|
//tcp_checksum.subtract({hdr.my_tstamp.drop_tstamp_low});
|
|
//tcp_checksum.subtract_all_and_deposit(meta.bridged_metadata.temp_tcp_checksum);
|
|
|
|
transition accept;
|
|
}
|
|
|
|
|
|
|
|
|
|
state parse_udp {
|
|
packet.extract(hdr.udp);
|
|
transition accept;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
control SwitchEgress(
|
|
inout headers_t hdr,
|
|
inout my_metadata_t meta,
|
|
in egress_intrinsic_metadata_t eg_intr_md,
|
|
in egress_intrinsic_metadata_from_parser_t eg_intr_parser_md,
|
|
inout egress_intrinsic_metadata_for_deparser_t eg_intr_md_for_dprsr,
|
|
inout egress_intrinsic_metadata_for_output_port_t eg_intr_md_for_oport) {
|
|
|
|
CoDelEgress() codel_egress;
|
|
|
|
apply{
|
|
codel_egress.apply( meta.bridged_metadata.ingress_tstamp,
|
|
eg_intr_parser_md.global_tstamp,
|
|
eg_intr_md.egress_port,
|
|
hdr,
|
|
eg_intr_md_for_dprsr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
control SwitchEgressDeparser(packet_out packet, inout headers_t hdr, in my_metadata_t meta, in egress_intrinsic_metadata_for_deparser_t eg_dprsr_md) {
|
|
Checksum() ipv4_checksum;
|
|
//Checksum() tcp_checksum;
|
|
apply {
|
|
if (hdr.ipv4.isValid()) {
|
|
hdr.ipv4.hdr_checksum = ipv4_checksum.update({
|
|
hdr.ipv4.version,
|
|
hdr.ipv4.ihl,
|
|
hdr.ipv4.diffserv,
|
|
hdr.ipv4.ECN,
|
|
hdr.ipv4.total_len,
|
|
hdr.ipv4.identification,
|
|
hdr.ipv4.flags,
|
|
hdr.ipv4.frag_offset,
|
|
hdr.ipv4.ttl,
|
|
hdr.ipv4.protocol,
|
|
hdr.ipv4.src_addr,
|
|
hdr.ipv4.dst_addr
|
|
});
|
|
}
|
|
|
|
/*if (hdr.tcp.isValid()) {
|
|
hdr.tcp.checksum = tcp_checksum.update({
|
|
hdr.tcp.src_port,
|
|
hdr.tcp.dst_port,
|
|
hdr.tcp.seq_no,
|
|
hdr.tcp.ack_no,
|
|
hdr.tcp.data_offset,
|
|
hdr.tcp.res,
|
|
hdr.tcp.CWR,
|
|
hdr.tcp.ECE,
|
|
hdr.tcp.URG,
|
|
hdr.tcp.ACK,
|
|
hdr.tcp.PSH,
|
|
hdr.tcp.RST,
|
|
hdr.tcp.SYN,
|
|
hdr.tcp.FIN,
|
|
hdr.tcp.window,
|
|
hdr.tcp.checksum,
|
|
hdr.tcp.urgent_ptr,
|
|
hdr.my_tstamp.drop_flag,
|
|
hdr.my_tstamp.drop_tstamp_high,
|
|
hdr.my_tstamp.drop_tstamp_low
|
|
});
|
|
}*/
|
|
|
|
|
|
//packet.emit(meta.bridged_metadata);
|
|
packet.emit(hdr);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
Pipeline(SwitchIngressParser(),
|
|
SwitchIngress(),
|
|
SwitchIngressDeparser(),
|
|
SwitchEgressParser(),
|
|
SwitchEgress(),
|
|
SwitchEgressDeparser()) pipe;
|
|
|
|
Switch(pipe) main;
|