From 68ab61f4675a4cb81f8347a17daa68422db4572a Mon Sep 17 00:00:00 2001 From: Marian Pritsak Date: Fri, 27 Oct 2023 19:52:23 +0300 Subject: [PATCH] Refactor tunnels Signed-off-by: Marian Pritsak --- dash-pipeline/bmv2/dash_conntrack.p4 | 26 ++-- dash-pipeline/bmv2/dash_headers.p4 | 39 +++-- dash-pipeline/bmv2/dash_inbound.p4 | 17 ++- dash-pipeline/bmv2/dash_metadata.p4 | 1 + dash-pipeline/bmv2/dash_outbound.p4 | 66 +++----- dash-pipeline/bmv2/dash_parser.p4 | 134 ++++++++--------- dash-pipeline/bmv2/dash_pipeline.p4 | 63 ++++---- dash-pipeline/bmv2/dash_service_tunnel.p4 | 52 +++---- dash-pipeline/bmv2/dash_tunnel.p4 | 174 ++++++++++++++++++++++ 9 files changed, 370 insertions(+), 202 deletions(-) create mode 100644 dash-pipeline/bmv2/dash_tunnel.p4 diff --git a/dash-pipeline/bmv2/dash_conntrack.p4 b/dash-pipeline/bmv2/dash_conntrack.p4 index 09b43054f..3371f77fb 100644 --- a/dash-pipeline/bmv2/dash_conntrack.p4 +++ b/dash-pipeline/bmv2/dash_conntrack.p4 @@ -42,7 +42,7 @@ control ConntrackIn(inout headers_t hdr, action conntrackIn_allow (IPv4Address original_overlay_sip, IPv4Address original_overlay_dip) { /* Invalidate entry based on TCP flags */ // If FIN is 1 (0b000001), or if RST is 1 (0b000100): - if ((hdr.tcp.flags & 0b000101 /* FIN/RST */) != 0) { + if ((hdr.customer_tcp.flags & 0b000101 /* FIN/RST */) != 0) { set_entry_expire_time(EXPIRE_TIME_PROFILE_NOW); // New PNA extern /* set entry to be purged */ } @@ -54,7 +54,7 @@ control ConntrackIn(inout headers_t hdr, action conntrackIn_miss() { // TODO: Should this be ((hdr.tcp.flags & 0x2) != 0) instead? - if (hdr.tcp.flags == 0x2 /* SYN */) { + if (hdr.customer_tcp.flags == 0x2 /* SYN */) { if (meta.direction == dash_direction_t.OUTBOUND) { // New PNA Extern add_entry("conntrackIn_allow", @@ -67,14 +67,14 @@ control ConntrackIn(inout headers_t hdr, table conntrackIn { key = { - directionNeutralAddr(meta.direction, hdr.ipv4.src_addr, hdr.ipv4.dst_addr): + directionNeutralAddr(meta.direction, hdr.customer_ipv4.src_addr, hdr.customer_ipv4.dst_addr): exact @name("ipv4_addr1"); - directionNeutralAddr(meta.direction, hdr.ipv4.dst_addr, hdr.ipv4.src_addr): + directionNeutralAddr(meta.direction, hdr.customer_ipv4.dst_addr, hdr.customer_ipv4.src_addr): exact @name("ipv4_addr2"); - hdr.ipv4.protocol : exact; - directionNeutralPort(meta.direction, hdr.tcp.src_port, hdr.tcp.dst_port): + hdr.customer_ipv4.protocol : exact; + directionNeutralPort(meta.direction, hdr.customer_tcp.src_port, hdr.customer_tcp.dst_port): exact @name("tcp_port1"); - directionNeutralPort(meta.direction, hdr.tcp.dst_port, hdr.tcp.src_port): + directionNeutralPort(meta.direction, hdr.customer_tcp.dst_port, hdr.customer_tcp.src_port): exact @name("tcp_port2"); meta.eni_id : exact; } @@ -99,7 +99,7 @@ control ConntrackOut(inout headers_t hdr, action conntrackOut_allow () { /* Invalidate entry based on TCP flags */ // If FIN is 1 (0b000001), or if RST is 1 (0b000100): - if ((hdr.tcp.flags & 0b000101 /* FIN/RST */) != 0) { + if ((hdr.customer_tcp.flags & 0b000101 /* FIN/RST */) != 0) { set_entry_expire_time(EXPIRE_TIME_PROFILE_NOW); // New PNA extern /* set entry to be purged */ } @@ -109,7 +109,7 @@ control ConntrackOut(inout headers_t hdr, action conntrackOut_miss() { // TODO: Should this be ((hdr.tcp.flags & 0x2) != 0) instead? - if (hdr.tcp.flags == 0x2 /* SYN */) { + if (hdr.customer_tcp.flags == 0x2 /* SYN */) { if (meta.direction == dash_direction_t.INBOUND) { // New PNA Extern add_entry("conntrackOut_allow", {}, EXPIRE_TIME_PROFILE_LONG); @@ -120,14 +120,14 @@ control ConntrackOut(inout headers_t hdr, table conntrackOut { key = { - directionNeutralAddr(meta.direction, hdr.ipv4.src_addr, hdr.ipv4.dst_addr): + directionNeutralAddr(meta.direction, hdr.customer_ipv4.src_addr, hdr.customer_ipv4.dst_addr): exact @name("ipv4_addr1"); - directionNeutralAddr(meta.direction, hdr.ipv4.dst_addr, hdr.ipv4.src_addr): + directionNeutralAddr(meta.direction, hdr.customer_ipv4.dst_addr, hdr.customer_ipv4.src_addr): exact @name("ipv4_addr2"); hdr.ipv4.protocol : exact; - directionNeutralPort(meta.direction, hdr.tcp.src_port, hdr.tcp.dst_port): + directionNeutralPort(meta.direction, hdr.customer_tcp.src_port, hdr.customer_tcp.dst_port): exact @name("tcp_port1"); - directionNeutralPort(meta.direction, hdr.tcp.dst_port, hdr.tcp.src_port): + directionNeutralPort(meta.direction, hdr.customer_tcp.dst_port, hdr.customer_tcp.src_port): exact @name("tcp_port2"); meta.eni_id : exact; } diff --git a/dash-pipeline/bmv2/dash_headers.p4 b/dash-pipeline/bmv2/dash_headers.p4 index 7ac84b14b..60fc1d0f5 100644 --- a/dash-pipeline/bmv2/dash_headers.p4 +++ b/dash-pipeline/bmv2/dash_headers.p4 @@ -94,19 +94,32 @@ header ipv6_t { const bit<16> IPV6_HDR_SIZE=320/8; struct headers_t { - ethernet_t ethernet; - ipv4_t ipv4; - ipv4options_t ipv4options; - ipv6_t ipv6; - udp_t udp; - tcp_t tcp; - vxlan_t vxlan; - nvgre_t nvgre; - ethernet_t inner_ethernet; - ipv4_t inner_ipv4; - ipv6_t inner_ipv6; - udp_t inner_udp; - tcp_t inner_tcp; + /* Underlay 1 headers */ + ethernet_t u1_ethernet; + ipv4_t u1_ipv4; + ipv4options_t u1_ipv4options; + ipv6_t u1_ipv6; + udp_t u1_udp; + tcp_t u1_tcp; + vxlan_t u1_vxlan; + nvgre_t u1_nvgre; + + /* Underlay 0 headers */ + ethernet_t u0_ethernet; + ipv4_t u0_ipv4; + ipv4options_t u0_ipv4options; + ipv6_t u0_ipv6; + udp_t u0_udp; + tcp_t u0_tcp; + vxlan_t u0_vxlan; + nvgre_t u0_nvgre; + + /* Customer headers */ + ethernet_t customer_ethernet; + ipv4_t customer_ipv4; + ipv6_t customer_ipv6; + udp_t customer_udp; + tcp_t customer_tcp; } enum bit<16> dash_encapsulation_t { diff --git a/dash-pipeline/bmv2/dash_inbound.p4 b/dash-pipeline/bmv2/dash_inbound.p4 index 9e69f6097..15f89d247 100644 --- a/dash-pipeline/bmv2/dash_inbound.p4 +++ b/dash-pipeline/bmv2/dash_inbound.p4 @@ -3,7 +3,6 @@ #include "dash_headers.p4" #include "dash_service_tunnel.p4" -#include "dash_vxlan.p4" #include "dash_acl.p4" #include "dash_conntrack.p4" @@ -36,13 +35,15 @@ control inbound(inout headers_t hdr, ConntrackOut.apply(hdr, meta); #endif //PNA_CONNTRACK - vxlan_encap(hdr, - meta.encap_data.underlay_dmac, - meta.encap_data.underlay_smac, - meta.encap_data.underlay_dip, - meta.encap_data.underlay_sip, - hdr.ethernet.dst_addr, - meta.encap_data.vni); + tunnel_encap(hdr, + meta, + meta.encap_data.overlay_dmac, + meta.encap_data.underlay_dmac, + meta.encap_data.underlay_smac, + meta.encap_data.underlay_dip, + meta.encap_data.underlay_sip, + dash_encapsulation_t.VXLAN, + meta.encap_data.vni); } } diff --git a/dash-pipeline/bmv2/dash_metadata.p4 b/dash-pipeline/bmv2/dash_metadata.p4 index 78e31b26c..9d03f132b 100644 --- a/dash-pipeline/bmv2/dash_metadata.p4 +++ b/dash-pipeline/bmv2/dash_metadata.p4 @@ -71,6 +71,7 @@ struct metadata_t { bit<16> mapping_meter_class; bit<16> meter_class; bit<32> meter_bucket_index; + bit<16> tunnel_pointer; } #endif /* _SIRIUS_METADATA_P4_ */ diff --git a/dash-pipeline/bmv2/dash_outbound.p4 b/dash-pipeline/bmv2/dash_outbound.p4 index 7e14f7aee..f5fc5c94a 100644 --- a/dash-pipeline/bmv2/dash_outbound.p4 +++ b/dash-pipeline/bmv2/dash_outbound.p4 @@ -62,8 +62,8 @@ control outbound(inout headers_t hdr, /* assert(is_overlay_dip_v4_or_v6 == 1 && is_overlay_sip_v4_or_v6 == 1); assert(is_overlay_dip_mask_v4_or_v6 == 1 && is_overlay_sip_mask_v4_or_v6 == 1); assert(is_underlay_dip_v4_or_v6 != 1 && is_underlay_sip_v4_or_v6 != 1); */ - meta.encap_data.original_overlay_dip = hdr.ipv4.src_addr; - meta.encap_data.original_overlay_sip = hdr.ipv4.dst_addr; + meta.encap_data.original_overlay_dip = hdr.u0_ipv4.src_addr; + meta.encap_data.original_overlay_sip = hdr.u0_ipv4.dst_addr; service_tunnel_encode(hdr, overlay_dip, @@ -74,7 +74,7 @@ control outbound(inout headers_t hdr, /* encapsulation will be done in apply block based on dash_encapsulation */ meta.encap_data.underlay_dip = underlay_dip == 0 ? meta.encap_data.original_overlay_dip : (IPv4Address)underlay_dip; meta.encap_data.underlay_sip = underlay_sip == 0 ? meta.encap_data.original_overlay_sip : (IPv4Address)underlay_sip; - meta.encap_data.overlay_dmac = hdr.ethernet.dst_addr; + meta.encap_data.overlay_dmac = hdr.u0_ethernet.dst_addr; meta.encap_data.dash_encapsulation = dash_encapsulation; meta.encap_data.service_tunnel_key = tunnel_key; set_route_meter_attrs(meter_policy_en, meter_class); @@ -148,14 +148,14 @@ control outbound(inout headers_t hdr, bit<24> tunnel_key, bit<16> meter_class, bit<1> meter_class_override) { - meta.encap_data.overlay_dmac = hdr.ethernet.dst_addr; + meta.encap_data.overlay_dmac = hdr.u0_ethernet.dst_addr; meta.encap_data.dash_encapsulation = dash_encapsulation; meta.encap_data.vni = tunnel_key; service_tunnel_encode(hdr, overlay_dip, 0xffffffffffffffffffffffff, - (overlay_sip & ~meta.eni_data.pl_sip_mask) | meta.eni_data.pl_sip | (IPv6Address)hdr.ipv4.dst_addr, + (overlay_sip & ~meta.eni_data.pl_sip_mask) | meta.eni_data.pl_sip | (IPv6Address)hdr.u0_ipv4.dst_addr, 0xffffffffffffffffffffffff); set_tunnel(underlay_dip, @@ -247,46 +247,26 @@ control outbound(inout headers_t hdr, } } - if (meta.encap_data.dash_encapsulation == dash_encapsulation_t.VXLAN) { - vxlan_encap(hdr, - meta.encap_data.underlay_dmac, - meta.encap_data.underlay_smac, - meta.encap_data.underlay_dip, - meta.encap_data.underlay_sip, - meta.encap_data.overlay_dmac, - meta.encap_data.vni); - } else if (meta.encap_data.dash_encapsulation == dash_encapsulation_t.NVGRE) { - nvgre_encap(hdr, - meta.encap_data.underlay_dmac, - meta.encap_data.underlay_smac, - meta.encap_data.underlay_dip, - meta.encap_data.underlay_sip, - meta.encap_data.overlay_dmac, - meta.encap_data.vni); - } else { - drop(); - } + tunnel_encap(hdr, + meta, + meta.encap_data.overlay_dmac, + meta.encap_data.underlay_dmac, + meta.encap_data.underlay_smac, + meta.encap_data.underlay_dip, + meta.encap_data.underlay_sip, + meta.encap_data.dash_encapsulation, + meta.encap_data.vni); } route_service_tunnel: { - if (meta.encap_data.dash_encapsulation == dash_encapsulation_t.VXLAN) { - vxlan_encap(hdr, - meta.encap_data.underlay_dmac, - meta.encap_data.underlay_smac, - meta.encap_data.underlay_dip, - meta.encap_data.underlay_sip, - meta.encap_data.overlay_dmac, - meta.encap_data.service_tunnel_key); - } else if (meta.encap_data.dash_encapsulation == dash_encapsulation_t.NVGRE) { - nvgre_encap(hdr, - meta.encap_data.underlay_dmac, - meta.encap_data.underlay_smac, - meta.encap_data.underlay_dip, - meta.encap_data.underlay_sip, - meta.encap_data.overlay_dmac, - meta.encap_data.service_tunnel_key); - } else { - drop(); - } + tunnel_encap(hdr, + meta, + meta.encap_data.overlay_dmac, + meta.encap_data.underlay_dmac, + meta.encap_data.underlay_smac, + meta.encap_data.underlay_dip, + meta.encap_data.underlay_sip, + meta.encap_data.dash_encapsulation, + meta.encap_data.vni); } } } diff --git a/dash-pipeline/bmv2/dash_parser.p4 b/dash-pipeline/bmv2/dash_parser.p4 index 8e4d07ba2..d6eed01fc 100644 --- a/dash-pipeline/bmv2/dash_parser.p4 +++ b/dash-pipeline/bmv2/dash_parser.p4 @@ -29,101 +29,101 @@ parser dash_parser( ) { state start { - packet.extract(hd.ethernet); - transition select(hd.ethernet.ether_type) { - IPV4_ETHTYPE: parse_ipv4; - IPV6_ETHTYPE: parse_ipv6; + packet.extract(hd.u0_ethernet); + transition select(hd.u0_ethernet.ether_type) { + IPV4_ETHTYPE: parse_u0_ipv4; + IPV6_ETHTYPE: parse_u0_ipv6; default: accept; } } - state parse_ipv4 { - packet.extract(hd.ipv4); - verify(hd.ipv4.version == 4w4, error.IPv4IncorrectVersion); - verify(hd.ipv4.ihl >= 5, error.InvalidIPv4Header); - transition select (hd.ipv4.ihl) { - 5: dispatch_on_protocol; - default: parse_ipv4options; + state parse_u0_ipv4 { + packet.extract(hd.u0_ipv4); + verify(hd.u0_ipv4.version == 4w4, error.IPv4IncorrectVersion); + verify(hd.u0_ipv4.ihl >= 5, error.InvalidIPv4Header); + transition select (hd.u0_ipv4.ihl) { + 5: dispatch_on_u0_protocol; + default: parse_u0_ipv4options; } } - state parse_ipv4options { - packet.extract(hd.ipv4options, - (bit<32>)(((bit<16>)hd.ipv4.ihl - 5) * 32)); - transition dispatch_on_protocol; + state parse_u0_ipv4options { + packet.extract(hd.u0_ipv4options, + (bit<32>)(((bit<16>)hd.u0_ipv4.ihl - 5) * 32)); + transition dispatch_on_u0_protocol; } - state dispatch_on_protocol { - transition select(hd.ipv4.protocol) { - UDP_PROTO: parse_udp; - TCP_PROTO: parse_tcp; + state dispatch_on_u0_protocol { + transition select(hd.u0_ipv4.protocol) { + UDP_PROTO: parse_u0_udp; + TCP_PROTO: parse_u0_tcp; default: accept; } } - state parse_ipv6 { - packet.extract(hd.ipv6); - transition select(hd.ipv6.next_header) { - UDP_PROTO: parse_udp; - TCP_PROTO: parse_tcp; + state parse_u0_ipv6 { + packet.extract(hd.u0_ipv6); + transition select(hd.u0_ipv6.next_header) { + UDP_PROTO: parse_u0_udp; + TCP_PROTO: parse_u0_tcp; default: accept; } } - state parse_udp { - packet.extract(hd.udp); - transition select(hd.udp.dst_port) { - UDP_PORT_VXLAN: parse_vxlan; + state parse_u0_udp { + packet.extract(hd.u0_udp); + transition select(hd.u0_udp.dst_port) { + UDP_PORT_VXLAN: parse_u0_vxlan; default: accept; } } - state parse_tcp { - packet.extract(hd.tcp); + state parse_u0_tcp { + packet.extract(hd.u0_tcp); transition accept; } - state parse_vxlan { - packet.extract(hd.vxlan); - transition parse_inner_ethernet; + state parse_u0_vxlan { + packet.extract(hd.u0_vxlan); + transition parse_customer_ethernet; } - state parse_inner_ethernet { - packet.extract(hd.inner_ethernet); - transition select(hd.inner_ethernet.ether_type) { - IPV4_ETHTYPE: parse_inner_ipv4; - IPV6_ETHTYPE: parse_inner_ipv6; + state parse_customer_ethernet { + packet.extract(hd.customer_ethernet); + transition select(hd.customer_ethernet.ether_type) { + IPV4_ETHTYPE: parse_customer_ipv4; + IPV6_ETHTYPE: parse_customer_ipv6; default: accept; } } - state parse_inner_ipv4 { - packet.extract(hd.inner_ipv4); - verify(hd.inner_ipv4.version == 4w4, error.IPv4IncorrectVersion); - verify(hd.inner_ipv4.ihl == 4w5, error.IPv4OptionsNotSupported); - transition select(hd.inner_ipv4.protocol) { - UDP_PROTO: parse_inner_udp; - TCP_PROTO: parse_inner_tcp; + state parse_customer_ipv4 { + packet.extract(hd.customer_ipv4); + verify(hd.customer_ipv4.version == 4w4, error.IPv4IncorrectVersion); + verify(hd.customer_ipv4.ihl == 4w5, error.IPv4OptionsNotSupported); + transition select(hd.customer_ipv4.protocol) { + UDP_PROTO: parse_customer_udp; + TCP_PROTO: parse_customer_tcp; default: accept; } } - state parse_inner_ipv6 { - packet.extract(hd.inner_ipv6); - transition select(hd.inner_ipv6.next_header) { - UDP_PROTO: parse_inner_udp; - TCP_PROTO: parse_inner_tcp; + state parse_customer_ipv6 { + packet.extract(hd.customer_ipv6); + transition select(hd.customer_ipv6.next_header) { + UDP_PROTO: parse_customer_udp; + TCP_PROTO: parse_customer_tcp; default: accept; } } - state parse_inner_tcp { - packet.extract(hd.inner_tcp); + state parse_customer_tcp { + packet.extract(hd.customer_tcp); transition accept; } - state parse_inner_udp { - packet.extract(hd.inner_udp); + state parse_customer_udp { + packet.extract(hd.customer_udp); transition accept; } } @@ -138,19 +138,19 @@ control dash_deparser( ) { apply { - packet.emit(hdr.ethernet); - packet.emit(hdr.ipv4); - packet.emit(hdr.ipv4options); - packet.emit(hdr.ipv6); - packet.emit(hdr.udp); - packet.emit(hdr.tcp); - packet.emit(hdr.vxlan); - packet.emit(hdr.nvgre); - packet.emit(hdr.inner_ethernet); - packet.emit(hdr.inner_ipv4); - packet.emit(hdr.inner_ipv6); - packet.emit(hdr.inner_tcp); - packet.emit(hdr.inner_udp); + packet.emit(hdr.u0_ethernet); + packet.emit(hdr.u0_ipv4); + packet.emit(hdr.u0_ipv4options); + packet.emit(hdr.u0_ipv6); + packet.emit(hdr.u0_udp); + packet.emit(hdr.u0_tcp); + packet.emit(hdr.u0_vxlan); + packet.emit(hdr.u0_nvgre); + packet.emit(hdr.customer_ethernet); + packet.emit(hdr.customer_ipv4); + packet.emit(hdr.customer_ipv6); + packet.emit(hdr.customer_tcp); + packet.emit(hdr.customer_udp); } } diff --git a/dash-pipeline/bmv2/dash_pipeline.p4 b/dash-pipeline/bmv2/dash_pipeline.p4 index a39641ea0..aeeec5f52 100644 --- a/dash-pipeline/bmv2/dash_pipeline.p4 +++ b/dash-pipeline/bmv2/dash_pipeline.p4 @@ -4,8 +4,7 @@ #include "dash_headers.p4" #include "dash_metadata.p4" #include "dash_parser.p4" -#include "dash_vxlan.p4" -#include "dash_nvgre.p4" +#include "dash_tunnel.p4" #include "dash_outbound.p4" #include "dash_inbound.p4" #include "dash_conntrack.p4" @@ -42,7 +41,7 @@ control dash_ingress( @name("vip|dash_vip") table vip { key = { - hdr.ipv4.dst_addr : exact @name("hdr.ipv4.dst_addr:VIP"); + hdr.u0_ipv4.dst_addr : exact @name("hdr.u0_ipv4.dst_addr:VIP"); } actions = { @@ -64,7 +63,7 @@ control dash_ingress( @name("direction_lookup|dash_direction_lookup") table direction_lookup { key = { - hdr.vxlan.vni : exact @name("hdr.vxlan.vni:VNI"); + hdr.u0_vxlan.vni : exact @name("hdr.u0_vxlan.vni:VNI"); } actions = { @@ -207,7 +206,7 @@ control dash_ingress( action permit() { } - action vxlan_decap_pa_validate(bit<16> src_vnet_id) { + action tunnel_decap_pa_validate(bit<16> src_vnet_id) { meta.vnet_id = src_vnet_id; } @@ -215,7 +214,7 @@ control dash_ingress( table pa_validation { key = { meta.vnet_id: exact @name("meta.vnet_id:vnet_id"); - hdr.ipv4.src_addr : exact @name("hdr.ipv4.src_addr:sip"); + hdr.u0_ipv4.src_addr : exact @name("hdr.u0_ipv4.src_addr:sip"); } actions = { @@ -230,12 +229,12 @@ control dash_ingress( table inbound_routing { key = { meta.eni_id: exact @name("meta.eni_id:eni_id"); - hdr.vxlan.vni : exact @name("hdr.vxlan.vni:VNI"); - hdr.ipv4.src_addr : ternary @name("hdr.ipv4.src_addr:sip"); + hdr.u0_vxlan.vni : exact @name("hdr.u0_vxlan.vni:VNI"); + hdr.u0_ipv4.src_addr : ternary @name("hdr.u0_ipv4.src_addr:sip"); } actions = { - vxlan_decap(hdr); - vxlan_decap_pa_validate; + tunnel_decap(hdr, meta); + tunnel_decap_pa_validate; @defaultonly deny; } @@ -274,7 +273,7 @@ control dash_ingress( table meter_rule { key = { meta.meter_policy_id: exact @name("meta.meter_policy_id:meter_policy_id") @Sai[type="sai_object_id_t", isresourcetype="true", objects="METER_POLICY"]; - hdr.ipv4.dst_addr : ternary @name("hdr.ipv4.dst_addr:dip"); + hdr.u0_ipv4.dst_addr : ternary @name("hdr.ipv4.dst_addr:dip"); } actions = { @@ -370,7 +369,7 @@ control dash_ingress( if (vip.apply().hit) { /* Use the same VIP that was in packet's destination if it's present in the VIP table */ - meta.encap_data.underlay_sip = hdr.ipv4.dst_addr; + meta.encap_data.underlay_sip = hdr.u0_ipv4.dst_addr; } /* If Outer VNI matches with a reserved VNI, then the direction is Outbound - */ @@ -382,17 +381,17 @@ control dash_ingress( /* Put VM's MAC in the direction agnostic metadata field */ meta.eni_addr = meta.direction == dash_direction_t.OUTBOUND ? - hdr.inner_ethernet.src_addr : - hdr.inner_ethernet.dst_addr; + hdr.customer_ethernet.src_addr : + hdr.customer_ethernet.dst_addr; eni_ether_address_map.apply(); if (meta.direction == dash_direction_t.OUTBOUND) { - vxlan_decap(hdr); + tunnel_decap(hdr, meta); } else if (meta.direction == dash_direction_t.INBOUND) { switch (inbound_routing.apply().action_run) { - vxlan_decap_pa_validate: { + tunnel_decap_pa_validate: { pa_validation.apply(); - vxlan_decap(hdr); + tunnel_decap(hdr, meta); } } } @@ -403,23 +402,23 @@ control dash_ingress( meta.ip_protocol = 0; meta.dst_ip_addr = 0; meta.src_ip_addr = 0; - if (hdr.ipv6.isValid()) { - meta.ip_protocol = hdr.ipv6.next_header; - meta.src_ip_addr = hdr.ipv6.src_addr; - meta.dst_ip_addr = hdr.ipv6.dst_addr; + if (hdr.customer_ipv6.isValid()) { + meta.ip_protocol = hdr.customer_ipv6.next_header; + meta.src_ip_addr = hdr.customer_ipv6.src_addr; + meta.dst_ip_addr = hdr.customer_ipv6.dst_addr; meta.is_overlay_ip_v6 = 1; - } else if (hdr.ipv4.isValid()) { - meta.ip_protocol = hdr.ipv4.protocol; - meta.src_ip_addr = (bit<128>)hdr.ipv4.src_addr; - meta.dst_ip_addr = (bit<128>)hdr.ipv4.dst_addr; + } else if (hdr.customer_ipv4.isValid()) { + meta.ip_protocol = hdr.customer_ipv4.protocol; + meta.src_ip_addr = (bit<128>)hdr.customer_ipv4.src_addr; + meta.dst_ip_addr = (bit<128>)hdr.customer_ipv4.dst_addr; } - if (hdr.tcp.isValid()) { - meta.src_l4_port = hdr.tcp.src_port; - meta.dst_l4_port = hdr.tcp.dst_port; - } else if (hdr.udp.isValid()) { - meta.src_l4_port = hdr.udp.src_port; - meta.dst_l4_port = hdr.udp.dst_port; + if (hdr.customer_tcp.isValid()) { + meta.src_l4_port = hdr.customer_tcp.src_port; + meta.dst_l4_port = hdr.customer_tcp.dst_port; + } else if (hdr.customer_udp.isValid()) { + meta.src_l4_port = hdr.customer_udp.src_port; + meta.dst_l4_port = hdr.customer_udp.dst_port; } eni.apply(); @@ -436,7 +435,7 @@ control dash_ingress( } /* Underlay routing */ - meta.dst_ip_addr = (bit<128>)hdr.ipv4.dst_addr; + meta.dst_ip_addr = (bit<128>)hdr.u0_ipv4.dst_addr; underlay.apply( hdr , meta diff --git a/dash-pipeline/bmv2/dash_service_tunnel.p4 b/dash-pipeline/bmv2/dash_service_tunnel.p4 index 6ab72fd2b..ba4161c1a 100644 --- a/dash-pipeline/bmv2/dash_service_tunnel.p4 +++ b/dash-pipeline/bmv2/dash_service_tunnel.p4 @@ -9,40 +9,40 @@ action service_tunnel_encode(inout headers_t hdr, in IPv6Address st_dst_mask, in IPv6Address st_src, in IPv6Address st_src_mask) { - hdr.ipv6.setValid(); - hdr.ipv6.version = 6; - hdr.ipv6.traffic_class = 0; - hdr.ipv6.flow_label = 0; - hdr.ipv6.payload_length = hdr.ipv4.total_len - IPV4_HDR_SIZE; - hdr.ipv6.next_header = hdr.ipv4.protocol; - hdr.ipv6.hop_limit = hdr.ipv4.ttl; - hdr.ipv6.dst_addr = ((IPv6Address)hdr.ipv4.dst_addr & ~st_dst_mask) | (st_dst & st_dst_mask); - hdr.ipv6.src_addr = ((IPv6Address)hdr.ipv4.src_addr & ~st_src_mask) | (st_src & st_src_mask); + hdr.u0_ipv6.setValid(); + hdr.u0_ipv6.version = 6; + hdr.u0_ipv6.traffic_class = 0; + hdr.u0_ipv6.flow_label = 0; + hdr.u0_ipv6.payload_length = hdr.u0_ipv4.total_len - IPV4_HDR_SIZE; + hdr.u0_ipv6.next_header = hdr.u0_ipv4.protocol; + hdr.u0_ipv6.hop_limit = hdr.u0_ipv4.ttl; + hdr.u0_ipv6.dst_addr = ((IPv6Address)hdr.u0_ipv4.dst_addr & ~st_dst_mask) | (st_dst & st_dst_mask); + hdr.u0_ipv6.src_addr = ((IPv6Address)hdr.u0_ipv4.src_addr & ~st_src_mask) | (st_src & st_src_mask); - hdr.ipv4.setInvalid(); - hdr.ethernet.ether_type = IPV6_ETHTYPE; + hdr.u0_ipv4.setInvalid(); + hdr.u0_ethernet.ether_type = IPV6_ETHTYPE; } /* Decodes V4 from V6 */ action service_tunnel_decode(inout headers_t hdr, in IPv4Address src, in IPv4Address dst) { - hdr.ipv4.setValid(); - hdr.ipv4.version = 4; - hdr.ipv4.ihl = 5; - hdr.ipv4.diffserv = 0; - hdr.ipv4.total_len = hdr.ipv6.payload_length + IPV4_HDR_SIZE; - hdr.ipv4.identification = 1; - hdr.ipv4.flags = 0; - hdr.ipv4.frag_offset = 0; - hdr.ipv4.protocol = hdr.ipv6.next_header; - hdr.ipv4.ttl = hdr.ipv6.hop_limit; - hdr.ipv4.hdr_checksum = 0; - hdr.ipv4.dst_addr = dst; - hdr.ipv4.src_addr = src; + hdr.u0_ipv4.setValid(); + hdr.u0_ipv4.version = 4; + hdr.u0_ipv4.ihl = 5; + hdr.u0_ipv4.diffserv = 0; + hdr.u0_ipv4.total_len = hdr.u0_ipv6.payload_length + IPV4_HDR_SIZE; + hdr.u0_ipv4.identification = 1; + hdr.u0_ipv4.flags = 0; + hdr.u0_ipv4.frag_offset = 0; + hdr.u0_ipv4.protocol = hdr.u0_ipv6.next_header; + hdr.u0_ipv4.ttl = hdr.u0_ipv6.hop_limit; + hdr.u0_ipv4.hdr_checksum = 0; + hdr.u0_ipv4.dst_addr = dst; + hdr.u0_ipv4.src_addr = src; - hdr.ipv6.setInvalid(); - hdr.ethernet.ether_type = IPV4_ETHTYPE; + hdr.u0_ipv6.setInvalid(); + hdr.u0_ethernet.ether_type = IPV4_ETHTYPE; } #endif /* _SIRIUS_SERVICE_TUNNEL_P4_ */ diff --git a/dash-pipeline/bmv2/dash_tunnel.p4 b/dash-pipeline/bmv2/dash_tunnel.p4 new file mode 100644 index 000000000..d1a2cd749 --- /dev/null +++ b/dash-pipeline/bmv2/dash_tunnel.p4 @@ -0,0 +1,174 @@ +#ifndef _DASH_TUNNEL_P4_ +#define _DASH_TUNNEL_P4_ + +#include "dash_headers.p4" + +#define PUSH_VXLAN_TUNNEL_DEF(underlay_id, overlay_id) \ +action push_vxlan_tunnel_ ## underlay_id ## (inout headers_t hdr, \ + in EthernetAddress overlay_dmac, \ + in EthernetAddress underlay_dmac, \ + in EthernetAddress underlay_smac, \ + in IPv4Address underlay_dip, \ + in IPv4Address underlay_sip, \ + in bit<24> tunnel_key) { \ + hdr. ## overlay_id ## _ethernet.dst_addr = overlay_dmac; \ + hdr. ## underlay_id ## _ethernet.setValid(); \ + hdr. ## underlay_id ## _ethernet.dst_addr = underlay_dmac; \ + hdr. ## underlay_id ## _ethernet.src_addr = underlay_smac; \ + hdr. ## underlay_id ## _ethernet.ether_type = IPV4_ETHTYPE; \ + \ + hdr. ## underlay_id ## _ipv4.setValid(); \ + hdr. ## underlay_id ## _ipv4.total_len = hdr. ## overlay_id ## _ipv4.total_len*(bit<16>)(bit<1>)hdr. ## overlay_id ## _ipv4.isValid() + \ + hdr. ## overlay_id ## _ipv6.payload_length*(bit<16>)(bit<1>)hdr. ## overlay_id ## _ipv6.isValid() + \ + IPV6_HDR_SIZE*(bit<16>)(bit<1>)hdr. ## overlay_id ## _ipv6.isValid() + \ + ETHER_HDR_SIZE + \ + IPV4_HDR_SIZE + \ + UDP_HDR_SIZE + \ + VXLAN_HDR_SIZE; \ + hdr. ## underlay_id ## _ipv4.version = 4; \ + hdr. ## underlay_id ## _ipv4.ihl = 5; \ + hdr. ## underlay_id ## _ipv4.diffserv = 0; \ + hdr. ## underlay_id ## _ipv4.identification = 1; \ + hdr. ## underlay_id ## _ipv4.flags = 0; \ + hdr. ## underlay_id ## _ipv4.frag_offset = 0; \ + hdr. ## underlay_id ## _ipv4.ttl = 64; \ + hdr. ## underlay_id ## _ipv4.protocol = UDP_PROTO; \ + hdr. ## underlay_id ## _ipv4.dst_addr = underlay_dip; \ + hdr. ## underlay_id ## _ipv4.src_addr = underlay_sip; \ + hdr. ## underlay_id ## _ipv4.hdr_checksum = 0; \ + \ + hdr. ## underlay_id ## _udp.setValid(); \ + hdr. ## underlay_id ## _udp.src_port = 0; \ + hdr. ## underlay_id ## _udp.dst_port = UDP_PORT_VXLAN; \ + hdr. ## underlay_id ## _udp.length = hdr.inner_ipv4.total_len*(bit<16>)(bit<1>)hdr.inner_ipv4.isValid() + \ + hdr.inner_ipv6.payload_length*(bit<16>)(bit<1>)hdr.inner_ipv6.isValid() + \ + IPV6_HDR_SIZE*(bit<16>)(bit<1>)hdr.inner_ipv6.isValid() + \ + UDP_HDR_SIZE + \ + VXLAN_HDR_SIZE + \ + ETHER_HDR_SIZE; \ + hdr. ## underlay_id ## _udp.checksum = 0; \ + \ + hdr. ## underlay_id ## _vxlan.setValid(); \ + hdr. ## underlay_id ## _vxlan.reserved = 0; \ + hdr. ## underlay_id ## _vxlan.reserved_2 = 0; \ + hdr. ## underlay_id ## _vxlan.flags = 0; \ + hdr. ## underlay_id ## _vxlan.vni = tunnel_key; \ +} + +#define PUSH_NVGRE_TUNNEL_DEF(underlay_id, overlay_id) \ +action push_nvgre_tunnel_ ## underlay_id ## (inout headers_t hdr, \ + in EthernetAddress overlay_dmac, \ + in EthernetAddress underlay_dmac, \ + in EthernetAddress underlay_smac, \ + in IPv4Address underlay_dip, \ + in IPv4Address underlay_sip, \ + in bit<24> tunnel_key) { \ + hdr. ## overlay_id ## _ethernet.dst_addr = overlay_dmac; \ + hdr. ## underlay_id ## _ethernet.setValid(); \ + hdr. ## underlay_id ## _ethernet.dst_addr = underlay_dmac; \ + hdr. ## underlay_id ## _ethernet.src_addr = underlay_smac; \ + hdr. ## underlay_id ## _ethernet.ether_type = IPV4_ETHTYPE; \ + \ + hdr. ## underlay_id ## _ipv4.setValid(); \ + hdr. ## underlay_id ## _ipv4.total_len = hdr. ## overlay_id ## _ipv4.total_len*(bit<16>)(bit<1>)hdr. ## overlay_id ## _ipv4.isValid() + \ + hdr. ## overlay_id ## _ipv6.payload_length*(bit<16>)(bit<1>)hdr. ## overlay_id ## _ipv6.isValid() + \ + IPV6_HDR_SIZE*(bit<16>)(bit<1>)hdr. ## overlay_id ## _ipv6.isValid() + \ + ETHER_HDR_SIZE + \ + IPV4_HDR_SIZE + \ + UDP_HDR_SIZE + \ + VXLAN_HDR_SIZE; \ + hdr. ## underlay_id ## _ipv4.total_len = (ETHER_HDR_SIZE + IPV4_HDR_SIZE + \ + NVGRE_HDR_SIZE + hdr. ## underlay_id ## _ipv4.total_len); \ + hdr. ## underlay_id ## _ipv4.version = 4; \ + hdr. ## underlay_id ## _ipv4.ihl = 5; \ + hdr. ## underlay_id ## _ipv4.diffserv = 0; \ + hdr. ## underlay_id ## _ipv4.identification = 1; \ + hdr. ## underlay_id ## _ipv4.flags = 0; \ + hdr. ## underlay_id ## _ipv4.frag_offset = 0; \ + hdr. ## underlay_id ## _ipv4.ttl = 64; \ + hdr. ## underlay_id ## _ipv4.protocol = NVGRE_PROTO; \ + hdr. ## underlay_id ## _ipv4.dst_addr = underlay_dip; \ + hdr. ## underlay_id ## _ipv4.src_addr = underlay_sip; \ + hdr. ## underlay_id ## _ipv4.hdr_checksum = 0; \ + \ + hdr. ## underlay_id ## _nvgre.setValid(); \ + hdr. ## underlay_id ## _nvgre.flags = 4; \ + hdr. ## underlay_id ## _nvgre.reserved = 0; \ + hdr. ## underlay_id ## _nvgre.version = 0; \ + hdr. ## underlay_id ## _nvgre.protocol_type = 0x6558; \ + hdr. ## underlay_id ## _nvgre.vsid = tunnel_key; \ + hdr. ## underlay_id ## _nvgre.flow_id = 0; \ +} + +PUSH_VXLAN_TUNNEL_DEF(u0, customer) +PUSH_VXLAN_TUNNEL_DEF(u1, u0) +PUSH_NVGRE_TUNNEL_DEF(u0, customer) +PUSH_NVGRE_TUNNEL_DEF(u1, u0) + +#define tunnel_encap(hdr, \ + meta, \ + overlay_dmac, \ + underlay_dmac, \ + underlay_smac, \ + underlay_dip, \ + underlay_sip, \ + dash_encapsulation, \ + tunnel_key) { \ + if (dash_encapsulation == dash_encapsulation_t.VXLAN) { \ + if (meta.tunnel_pointer == 0) { \ + push_vxlan_tunnel_u0(hdr, \ + overlay_dmac, \ + underlay_dmac, \ + underlay_smac, \ + underlay_dip, \ + underlay_sip, \ + tunnel_key); \ + } else if (meta.tunnel_pointer == 0) { \ + push_vxlan_tunnel_u1(hdr, \ + overlay_dmac, \ + underlay_dmac, \ + underlay_smac, \ + underlay_dip, \ + underlay_sip, \ + tunnel_key); \ + } \ + } else if (dash_encapsulation == dash_encapsulation_t.NVGRE) { \ + if (meta.tunnel_pointer == 0) { \ + push_vxlan_tunnel_u0(hdr, \ + overlay_dmac, \ + underlay_dmac, \ + underlay_smac, \ + underlay_dip, \ + underlay_sip, \ + tunnel_key); \ + } else if (meta.tunnel_pointer == 0) { \ + push_vxlan_tunnel_u1(hdr, \ + overlay_dmac, \ + underlay_dmac, \ + underlay_smac, \ + underlay_dip, \ + underlay_sip, \ + tunnel_key); \ + } \ + } \ + \ + meta.tunnel_pointer = meta.tunnel_pointer + 1; \ +} + +/* Tunnel decap can only pop u0 because that's what was parsed. + If the packet has more than one tunnel on ingress, BM will + reparse it. + It is also assumed, that if DASH pushes more than one tunnel, + they won't need to pop them */ +action tunnel_decap(inout headers_t hdr, inout metadata_t meta) { + hdr.u0_ethernet.setInvalid(); + hdr.u0_ipv4.setInvalid(); + hdr.u0_ipv6.setInvalid(); + hdr.u0_nvgre.setInvalid(); + hdr.u0_vxlan.setInvalid(); + hdr.u0_udp.setInvalid(); + + meta.tunnel_pointer = 0; +} + +#endif /* _DASH_TUNNEL_P4_ */