diff --git a/bug1-bool/checksums.p4 b/bug1-bool/checksums.p4 new file mode 100644 index 0000000..dafdf47 --- /dev/null +++ b/bug1-bool/checksums.p4 @@ -0,0 +1,39 @@ +/* -*- P4_16 -*- */ +#ifndef CHECKSUMS_P4 +#define CHECKSUMS_P4 + +#include +#include + +#include "headers.p4" + +/************************************************************************* +************* 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 {} +} + +/************************************************************************* +************** 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 { + update_checksum_with_payload(meta.do_cksum, + { + hdr.ipv6.src_addr, /* 128 */ + hdr.ipv6.dst_addr, /* 128 */ + meta.cast_length, /* 32 */ + 24w0, /* 24 0's */ + PROTO_ICMP6 /* 8 */ + }, + hdr.icmp6.checksum, + HashAlgorithm.csum16 + ); + } +} + + +#endif diff --git a/bug1-bool/headers.p4 b/bug1-bool/headers.p4 new file mode 100644 index 0000000..63b2ef9 --- /dev/null +++ b/bug1-bool/headers.p4 @@ -0,0 +1,140 @@ +/* -*- P4_16 -*- */ +#ifndef HEADERS_P4 +#define HEADERS_P4 + +#include +#include + +typedef bit<48> mac_addr_t; +typedef bit<32> ipv4_addr_t; +typedef bit<128> ipv6_addr_t; +typedef bit<9> port_t; +typedef bit<16> mcast_t; +typedef bit<16> task_t; + + +const bit<16> TYPE_IPV4 = 0x0800; +const bit<16> TYPE_IPV6 = 0x86DD; +const bit<16> TYPE_CPU = 0x4242; +const bit<16> TYPE_DEBUG = 0x2323; + + +const bit<8> PROTO_ICMP = 1; +const bit<8> PROTO_TCP = 6; +const bit<8> PROTO_UDP = 17; +const bit<8> PROTO_ICMP6 = 58; + +const bit<8> TCP_SEQ_LEN = 4; + +const bit<8> ICMP6_ECHO_REQUEST = 128; +const bit<8> ICMP6_ECHO_REPLY = 129; +const bit<8> ICMP6_NS = 135; +const bit<8> ICMP6_NA = 136; + + +const task_t TASK_ICMP6_NS = 1; +const task_t TASK_ICMP6_GENERAL = 2; +const task_t TASK_DEBUG = 3; +const task_t TASK_ICMP6_REPLY = 4; + + +header ethernet_t { + mac_addr_t dst_addr; + mac_addr_t src_addr; + bit<16> ethertype; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<6> diff_serv; + bit<2> ecn; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + ipv4_addr_t src_addr; + ipv4_addr_t dst_addr; +} + +/* https://en.wikipedia.org/wiki/IPv6_packet */ +header ipv6_t { + bit<4> version; + bit<8> traffic_class; + bit<20> flow_label; + bit<16> payload_length; + bit<8> next_header; + bit<8> hop_limit; + ipv6_addr_t src_addr; + ipv6_addr_t dst_addr; +} + +header tcp_t{ + bit<16> src_port; + bit<16> dst_port; + int<32> seqNo; + int<32> ackNo; + bit<4> data_offset; + bit<4> res; + bit<1> cwr; + bit<1> ece; + bit<1> urg; + bit<1> ack; + bit<1> psh; + bit<1> rst; + bit<1> syn; + bit<1> fin; + bit<16> window; + bit<16> checksum; + bit<16> urgentPtr; +} + +header udp_t { + bit<16> src_port; + bit<16> dst_port; + bit<16> payload_length; + bit<16> checksum; +} + +header icmp6_t { + bit<8> type; + bit<8> code; + bit<16> checksum; +} + +header icmp_t { + bit<8> type; + bit<8> code; + bit<16> checksum; + bit<32> rest; +} + +header cpu_t { + task_t task; + bit<16> ingress_port; + bit<16> ethertype; +} + +struct headers { + ethernet_t ethernet; + ipv4_t ipv4; + ipv6_t ipv6; + tcp_t tcp; + udp_t udp; + icmp6_t icmp6; + icmp_t icmp; + cpu_t cpu; +} + +struct metadata { + port_t ingress_port; + task_t task; + bit<16> tcp_length; + bit<32> cast_length; + bool do_cksum; +} + +#endif \ No newline at end of file diff --git a/bug1-bool/parsers.p4 b/bug1-bool/parsers.p4 new file mode 100644 index 0000000..4988ede --- /dev/null +++ b/bug1-bool/parsers.p4 @@ -0,0 +1,97 @@ +/* -*- P4_16 -*- */ +#ifndef PARSERS_P4 +#define PARSERS_P4 + +#include +#include + +#include "headers.p4" + +parser MyParser(packet_in packet, + out headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + + state start { + packet.extract(hdr.ethernet); + transition select(hdr.ethernet.ethertype){ + TYPE_IPV4: ipv4; + TYPE_IPV6: ipv6; + default: accept; + } + } + + state ipv4 { + packet.extract(hdr.ipv4); + meta.tcp_length = hdr.ipv4.totalLen - 16w20; + + transition select(hdr.ipv4.protocol){ + PROTO_TCP: tcp; + PROTO_UDP: udp; + PROTO_ICMP: icmp; + + default: accept; + } + } + + state ipv6 { + packet.extract(hdr.ipv6); + meta.tcp_length = hdr.ipv6.payload_length; + + transition select(hdr.ipv6.next_header){ + PROTO_TCP: tcp; + PROTO_UDP: udp; + PROTO_ICMP6: icmp6; + default: accept; + } + } + + /* Leaf */ + state tcp { + packet.extract(hdr.tcp); + transition accept; + } + + state udp { + packet.extract(hdr.udp); + transition accept; + } + + state icmp6 { + packet.extract(hdr.icmp6); + transition accept; + } + + state icmp { + packet.extract(hdr.icmp); + transition accept; + } + +} + +/************************************************************************* +************************ D E P A R S E R ******************************* +*************************************************************************/ + +control MyDeparser(packet_out packet, in headers hdr) { + apply { + /* always */ + packet.emit(hdr.ethernet); + + /* only if information is sent to the controller */ + packet.emit(hdr.cpu); + + /* either */ + packet.emit(hdr.ipv4); + packet.emit(hdr.ipv6); + + /* either */ + packet.emit(hdr.tcp); + packet.emit(hdr.udp); + packet.emit(hdr.icmp); + packet.emit(hdr.icmp6); + } +} + + +#endif diff --git a/bug1-bool/settings.p4 b/bug1-bool/settings.p4 new file mode 100644 index 0000000..7610ce6 --- /dev/null +++ b/bug1-bool/settings.p4 @@ -0,0 +1,14 @@ +/* -*- P4_16 -*- */ +/* table sizes, register widths, and such */ +#ifndef SETTINGS_P4 +#define SETTINGS_P4 + +#include +#include + +#define THE_ANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING 42 /* Important constant */ +#define ROUTING_TABLE_SIZE 64 /* maximum routes per protocol */ +#define ADDRESS_TABLE_SIZE 64 /* maximum number of addresses per protocol */ +#define NDP_TABLE_SIZE 64 /* maximum number of multicast groups */ + +#endif diff --git a/bug1-bool/static-mapping.p4 b/bug1-bool/static-mapping.p4 new file mode 100644 index 0000000..9059352 --- /dev/null +++ b/bug1-bool/static-mapping.p4 @@ -0,0 +1,256 @@ +/* -*- P4_16 -*- */ +#include +#include + +#include "headers.p4" +#include "parsers.p4" +#include "checksums.p4" +#include "settings.p4" + + +/************************************************************************* +************** 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) { + + /********************** ACTIONS ***********************************/ + + action drop() { + mark_to_drop(); + } + + action set_egress_port (port_t out_port) { + standard_metadata.egress_spec = out_port; + } + + action controller_debug() { + meta.task = TASK_DEBUG; + meta.ingress_port = standard_metadata.ingress_port; + clone3(CloneType.I2E, 100, meta); + } + + action controller_reply(task_t task) { + meta.task = task; + meta.ingress_port = standard_metadata.ingress_port; + clone3(CloneType.I2E, 100, meta); + } + + action multicast_pkg(mcast_t mcast_grp) { /* Output PKG on correct ports (plural) */ + standard_metadata.mcast_grp = mcast_grp; + } + + action icmp6_neighbor_solicitation(ipv6_addr_t addr) { + /* egress = ingress */ + standard_metadata.egress_spec = standard_metadata.ingress_port; + + hdr.ipv6.dst_addr = hdr.ipv6.src_addr; + hdr.ipv6.src_addr = addr; + hdr.icmp6.type = ICMP6_NA; + } + + action icmp6_echo_reply() { + mac_addr_t mac_tmp = hdr.ethernet.dst_addr; + hdr.ethernet.dst_addr = hdr.ethernet.src_addr; + hdr.ethernet.src_addr = mac_tmp; + + ipv6_addr_t addr_tmp = hdr.ipv6.dst_addr; + hdr.ipv6.dst_addr = hdr.ipv6.src_addr; + hdr.ipv6.src_addr = addr_tmp; + + hdr.icmp6.type = ICMP6_ECHO_REPLY; + + meta.do_cksum = true; + meta.cast_length = (bit<32>) hdr.ipv6.payload_length; + } + + /* this needs SESSIONS!! + - icmp6: (src addr, dst addr, ID??, ) + - tcp: (src port, dst port, dst_addr, src addr) + - udp: (src port, dst port, dst_addr, src addr) + */ + // action nat64_static(ipv4_addr_t nataddr, ipv6_addr_t nat64_prefix) { + // hdr.ipv4.dst_addr = hdr.ipv6.dst_addr - nat64_prefix; + // hdr.ipv4.dst_addr = hdr.ipv6.dst_addr - nat64_prefix; + // } + + /********************** Reply to NDP for US ***********************************/ + table ndp_answer { + key = { + hdr.ipv6.dst_addr: exact; /* our multicast embedded mac address */ + hdr.icmp6.type: exact; + } + actions = { + controller_debug; + icmp6_neighbor_solicitation; + NoAction; + } + size = NDP_TABLE_SIZE; + default_action = NoAction; + } + + /********************** debugging / general support ***********************************/ + + table port2mcast { + key = { + standard_metadata.ingress_port : exact; + } + actions = { + multicast_pkg; + controller_debug; + NoAction; + } + size = NDP_TABLE_SIZE; + default_action = NoAction; +// default_action = controller_debug; + } + + /* Handle multicast registration of NDP */ + table addr2mcast { + key = { + hdr.ipv6.dst_addr: exact; + } + actions = { + multicast_pkg; + controller_debug; + NoAction; + } + size = NDP_TABLE_SIZE; + default_action = NoAction; +// default_action = controller_debug; + } + + /********************** NDP support ***********************************/ + + + table ndp { + key = { + hdr.ipv6.dst_addr: lpm; + standard_metadata.ingress_port : exact; + } + actions = { + multicast_pkg; + controller_debug; + NoAction; + } + size = NDP_TABLE_SIZE; +// default_action = NoAction; + default_action = controller_debug; + } + + + /********************** ADDRESS TABLES ***********************************/ + action icmp6_answer() { + + if(hdr.icmp6.isValid()) { + if(hdr.icmp6.code == ICMP6_ECHO_REQUEST) { + ipv6_addr_t tmp = hdr.ipv6.src_addr; + hdr.ipv6.src_addr = hdr.ipv6.dst_addr; + hdr.ipv6.dst_addr = tmp; + hdr.icmp6.code = ICMP6_ECHO_REPLY; + } + } + + /* do something: + - change src/dst + - change type + */ + } + + + /********************** ROUTING (egress definiton) TABLES ***********************************/ + + table v6_addresses { + key = { + hdr.ipv6.dst_addr: exact; + } + actions = { + controller_debug; + controller_reply; + icmp6_echo_reply; + NoAction; + } + size = ADDRESS_TABLE_SIZE; + default_action = NoAction; + + } + + table v6_networks { + key = { + hdr.ipv6.dst_addr: lpm; + } + actions = { + set_egress_port; + controller_debug; + controller_reply; + NoAction; + } + size = ROUTING_TABLE_SIZE; + default_action = NoAction; + } + + table v4_networks { + key = { + hdr.ipv4.dst_addr: lpm; + } + actions = { + set_egress_port; + NoAction; + } + size = ROUTING_TABLE_SIZE; + default_action = NoAction; + } + + /********************** APPLYING TABLES ***********************************/ + apply { + if(hdr.ipv6.isValid()) { + /* FIXME: structure / use .hit to do logic */ + // ndp_answer.apply(); + //ndp.apply(); /* flood or if it is us - answer */ + + v6_addresses.apply(); + v6_networks.apply(); + } + if(hdr.ipv4.isValid()) { + v4_networks.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) { + apply { + // ingress clone + if (standard_metadata.instance_type == 1){ + hdr.cpu.setValid(); + hdr.cpu.task = meta.task; + hdr.cpu.ethertype = hdr.ethernet.ethertype; + hdr.cpu.ingress_port = (bit<16>)meta.ingress_port; + + hdr.ethernet.ethertype = TYPE_CPU; + } + } +} + +/************************************************************************* +*********************** S W I T C H ******************************* +*************************************************************************/ + +V1Switch( +MyParser(), +MyVerifyChecksum(), +MyIngress(), +MyEgress(), +MyComputeChecksum(), +MyDeparser() +) main; + + + // truncate((bit<32>)22); //ether+cpu header diff --git a/p4app/bug1-bool.json b/p4app/bug1-bool.json index ab6943b..ad3e8b4 100644 --- a/p4app/bug1-bool.json +++ b/p4app/bug1-bool.json @@ -1,5 +1,5 @@ { - "program": "../p4src/bug1-bool.p4", + "program": "../bug1-bool/static-mapping.p4", "switch": "simple_switch", "compiler": "p4c", "options": "--target bmv2 --arch v1model --std p4-16",