Fixed downlink processing of spgw.p4
Change-Id: I37f2361bcdd6539a38b294b7da10989a851cf2ec
diff --git a/pipelines/fabric/src/main/resources/include/checksum.p4 b/pipelines/fabric/src/main/resources/include/checksum.p4
index 4d1782d..d920235 100644
--- a/pipelines/fabric/src/main/resources/include/checksum.p4
+++ b/pipelines/fabric/src/main/resources/include/checksum.p4
@@ -43,7 +43,8 @@
HashAlgorithm.csum16
);
#ifdef WITH_SPGW
- update_gtpu_checksum.apply(hdr.gtpu_ipv4);
+ update_gtpu_checksum.apply(hdr.gtpu_ipv4, hdr.gtpu_udp, hdr.gtpu,
+ hdr.ipv4, hdr.udp);
#endif // WITH_SPGW
}
}
diff --git a/pipelines/fabric/src/main/resources/include/define.p4 b/pipelines/fabric/src/main/resources/include/define.p4
index d3a7811..f4e5b56 100644
--- a/pipelines/fabric/src/main/resources/include/define.p4
+++ b/pipelines/fabric/src/main/resources/include/define.p4
@@ -63,6 +63,7 @@
#define ETH_HDR_SIZE 14
#define IPV4_HDR_SIZE 20
#define UDP_HDR_SIZE 8
+#define GTP_HDR_SIZE 8
#define UDP_PORT_GTPU 2152
#define GTP_GPDU 0xff
diff --git a/pipelines/fabric/src/main/resources/include/spgw.p4 b/pipelines/fabric/src/main/resources/include/spgw.p4
index ce39acb..22f68db 100644
--- a/pipelines/fabric/src/main/resources/include/spgw.p4
+++ b/pipelines/fabric/src/main/resources/include/spgw.p4
@@ -144,6 +144,7 @@
spgw_meta.do_spgw = true;
}
} else {
+ spgw_meta.direction = DIR_DOWNLINK;
if (ue_filter_table.apply().hit) {
spgw_meta.do_spgw = true;
}
@@ -192,7 +193,28 @@
) {
action gtpu_encap() {
- // GTPU
+ gtpu_ipv4.setValid();
+ gtpu_ipv4.version = IP_VERSION_4;
+ gtpu_ipv4.ihl = IPV4_MIN_IHL;
+ gtpu_ipv4.diffserv = 0;
+ gtpu_ipv4.total_len = (bit<16>) (std_meta.packet_length
+ - ETH_HDR_SIZE + IPV4_HDR_SIZE + UDP_HDR_SIZE + GTP_HDR_SIZE);
+ gtpu_ipv4.identification = 0x1513; /* From NGIC */
+ gtpu_ipv4.flags = 0;
+ gtpu_ipv4.frag_offset = 0;
+ gtpu_ipv4.ttl = DEFAULT_IPV4_TTL;
+ gtpu_ipv4.protocol = PROTO_UDP;
+ gtpu_ipv4.dst_addr = spgw_meta.dl_sess_enb_addr;
+ gtpu_ipv4.src_addr = spgw_meta.dl_sess_s1u_addr;
+ gtpu_ipv4.hdr_checksum = 0; // Updated later
+
+ gtpu_udp.setValid();
+ gtpu_udp.src_port = UDP_PORT_GTPU;
+ gtpu_udp.dst_port = UDP_PORT_GTPU;
+ gtpu_udp.len = (bit<16>) (std_meta.packet_length
+ - ETH_HDR_SIZE + UDP_HDR_SIZE + GTP_HDR_SIZE);
+ gtpu_udp.checksum = 0; // Updated later
+
gtpu.setValid();
gtpu.version = GTPU_VERSION;
gtpu.pt = GTP_PROTOCOL_TYPE_GTP;
@@ -203,28 +225,6 @@
gtpu.msgtype = GTP_GPDU;
gtpu.msglen = (bit<16>) (std_meta.packet_length - ETH_HDR_SIZE);
gtpu.teid = spgw_meta.dl_sess_teid;
- // Outer IPv4
- gtpu_ipv4.setValid();
- gtpu_ipv4.version = IP_VERSION_4;
- gtpu_ipv4.ihl = IPV4_MIN_IHL;
- gtpu_ipv4.diffserv = 0;
- gtpu_ipv4.total_len = (bit<16>) (std_meta.packet_length
- - ETH_HDR_SIZE + IPV4_HDR_SIZE + UDP_HDR_SIZE);
- gtpu_ipv4.identification = 0x1513; /* From NGIC */
- gtpu_ipv4.flags = 0;
- gtpu_ipv4.frag_offset = 0;
- gtpu_ipv4.ttl = DEFAULT_IPV4_TTL;
- gtpu_ipv4.protocol = PROTO_UDP;
- gtpu_ipv4.dst_addr = spgw_meta.dl_sess_enb_addr;
- gtpu_ipv4.src_addr = spgw_meta.dl_sess_s1u_addr;
- gtpu_ipv4.hdr_checksum = 0; /* Updated later */
- // Outer UDP
- gtpu_udp.setValid();
- gtpu_udp.src_port = UDP_PORT_GTPU;
- gtpu_udp.dst_port = UDP_PORT_GTPU;
- gtpu_udp.len = (bit<16>) (std_meta.packet_length
- - ETH_HDR_SIZE + UDP_HDR_SIZE);
- gtpu_udp.checksum = 0; /* Ignore, won't be updated */
}
apply {
@@ -235,7 +235,9 @@
}
-control verify_gtpu_checksum(inout ipv4_t gtpu_ipv4) {
+control verify_gtpu_checksum(
+ inout ipv4_t gtpu_ipv4
+ ) {
apply {
verify_checksum(gtpu_ipv4.isValid(),
{
@@ -258,7 +260,13 @@
}
-control update_gtpu_checksum(inout ipv4_t gtpu_ipv4) {
+control update_gtpu_checksum(
+ inout ipv4_t gtpu_ipv4,
+ inout udp_t gtpu_udp,
+ in gtpu_t gtpu,
+ in ipv4_t ipv4,
+ in udp_t udp
+ ) {
apply {
// Compute outer IPv4 checksum.
update_checksum(gtpu_ipv4.isValid(),
@@ -278,6 +286,27 @@
gtpu_ipv4.hdr_checksum,
HashAlgorithm.csum16
);
+
+ // Compute outer UDP checksum.
+ update_checksum_with_payload(gtpu_udp.isValid(),
+ {
+ gtpu_ipv4.src_addr,
+ gtpu_ipv4.dst_addr,
+ 8w0,
+ gtpu_ipv4.protocol,
+ gtpu_udp.len,
+ gtpu_udp.src_port,
+ gtpu_udp.dst_port,
+ gtpu_udp.len,
+ gtpu,
+ ipv4,
+ // FIXME: we are assuming only UDP for downlink packets
+ // How to conditionally switch between UDP/TCP/ICMP?
+ udp
+ },
+ gtpu_udp.checksum,
+ HashAlgorithm.csum16
+ );
}
}