After changing ipv4.ihl and option field how to get packet on host2?

I have 2 hosts connected via a programmable switch.
The program is a basic p4 program that diverts the packets according to the destination ip address. Before adding on Ingress match-action pipeline
" action send(PortId_t port) {
ig_tm_md.ucast_egress_port = port;
hdr.ipv4.ihl = 6;
hdr.ipv4_option.queuelength =7; //(bit<32>)eg_intr_md.deq_qdepth; } "
these 2 lines I can see that host2 and host1 are exchanging the packets. But when I increase ipv4.ihl field to 6 and hdr.ipv4_option.queuelength =7; I can’t exchange the packets. Do I need to update anything to get the changed values on host2. When sniffing the packet using wireshark I can see that :
"host 2: #sudo python3 send.py 192.168.1.1 “P4 is cool”
host 1: # sudo tshark -i enp193s0
"1 0.000000000 192.168.1.2 → 192.168.1.1 TCP 68 0 → 0 [RST, PSH, ACK, ECN, CWR, NS, Reserved] Seq=0 Ack=1342316544 Win=0[Malformed Packet] "

How can I resolve this issue?

Kind regards,
Nagmat

The IPv4 header checksum field should include any IPv4 options in its calculation. If you are changing the IHL field received by the switch from 5 to 6, but not updating the checksum to include this new 4 bytes of IPv4 options data, that would cause any device that verifies IPv4 header checksums, like a host’s IPv4 networking software, to discard the packet.

Thanks for quick response. I am updating ihl field on Control Ingress and updating checksum on Ingress Deparser as shown :


control IngressDeparser(packet_out pkt,
    /* User */
    inout my_ingress_headers_t                       hdr,
    in    my_ingress_metadata_t                      meta,
    /* Intrinsic */
    in    ingress_intrinsic_metadata_for_deparser_t  ig_dprsr_md)
{
     Checksum() ipv4_checksum;

    apply {
        hdr.ipv4.hdr_checksum = ipv4_checksum.update({
                hdr.ipv4.version,
                hdr.ipv4.ihl,
                hdr.ipv4.diffserv,
                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
            });

        pkt.emit(hdr.ethernet);
        pkt.emit(hdr.ipv4);
    }
}

Even if I am updating checksum I am getting bogus TCP header while receiving packet with wireshark. Am I updating something wrong?

I do not know your complete program, nor exactly what packet you are trying to send in, what path of execution it is taking through your P4 program, nor what packet is coming out, so your description might be accurate, but I do not have any way to check that.

The checksum updating code you have written does not include the 4 bytes of IPv4 options you are adding when changing the IPv4 IHL field from 5 to 6, so that IPv4 checksum is almost certainly incorrect for the packets whose IHL value you are changing.

1 Like

@nagmat ,

This is the third forum where you post the same question and I believe it has already been answered and even more than once.

As you can see, the recommendations are exactly the same – all you need to do is to carefully follow all of them.

In fact, I believe that you finally got the issue resolved, so please confirm here.

1 Like

The issue was with updating checksum and setting option fields valid.

" action send(PortId_t port) {
ig_tm_md.ucast_egress_port = port;
hdr.ipv4.ihl = 6;
hdr.ipv4_option.setValid();
hdr.ipv4_option.queuelength = (bit<32>)eg_intr_md.deq_qdepth; } "