From 1e3fd573c9b89dd26adffa2f9e70b668f66d33e8 Mon Sep 17 00:00:00 2001 From: Junhua Zhai Date: Tue, 16 Jul 2024 12:39:49 +0000 Subject: [PATCH] Add flow state FSM --- dash-pipeline/bmv2/dash_metadata.p4 | 1 + dash-pipeline/bmv2/dash_parser.p4 | 24 ++++- dash-pipeline/bmv2/dash_pipeline.p4 | 28 +++--- dash-pipeline/bmv2/stages/conntrack_lookup.p4 | 91 ++++++++++++++++++- 4 files changed, 123 insertions(+), 21 deletions(-) diff --git a/dash-pipeline/bmv2/dash_metadata.p4 b/dash-pipeline/bmv2/dash_metadata.p4 index fbe329cb0..a92bf2b78 100644 --- a/dash-pipeline/bmv2/dash_metadata.p4 +++ b/dash-pipeline/bmv2/dash_metadata.p4 @@ -187,6 +187,7 @@ struct metadata_t { dash_flow_state_t flow_state; bit<16> bulk_get_session_id; bit<16> bulk_get_session_filter_id; + bool to_dpapp; #endif // DPAPP_CONNTRACK // Stage transition control diff --git a/dash-pipeline/bmv2/dash_parser.p4 b/dash-pipeline/bmv2/dash_parser.p4 index 3ff5652bf..b3797f51d 100644 --- a/dash-pipeline/bmv2/dash_parser.p4 +++ b/dash-pipeline/bmv2/dash_parser.p4 @@ -52,8 +52,28 @@ parser dash_parser( #ifdef DPAPP_CONNTRACK state parse_dash { packet.extract(hd.packet_meta); - // TODO extract flow_key, etc by checking packet type/subtype - packet.extract(hd.flow_key); + if (hd.packet_meta.packet_subtype != dash_packet_subtype_t.NONE) { + // Flow create/update/delete, extract flow_key + packet.extract(hd.flow_key); + } + + if (hd.packet_meta.packet_subtype == dash_packet_subtype_t.FLOW_DELETE) { + // Flow delete, extract flow_data ... + packet.extract(hd.flow_data); + + if (hd.flow_data.routing_actions != 0) { + packet.extract(hd.flow_overlay_data); + } + + if (hd.flow_data.routing_actions & dash_routing_actions_t.STATIC_ENCAP != 0) { + packet.extract(hd.flow_encap_data); + } + + if (hd.flow_data.tunnel_id != 0) { + packet.extract(hd.flow_tunnel_data); + } + } + transition parse_customer_ethernet; } #endif // DPAPP_CONNTRACK diff --git a/dash-pipeline/bmv2/dash_pipeline.p4 b/dash-pipeline/bmv2/dash_pipeline.p4 index 19f110514..a4b3a536a 100644 --- a/dash-pipeline/bmv2/dash_pipeline.p4 +++ b/dash-pipeline/bmv2/dash_pipeline.p4 @@ -363,7 +363,8 @@ control dash_ingress( ha_stage.apply(hdr, meta); #ifdef DPAPP_CONNTRACK - if (meta.flow_state == dash_flow_state_t.FLOW_MISS) { + if (meta.flow_state == dash_flow_state_t.FLOW_MISS && + hdr.packet_meta.packet_source == dash_packet_source_t.EXTERNAL) { #endif // DPAPP_CONNTRACK acl_group.apply(); @@ -380,13 +381,19 @@ control dash_ingress( tunnel_stage.apply(hdr, meta); + if (meta.dropped) { + drop_action(); + return; + } + #ifdef DPAPP_CONNTRACK - if (!meta.dropped) { - conntrack_set_flow_data.apply(hdr, meta); + } + + conntrack_flow_handle.apply(hdr, meta); + if (meta.to_dpapp) { standard_metadata.egress_spec = 2; // vpp port return; } - } #endif // DPAPP_CONNTRACK routing_action_apply.apply(hdr, meta); @@ -424,19 +431,6 @@ control dash_ingress( UPDATE_ENI_COUNTER(eni_inbound_tx); } } - -#ifdef DPAPP_CONNTRACK - // Drop dash header in fast path - if (meta.flow_state == dash_flow_state_t.FLOW_CREATED) { - hdr.dp_ethernet.setInvalid(); - hdr.packet_meta.setInvalid(); - hdr.flow_key.setInvalid(); - hdr.flow_data.setInvalid(); - hdr.flow_overlay_data.setInvalid(); - hdr.flow_encap_data.setInvalid(); - hdr.flow_tunnel_data.setInvalid(); - } -#endif // DPAPP_CONNTRACK } } diff --git a/dash-pipeline/bmv2/stages/conntrack_lookup.p4 b/dash-pipeline/bmv2/stages/conntrack_lookup.p4 index 4907c73c9..cb8714643 100644 --- a/dash-pipeline/bmv2/stages/conntrack_lookup.p4 +++ b/dash-pipeline/bmv2/stages/conntrack_lookup.p4 @@ -4,7 +4,37 @@ #ifdef DPAPP_CONNTRACK #include "../dash_metadata.p4" -control conntrack_set_flow_data(inout headers_t hdr, inout metadata_t meta) +action conntrack_set_meta_from_dash_header(in headers_t hdr, out metadata_t meta) +{ + /* basic metadata */ + meta.direction = hdr.flow_data.direction; + meta.dash_tunnel_id = hdr.flow_data.tunnel_id; + meta.routing_actions = hdr.flow_data.routing_actions; + meta.meter_class = hdr.flow_data.meter_class; + + /* encapsulation metadata */ + meta.encap_data = hdr.flow_encap_data; + + /* tunnel metadata */ + meta.tunnel_data = hdr.flow_tunnel_data; + + /* overlay rewrite metadata */ + meta.overlay_data = hdr.flow_overlay_data; +} + +action conntrack_strip_dash_header(inout headers_t hdr) +{ + hdr.dp_ethernet.setInvalid(); + hdr.packet_meta.setInvalid(); + hdr.flow_key.setInvalid(); + hdr.flow_data.setInvalid(); + hdr.flow_overlay_data.setInvalid(); + hdr.flow_encap_data.setInvalid(); + hdr.flow_tunnel_data.setInvalid(); +} + +control conntrack_build_dash_header(inout headers_t hdr, in metadata_t meta, + dash_packet_subtype_t packet_subtype) { apply { bit<16> length = 0; @@ -38,7 +68,7 @@ control conntrack_set_flow_data(inout headers_t hdr, inout metadata_t meta) hdr.packet_meta.setValid(); hdr.packet_meta.packet_source = dash_packet_source_t.PIPELINE; hdr.packet_meta.packet_type = dash_packet_type_t.REGULAR; - hdr.packet_meta.packet_subtype = dash_packet_subtype_t.FLOW_CREATE; + hdr.packet_meta.packet_subtype = packet_subtype; hdr.packet_meta.length = length + PACKET_META_HDR_SIZE; hdr.dp_ethernet.setValid(); @@ -48,6 +78,63 @@ control conntrack_set_flow_data(inout headers_t hdr, inout metadata_t meta) } } +control conntrack_flow_miss_handle(inout headers_t hdr, inout metadata_t meta) +{ + apply { + if ((hdr.customer_tcp.isValid() && hdr.customer_tcp.flags == 0x2 /* SYN */) + || hdr.customer_udp.isValid()) { + conntrack_build_dash_header.apply(hdr, meta, dash_packet_subtype_t.FLOW_CREATE); + meta.to_dpapp = true; // trap to dpapp + return; + } + else if ((hdr.customer_tcp.flags & 0b000101 /* FIN/RST */) != 0 + && hdr.packet_meta.packet_source == dash_packet_source_t.DPAPP) { + /* Flow should be just deleted by dpapp */ + conntrack_set_meta_from_dash_header(hdr, meta); + return; + } + + // should not reach here + meta.dropped = true; // drop it + } +} + +control conntrack_flow_created_handle(inout headers_t hdr, inout metadata_t meta) +{ + apply { + if (hdr.customer_tcp.isValid()) { + if ((hdr.customer_tcp.flags & 0b000101 /* FIN/RST */) != 0) { + conntrack_build_dash_header.apply(hdr, meta, dash_packet_subtype_t.FLOW_DELETE); + meta.to_dpapp = true; // trap to dpapp + return; + } + } + + // TODO update flow timestamp for aging + } +} + + +control conntrack_flow_handle(inout headers_t hdr, inout metadata_t meta) +{ + apply { + switch (meta.flow_state) { + dash_flow_state_t.FLOW_MISS: { + conntrack_flow_miss_handle.apply(hdr, meta); + } + dash_flow_state_t.FLOW_CREATED: { + conntrack_flow_created_handle.apply(hdr, meta); + } + } + + // Drop dash header if not sending to dpapp + if (!meta.to_dpapp) { + conntrack_strip_dash_header(hdr); + } + } +} + + control conntrack_lookup_stage(inout headers_t hdr, inout metadata_t meta) { // // Flow table: