Dear community,
I am adding ICMP protocol to the existing code. The code was working fine before ICMP implementation. Below is given the code with ICMP implementation:
/* -*- P4_17 -*- */
#include <core.p4>
#include <v1model.p4>
const bit<16> TYPE_IPV4 = 0x800;
const bit<8> UDP_PROTOCOL = 0x11;
const bit<8> TCP_PROTOCOL = 0x06;
const bit<16> ETHERTYPE_ARP = 0x0806;
const bit<8> IPPROTO_ICMP = 0x01;
/*************************************************************************
*********************** 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;
}
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
ip4Addr_t srcAddr;
ip4Addr_t dstAddr;
}
const bit<16> ARP_HTYPE_ETHERNET = 0x0001;
const bit<16> ARP_PTYPE_IPV4 = 0x0800;
const bit<8> ARP_HLEN_ETHERNET = 6;
const bit<8> ARP_PLEN_IPV4 = 4;
const bit<16> ARP_OPER_REQUEST = 1;
const bit<16> ARP_OPER_REPLY = 2;
header arp_t {
bit<16> hrd; // Hardware Type
bit<16> pro; // Protocol Type
bit<8> hln; // Hardware Address Length
bit<8> pln; // Protocol Address Length
bit<16> op; // Opcode
macAddr_t sha; // Sender Hardware Address
ip4Addr_t spa; // Sender Protocol Address
macAddr_t tha; // Target Hardware Address
ip4Addr_t tpa; // Target Protocol Address
}
const bit<8> ICMP_ECHO_REQUEST = 8;
const bit<8> ICMP_ECHO_REPLY = 0;
header icmp_t {
bit<8> type;
bit<8> code;
bit<16> checksum;
}
header udp_t {
bit<16> srcPort;
bit<16> dstPort;
bit<16> length_;
bit<16> checksum;
}
header tcp_t {
bit<16> srcPort;
bit<16> dstPort;
bit<32> seqNo;
bit<32> ackNo;
bit<4> dataOffset;
bit<3> res;
bit<3> ecn;
bit<6> ctrl;
bit<16> window;
bit<16> checksum;
bit<16> urgentPtr;
}
struct metadata {
ip4Addr_t dst_ipv4;
macAddr_t mac_da;
macAddr_t mac_sa;
egressSpec_t egress_port;
macAddr_t my_mac;
/* empty */
}
header metadata_t {
bit<32> enq_timestamp;
bit<32> enq_qdepth;
bit<32> deq_timedelta;
bit<32> deq_qdepth;
}
struct headers {
ethernet_t ethernet;
arp_t arp;
ipv4_t ipv4;
udp_t udp;
tcp_t tcp;
icmp_t icmp;
metadata_t my_meta;
}
/*************************************************************************
*********************** 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) {
TYPE_IPV4: parse_ipv4;
ETHERTYPE_ARP : parse_arp;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
transition select(hdr.ipv4.protocol){
UDP_PROTOCOL: parse_udp;
TCP_PROTOCOL: parse_tcp;
IPPROTO_ICMP : parse_icmp;
default : accept;
}
}
state parse_arp {
packet.extract(hdr.arp);
transition accept;
}
state parse_udp{
packet.extract(hdr.udp);
transition accept;
}
state parse_tcp{
packet.extract(hdr.tcp);
transition accept;
}
state parse_icmp {
packet.extract(hdr.icmp);
transition 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 ipv4_forward(egressSpec_t port) {
//standard_metadata.egress_spec = port;
//hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
//hdr.ethernet.dstAddr = dstAddr;
standard_metadata.egress_spec = port;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
}
action arp_forward2(egressSpec_t port) {
standard_metadata.egress_spec = port;
}
table ipv4_lpm {
key = {
hdr.ipv4.dstAddr: exact;
}
actions = {
ipv4_forward;
drop;
NoAction;
}
size = 1024;
default_action = NoAction();
}
action forward_ipv4() {
//hdr.ethernet.srcAddr = meta.mac_sa;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
standard_metadata.egress_spec = meta.egress_port;
}
action icmp_forward2() {
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
standard_metadata.egress_spec = meta.egress_port;
}
table arp_forward {
key = {
hdr.arp.tpa: exact;
}
actions = {
arp_forward2;
NoAction;
}
size = 1024;
default_action = NoAction();
}
table icmp_forward {
key = {
hdr.icmp.type : exact;
}
actions = {
icmp_forward2;
NoAction;
}
size = 1024;
default_action = NoAction();
}
apply {
ipv4_lpm.apply();
//forward.apply();
if (((hdr.arp.isValid()) && (hdr.arp.op == ARP_OPER_REQUEST || hdr.arp.op == ARP_OPER_REPLY))) { arp_forward.apply(); }
if (hdr.icmp.isValid()) {icmp_forward.apply();}
}
}
/*************************************************************************
**************** E G R E S S P R O C E S S I N G *******************
*************************************************************************/
struct my_egress_metadata{
bit<48> enq_timestamp;
bit<19> enq_depth;
bit<32> deq_time_delta;
bit<19> deq_depth;
bit<8> qid;
}
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply {
hdr.my_meta.setValid();
hdr.my_meta.enq_timestamp = 0xA; //standard_metadata.enq_timestamp;
hdr.my_meta.enq_qdepth = (bit<32>) 0xB; //standard_metadata.enq_qdepth;
hdr.my_meta.deq_timedelta = 0xC; //standard_metadata.deq_timedelta;
hdr.my_meta.deq_qdepth = (bit<32>) 0xD; //standard_metadata.deq_qdepth;
}
}
/*************************************************************************
************* 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(
hdr.ipv4.isValid(),
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffserv,
hdr.ipv4.totalLen,
hdr.ipv4.identification,
hdr.ipv4.flags,
hdr.ipv4.fragOffset,
hdr.ipv4.ttl,
hdr.ipv4.protocol,
hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr },
hdr.ipv4.hdrChecksum,
HashAlgorithm.csum16);
}
}
/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/
control MyDeparser(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.arp);
packet.emit(hdr.ipv4);
packet.emit(hdr.udp);
packet.emit(hdr.tcp);
packet.emit(hdr.icmp);
packet.emit(hdr.my_meta);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
As shown in console logs below , whenever I ping the host somehow hdr.icmp.isValid is giving false and throwing the packet to port 0.
[21:12:17.376] [bmv2] [T] [thread 371] [28.0] [cxt 0] arp_pl.p4(264) Condition "hdr.icmp.isValid()" (node_5) is false
[21:12:17.376] [bmv2] [D] [thread 371] [28.0] [cxt 0] Pipeline 'ingress': end
[21:12:17.376] [bmv2] [D] [thread 371] [28.0] [cxt 0] Egress port is 0
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Pipeline 'egress': start
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] Applying table 'tbl_arp_pl284'
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Looking up key:
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Table 'tbl_arp_pl284': miss
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Action entry is arp_pl284 -
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] Action arp_pl284
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] arp_pl.p4(284) Primitive hdr.my_meta.setValid()
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] arp_pl.p4(285) Primitive hdr.my_meta.enq_timestamp = 0xA
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] arp_pl.p4(286) Primitive hdr.my_meta.enq_qdepth = (bit<32>) 0xB
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] arp_pl.p4(287) Primitive hdr.my_meta.deq_timedelta = 0xC
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] arp_pl.p4(288) Primitive hdr.my_meta.deq_qdepth = (bit<32>) 0xD
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Pipeline 'egress': end
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Deparser 'deparser': start
[21:12:17.376] [bmv2] [T] [thread 372] [28.0] [cxt 0] Skipping checksum 'cksum' update because condition not met
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Deparsing header 'ethernet'
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Deparsing header 'arp'
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Deparsing header 'my_meta'
[21:12:17.376] [bmv2] [D] [thread 372] [28.0] [cxt 0] Deparser 'deparser': end
[21:12:17.376] [bmv2] [D] [thread 376] [28.0] [cxt 0] Transmitting packet of size 72 out of port 0
What may be the issue?