Backport fabric-tna dbuf support to v1model
Change-Id: I6a957d2474e94e1dcb7c3f598033ff243754372f
diff --git a/pipelines/fabric/impl/src/main/resources/include/control/spgw.p4 b/pipelines/fabric/impl/src/main/resources/include/control/spgw.p4
index 34a88b8..10c4467 100644
--- a/pipelines/fabric/impl/src/main/resources/include/control/spgw.p4
+++ b/pipelines/fabric/impl/src/main/resources/include/control/spgw.p4
@@ -30,13 +30,86 @@
#define MAX_PDR_COUNTERS 2 * MAX_UES
#define MAX_FARS 2 * MAX_UES
+control DecapGtpu(inout parsed_headers_t hdr,
+ inout fabric_metadata_t fabric_md) {
+ @hidden
+ action decap_inner_common() {
+ // Correct parser-set metadata to use the inner header values
+ fabric_md.ip_eth_type = ETHERTYPE_IPV4;
+ fabric_md.ip_proto = hdr.inner_ipv4.protocol;
+ fabric_md.ipv4_src_addr = hdr.inner_ipv4.src_addr;
+ fabric_md.ipv4_dst_addr = hdr.inner_ipv4.dst_addr;
+ fabric_md.l4_sport = fabric_md.inner_l4_sport;
+ fabric_md.l4_dport = fabric_md.inner_l4_dport;
+ // Move GTPU and inner L3 headers out
+ hdr.ipv4 = hdr.inner_ipv4;
+ hdr.inner_ipv4.setInvalid();
+ hdr.gtpu.setInvalid();
+ }
+ @hidden
+ action decap_inner_tcp() {
+ decap_inner_common();
+ hdr.udp.setInvalid();
+ hdr.tcp = hdr.inner_tcp;
+ hdr.inner_tcp.setInvalid();
+ }
+ @hidden
+ action decap_inner_udp() {
+ decap_inner_common();
+ hdr.udp = hdr.inner_udp;
+ hdr.inner_udp.setInvalid();
+ }
+ @hidden
+ action decap_inner_icmp() {
+ decap_inner_common();
+ hdr.udp.setInvalid();
+ hdr.icmp = hdr.inner_icmp;
+ hdr.inner_icmp.setInvalid();
+ }
+ @hidden
+ action decap_inner_unknown() {
+ decap_inner_common();
+ hdr.udp.setInvalid();
+ }
+ @hidden
+ table decap_gtpu {
+ key = {
+ hdr.inner_tcp.isValid() : exact;
+ hdr.inner_udp.isValid() : exact;
+ hdr.inner_icmp.isValid() : exact;
+ }
+ actions = {
+ decap_inner_tcp;
+ decap_inner_udp;
+ decap_inner_icmp;
+ decap_inner_unknown;
+ }
+ const default_action = decap_inner_unknown;
+ const entries = {
+ (true, false, false) : decap_inner_tcp();
+ (false, true, false) : decap_inner_udp();
+ (false, false, true) : decap_inner_icmp();
+ }
+ size = 4;
+ }
+ apply {
+ decap_gtpu.apply();
+ }
+}
control SpgwIngress(inout parsed_headers_t hdr,
inout fabric_metadata_t fabric_md,
inout standard_metadata_t standard_metadata) {
+ //=============================//
+ //===== Misc Things ======//
+ //=============================//
+
+ counter(MAX_PDR_COUNTERS, CounterType.packets_and_bytes) pdr_counter;
+ DecapGtpu() decap_gtpu_from_dbuf;
+ DecapGtpu() decap_gtpu;
//=============================//
@@ -135,7 +208,8 @@
action load_normal_far_attributes(bit<1> drop,
bit<1> notify_cp) {
// general far attributes
- fabric_md.spgw.far_dropped = (_BOOL)drop;
+ fabric_md.skip_forwarding = (_BOOL)drop;
+ fabric_md.skip_next = (_BOOL)drop;
fabric_md.spgw.notify_spgwc = (_BOOL)notify_cp;
}
action load_tunnel_far_attributes(bit<1> drop,
@@ -145,7 +219,8 @@
bit<32> tunnel_dst_addr,
teid_t teid) {
// general far attributes
- fabric_md.spgw.far_dropped = (_BOOL)drop;
+ fabric_md.skip_forwarding = (_BOOL)drop;
+ fabric_md.skip_next = (_BOOL)drop;
fabric_md.spgw.notify_spgwc = (_BOOL)notify_cp;
// GTP tunnel attributes
fabric_md.spgw.needs_gtpu_encap = _TRUE;
@@ -160,6 +235,17 @@
fabric_md.l4_dport = UDP_PORT_GTPU;
}
+ action load_dbuf_far_attributes(bit<1> drop,
+ bit<1> notify_cp,
+ bit<16> tunnel_src_port,
+ bit<32> tunnel_src_addr,
+ bit<32> tunnel_dst_addr,
+ teid_t teid) {
+ load_tunnel_far_attributes(drop, notify_cp, tunnel_src_port,
+ tunnel_src_addr, tunnel_dst_addr, teid);
+ fabric_md.spgw.skip_egress_pdr_ctr = _TRUE;
+ }
+
table far_lookup {
key = {
fabric_md.spgw.far_id : exact @name("far_id");
@@ -167,74 +253,13 @@
actions = {
load_normal_far_attributes;
load_tunnel_far_attributes;
+ load_dbuf_far_attributes;
}
// default is drop and don't notify CP
- const default_action = load_normal_far_attributes(1, 1);
+ const default_action = load_normal_far_attributes(1, 0);
size = MAX_FARS;
}
- //=============================//
- //===== Misc Things ======//
- //=============================//
-
- counter(MAX_PDR_COUNTERS, CounterType.packets_and_bytes) pdr_counter;
-
-
- @hidden
- action decap_inner_common() {
- // Correct parser-set metadata to use the inner header values
- fabric_md.ip_eth_type = ETHERTYPE_IPV4;
- fabric_md.ip_proto = hdr.inner_ipv4.protocol;
- fabric_md.ipv4_src_addr = hdr.inner_ipv4.src_addr;
- fabric_md.ipv4_dst_addr = hdr.inner_ipv4.dst_addr;
- fabric_md.l4_sport = fabric_md.inner_l4_sport;
- fabric_md.l4_dport = fabric_md.inner_l4_dport;
- // Move GTPU and inner L3 headers out
- hdr.ipv4 = hdr.inner_ipv4;
- hdr.inner_ipv4.setInvalid();
- hdr.gtpu.setInvalid();
- }
- action decap_inner_tcp() {
- decap_inner_common();
- hdr.udp.setInvalid();
- hdr.tcp = hdr.inner_tcp;
- hdr.inner_tcp.setInvalid();
- }
- action decap_inner_udp() {
- decap_inner_common();
- hdr.udp = hdr.inner_udp;
- hdr.inner_udp.setInvalid();
- }
- action decap_inner_icmp() {
- decap_inner_common();
- hdr.udp.setInvalid();
- hdr.icmp = hdr.inner_icmp;
- hdr.inner_icmp.setInvalid();
- }
- action decap_inner_unknown() {
- decap_inner_common();
- hdr.udp.setInvalid();
- }
- @hidden
- table decap_gtpu {
- key = {
- hdr.inner_tcp.isValid() : exact;
- hdr.inner_udp.isValid() : exact;
- hdr.inner_icmp.isValid() : exact;
- }
- actions = {
- decap_inner_tcp;
- decap_inner_udp;
- decap_inner_icmp;
- decap_inner_unknown;
- }
- const default_action = decap_inner_unknown;
- const entries = {
- (true, false, false) : decap_inner_tcp();
- (false, true, false) : decap_inner_udp();
- (false, false, true) : decap_inner_icmp();
- }
- }
//=============================//
@@ -243,50 +268,36 @@
apply {
// Interfaces
- interface_lookup.apply();
+ if (interface_lookup.apply().hit) {
+ if (fabric_md.spgw.src_iface == SPGW_IFACE_FROM_DBUF) {
+ decap_gtpu_from_dbuf.apply(hdr, fabric_md);
+ }
+ // PDRs
+ if (hdr.gtpu.isValid()) {
+ uplink_pdr_lookup.apply();
+ } else {
+ downlink_pdr_lookup.apply();
+ }
+ if (fabric_md.spgw.src_iface != SPGW_IFACE_FROM_DBUF) {
+ pdr_counter.count(fabric_md.spgw.ctr_id);
+ }
- // If interface table missed, or the interface skips PDRs/FARs (TODO: is that a thing?)
- if (fabric_md.spgw.skip_spgw == _TRUE) return;
+ // GTPU Decapsulate
+ if (fabric_md.spgw.needs_gtpu_decap == _TRUE) {
+ decap_gtpu.apply(hdr, fabric_md);
+ }
- // PDRs
- // Currently only best-case PDR tables to make v1model-to-tofino compiler happy
- if (hdr.gtpu.isValid()) {
- uplink_pdr_lookup.apply();
- } else {
- downlink_pdr_lookup.apply();
+ // FARs
+ // Load FAR info
+ far_lookup.apply();
+
+ // Nothing to be done immediately for forwarding or encapsulation.
+ // Forwarding is done by other parts of fabric.p4, and
+ // encapsulation is done in the egress
+
+ // Needed for correct GTPU encapsulation in egress
+ fabric_md.spgw.ipv4_len = hdr.ipv4.total_len;
}
- // Inefficient PDR table if efficient tables missed
- // Removed to make v1model-to-tofino compiler happy. Not removed in TNA port
- //if (fabric_md.spgw.pdr_hit == _FALSE) {
- // flexible_pdr_lookup.apply();
- //}
- pdr_counter.count(fabric_md.spgw.ctr_id);
-
- // GTPU Decapsulate
- if (fabric_md.spgw.needs_gtpu_decap == _TRUE) {
- decap_gtpu.apply();
- }
-
- // FARs
- // Load FAR info
- far_lookup.apply();
-
- if (fabric_md.spgw.notify_spgwc == _TRUE) {
- // TODO: cpu clone action here
- }
- if (fabric_md.spgw.far_dropped == _TRUE) {
- // Do dropping in the same way as fabric's filtering.p4, so we can traverse
- // the ACL table, which is good for cases like DHCP.
- fabric_md.skip_forwarding = _TRUE;
- fabric_md.skip_next = _TRUE;
- }
-
- // Nothing to be done immediately for forwarding or encapsulation.
- // Forwarding is done by other parts of fabric.p4, and
- // encapsulation is done in the egress
-
- // Needed for correct GTPU encapsulation in egress
- fabric_md.spgw.ipv4_len = hdr.ipv4.total_len;
}
}
@@ -340,11 +351,13 @@
}
apply {
- if (fabric_md.spgw.skip_spgw == _TRUE) return;
- pdr_counter.count(fabric_md.spgw.ctr_id);
-
- if (fabric_md.spgw.needs_gtpu_encap == _TRUE) {
- gtpu_encap();
+ if (fabric_md.spgw.skip_spgw == _FALSE) {
+ if (fabric_md.spgw.needs_gtpu_encap == _TRUE) {
+ gtpu_encap();
+ }
+ if (fabric_md.spgw.skip_egress_pdr_ctr == _FALSE) {
+ pdr_counter.count(fabric_md.spgw.ctr_id);
+ }
}
}
}