Hello,
I am new to P4, and I have implemented several small projects using VMware, Mininet, bmv2 switch, and P4, all the previous “tools”(except VMware) are running on Ubuntu 22.04.3 LTS.
During my tests, I saw that the bmv2 switch processes ethernet packets without problems up to Layer 3. For example, I can create tables for ARP, IP, I have tried ICMP as well, and it works without problems. However, when I am creating tables for TCP traffic, for some reason my virtual host does not respond to the message sent by my client. It seems like the bmv2 is malforming the packet or something. I have sniffed the packet and I can’t see any issue, but every time I make a TCP consult via a bmv2 switch the target virtual host created by mininet does not respond to the consult.
E.g.
This is the topology I create with Mininet:
h1-------bmv2 switch-----h2
Then I am uploading the compiled json file that contains my tables to the bmv2 switch, my code before compiling it into a json file is below(If my code is the problem I would appreciate help to correct it).
I dont see anything wrong with the code, and actually after populating my table and testing TCP connection over telnet or with wget(from h1), I can see that the SYN packet reaches h2, but despite having a HTTP service running on h2, this host does not respond at all to the SYN packet, I would expect a SYN-ACK response, but I see nothing, hence, every connection fails.
I have seen some tutorials here and there, and they used a python program to send data over TCP on port 1234, I replicated the exercise and effectively I can send data from client to server over TCP, BUT, the target host running a tcp service does never respond with a SYN ACK or ACK(the exercize are more like using udp concepts but over tcp), hence, I am not sure whether the BMV2 support TCP, or maybe the bmv2-mininet integration needs additional configuration.
BTW, I tried the same exercise with OVS and mininet on the same ubuntu machine and it ran without problems.
BTW, I thought my setup was wrong, then I tested it in the lab that the University of South Carolina offers online and the issue is the same.
/* -- P4_16 -- */
#include <core.p4>
#include <v1model.p4>
const bit<16> TYPE_IPV4 = 0x800;
/*************************************************************************
*********************** 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;
}
struct metadata {
/* empty */
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
}
/*************************************************************************
*********************** 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;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
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 forward(egressSpec_t port){
standard_metadata.egress_spec = port;
}
table forwarding {
key = {
standard_metadata.ingress_port:exact;
}
actions = {
forward;
drop;
NoAction;
}
size = 1024;
default_action = drop();
}
apply {
forwarding.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 { }
}
/*************************************************************************
************* 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 { }
}
/*************************************************************************
*********************** D E P A R S E R *******************************
*************************************************************************/
control MyDeparser(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
}
}
/*************************************************************************
*********************** S W I T C H *******************************
*************************************************************************/
V1Switch(
MyParser(),
MyVerifyChecksum(),
MyIngress(),
MyEgress(),
MyComputeChecksum(),
MyDeparser()
) main;
I hope you can help me, my email is absuarez@uw.edu just in case.