Question on MRI exercise


I have a question on MRI exercise in tutorial repository. By default, the exercise uses UDP protocol, everything works fine. I want to change UDP protocol to TCP protocol for experimental purpose, so I’ve just only modified the code of and a little bit

pkt = Ether(src=get_if_hwaddr(iface), dst="ff:ff:ff:ff:ff:ff") / IP(
        dst=addr, options = IPOption_MRI(count=0,
            swtraces=[])) / TCP(
            dport=1234, sport=random.randint(49152,65535)) / sys.argv[2]

def handle_pkt(pkt):
    if TCP in pkt and pkt[TCP].dport == 1234:
        print("got a packet")
    #    hexdump(pkt)

def main():
    ifaces = [i for i in os.listdir('/sys/class/net/') if 'eth' in i]
    iface = ifaces[0]
    print("sniffing on %s" % iface)
    sniff(iface = iface,
          prn = lambda x: handle_pkt(x))

I run the exercise again, send 1 packet from h1 to h2. On h2’s xterm window, the packet is successfully received

But in Wireshark, there’s just only a SYN packet generated from h1

I’ve check all other interfaces of switches, there’s no SYN/ACK or ACK generated back from h2.
Do I also need to modified the p4 code to parse tcp header so that TCP protocol can function properly, because with UDP, there’s no need to do that?

Thank you!

Hi @tuananh01,

  1. I think that the packet that you generate with python does not belong to a TCP stream, in other world you generate a single TCP packet but you don’t have a TCP session etc.
    In order to have a real TCP session you should use iperf .

  2. Once you have a TCP real session you should add the flow rules needed for forwarding SYN/ACK or ACK. So to forward them you might just need to apply a match based on ethernet type, or ip address. So you have to verfy that one or more of these parameter are defined in the match criteria of your forwarding table.


Hi @tuananh01 and @DavideS ,

  1. I agree with @DavideS . If you have a TCP session running there are only two ways (maybe more but can only come up with two XD). You can either let both end-hosts deal with it (i.e. run a TCP stream with iperf2 or iperf3 or something on those lines). Or you could try to make the edge switch of the other end-host answer to the messages one by one. Of course, you need to take care about the first SYN/SYN-ACK/ACK handshake before sending data. You would also need to ACK every packet, etc. All that done in the edge-switch (not the host). Of course, it is quite of a piece of work and you can never make packets 100% as you see them in Wireshark, but maybe a little similar. We had something working already but never finished, I think it was an HTTP request/response. Possibly I can try to finish it and share it with you at some point. To summarize this issue, I always recommend using a UDP-like protocol (UDP or CoAP might be fine).

  2. Also, this sentence makes sense. If you want a session among host 1 and host 2 (edge hosts), you need to make sure that the rules in the switch tables make sense. If you do not see any host responding, there might not be any rules installed yet. Or the rules installed do not match with the communication criteria (packets).