Skip to content

Commit

Permalink
[dash-p4] Add skeleton for matching stage transition control and extr…
Browse files Browse the repository at this point in the history
…act the matching stages in outbound pipeline into dedicated file. (#527)

## Problem 

Currently, the routing types in DASH is used to define 2 things: 

- Stage transition: which stage we need to run as the next stage
- Routing actions: what SDN transformations are required if this stage is the last stage used to match the packets.

Although the concepts are there, in DASH P4 code, these concepts are not reflected in a modularized way, and sometimes not that obvious as the transition cannot be found in the definitions of the routing types (P4 table actions).

## What this change is doing

This commit contains 2 changes inside:

- Add skeleton for matching stage transition control
- Extract the matching stages in outbound pipeline into dedicated file

These changes are intended to help with:

- Modularization and readability of the pipeline.
- Make the stage transition control more explicit and obvious.

This commit will not change any generated SAI APIs.
  • Loading branch information
r12f authored Feb 28, 2024
1 parent 477ce2d commit 1d1c89d
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 73 deletions.
19 changes: 19 additions & 0 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ enum bit<16> dash_direction_t {
INBOUND = 2
}

// Pipeline stages:
enum bit<16> dash_pipeline_stage_t {
INVALID = 0,

// Inbound stages
INBOUND_STAGE_START = 100,

// Outbound stages
OUTBOUND_STAGE_START = 200,
OUTBOUND_ROUTING = 200, // OUTBOUND_STAGE_START
OUTBOUND_MAPPING = 201,

// Common stages
ROUTING_ACTION_APPLY = 300
}

struct conntrack_data_t {
bool allow_in;
bool allow_out;
Expand Down Expand Up @@ -96,6 +112,9 @@ struct metadata_t {
bool is_fast_path_icmp_flow_redirection_packet;
bit<1> fast_path_icmp_flow_redirection_disabled;

// Stage transition control
dash_pipeline_stage_t target_stage;

// Actions
bit<32> routing_actions;

Expand Down
79 changes: 7 additions & 72 deletions dash-pipeline/bmv2/dash_outbound.p4
Original file line number Diff line number Diff line change
@@ -1,72 +1,15 @@
#ifndef _SIRIUS_OUTBOUND_P4_
#define _SIRIUS_OUTBOUND_P4_
#ifndef _DASH_OUTBOUND_P4_
#define _DASH_OUTBOUND_P4_

#include "dash_headers.p4"
#include "dash_acl.p4"
#include "dash_routing_types.p4"
#include "dash_conntrack.p4"
#include "stages/outbound_routing.p4"
#include "stages/outbound_mapping.p4"

control outbound(inout headers_t hdr,
inout metadata_t meta)
{
DEFINE_TABLE_COUNTER(routing_counter)

@SaiTable[name = "outbound_routing", api = "dash_outbound_routing"]
table routing {
key = {
meta.eni_id : exact @SaiVal[type="sai_object_id_t"];
meta.is_overlay_ip_v6 : exact @SaiVal[name = "destination_is_v6"];
meta.dst_ip_addr : lpm @SaiVal[name = "destination"];
}

actions = {
route_vnet(hdr, meta); /* for expressroute - ecmp of overlay */
route_vnet_direct(hdr, meta);
route_direct(hdr, meta);
route_service_tunnel(hdr, meta);
drop(meta);
}
const default_action = drop(meta);

ATTACH_TABLE_COUNTER(routing_counter)
}

DEFINE_TABLE_COUNTER(ca_to_pa_counter)

@SaiTable[name = "outbound_ca_to_pa", api = "dash_outbound_ca_to_pa"]
table ca_to_pa {
key = {
/* Flow for express route */
meta.dst_vnet_id: exact @SaiVal[type="sai_object_id_t"];
meta.is_lkup_dst_ip_v6 : exact @SaiVal[name = "dip_is_v6"];
meta.lkup_dst_ip_addr : exact @SaiVal[name = "dip"];
}

actions = {
set_tunnel_mapping(hdr, meta);
set_private_link_mapping(hdr, meta);
@defaultonly drop(meta);
}
const default_action = drop(meta);

ATTACH_TABLE_COUNTER(ca_to_pa_counter)
}

action set_vnet_attrs(bit<24> vni) {
meta.encap_data.vni = vni;
}

@SaiTable[name = "vnet", api = "dash_vnet", isobject="true"]
table vnet {
key = {
meta.vnet_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_vnet_attrs;
}
}

apply {
#ifdef STATEFUL_P4
ConntrackOut.apply(0);
Expand All @@ -92,17 +35,9 @@ control outbound(inout headers_t hdr,
meta.lkup_dst_ip_addr = meta.dst_ip_addr;
meta.is_lkup_dst_ip_v6 = meta.is_overlay_ip_v6;

switch (routing.apply().action_run) {
route_vnet_direct:
route_vnet: {
switch (ca_to_pa.apply().action_run) {
set_tunnel_mapping: {
vnet.apply();
}
}
}
}
outbound_routing_stage.apply(hdr, meta);
outbound_mapping_stage.apply(hdr, meta);
}
}

#endif /* _SIRIUS_OUTBOUND_P4_ */
#endif /* _DASH_OUTBOUND_P4_ */
2 changes: 1 addition & 1 deletion dash-pipeline/bmv2/dash_pipeline.p4
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,8 @@ control dash_ingress(

acl_group.apply();


if (meta.direction == dash_direction_t.OUTBOUND) {
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_ROUTING;
outbound.apply(hdr, meta);
} else if (meta.direction == dash_direction_t.INBOUND) {
inbound.apply(hdr, meta);
Expand Down
11 changes: 11 additions & 0 deletions dash-pipeline/bmv2/dash_routing_types.p4
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ action set_mapping_meter_attr(

// Routing Type - drop:
action drop(inout metadata_t meta) {
meta.target_stage = dash_pipeline_stage_t.ROUTING_ACTION_APPLY;
meta.dropped = true;
}

Expand All @@ -37,6 +38,7 @@ action route_vnet(
bit<1> meter_policy_en,
bit<16> meter_class)
{
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_MAPPING;
meta.dst_vnet_id = dst_vnet_id;
set_route_meter_attrs(meta, meter_policy_en, meter_class);
}
Expand All @@ -54,6 +56,7 @@ action route_vnet_direct(
bit<1> meter_policy_en,
bit<16> meter_class)
{
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_MAPPING;
meta.dst_vnet_id = dst_vnet_id;
meta.lkup_dst_ip_addr = overlay_ip;
meta.is_lkup_dst_ip_v6 = overlay_ip_is_v6;
Expand All @@ -69,6 +72,7 @@ action route_direct(
bit<1> meter_policy_en,
bit<16> meter_class)
{
meta.target_stage = dash_pipeline_stage_t.ROUTING_ACTION_APPLY;
set_route_meter_attrs(meta, meter_policy_en, meter_class);
}

Expand Down Expand Up @@ -100,6 +104,9 @@ action route_service_tunnel(
/* assert(overlay_dip_is_v6 == 1 && overlay_sip_is_v6 == 1);
assert(overlay_dip_mask_is_v6 == 1 && overlay_sip_mask_is_v6 == 1);
assert(underlay_dip_is_v6 != 1 && underlay_sip_is_v6 != 1); */

meta.target_stage = dash_pipeline_stage_t.ROUTING_ACTION_APPLY;

meta.encap_data.original_overlay_dip = hdr.u0_ipv4.src_addr;
meta.encap_data.original_overlay_sip = hdr.u0_ipv4.dst_addr;

Expand Down Expand Up @@ -136,6 +143,8 @@ action set_tunnel_mapping(
bit<16> meter_class,
bit<1> meter_class_override)
{
meta.target_stage = dash_pipeline_stage_t.ROUTING_ACTION_APPLY;

if (use_dst_vnet_vni == 1)
meta.vnet_id = meta.dst_vnet_id;

Expand All @@ -159,6 +168,8 @@ action set_private_link_mapping(
bit<16> meter_class,
bit<1> meter_class_override)
{
meta.target_stage = dash_pipeline_stage_t.ROUTING_ACTION_APPLY;

push_action_static_encap(hdr = hdr,
meta = meta,
encap = dash_encapsulation,
Expand Down
58 changes: 58 additions & 0 deletions dash-pipeline/bmv2/stages/outbound_mapping.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef _DASH_STAGE_OUTBOUND_MAPPING_P4_
#define _DASH_STAGE_OUTBOUND_MAPPING_P4_

#include "../dash_routing_types.p4"

control outbound_mapping_stage(inout headers_t hdr,
inout metadata_t meta)
{
DEFINE_TABLE_COUNTER(ca_to_pa_counter)

@SaiTable[name = "outbound_ca_to_pa", api = "dash_outbound_ca_to_pa"]
table ca_to_pa {
key = {
/* Flow for express route */
meta.dst_vnet_id: exact @SaiVal[type="sai_object_id_t"];
meta.is_lkup_dst_ip_v6 : exact @SaiVal[name = "dip_is_v6"];
meta.lkup_dst_ip_addr : exact @SaiVal[name = "dip"];
}

actions = {
set_tunnel_mapping(hdr, meta);
set_private_link_mapping(hdr, meta);
@defaultonly drop(meta);
}
const default_action = drop(meta);

ATTACH_TABLE_COUNTER(ca_to_pa_counter)
}

action set_vnet_attrs(bit<24> vni) {
meta.encap_data.vni = vni;
}

@SaiTable[name = "vnet", api = "dash_vnet", isobject="true"]
table vnet {
key = {
meta.vnet_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_vnet_attrs;
}
}

apply {
if (meta.target_stage != dash_pipeline_stage_t.OUTBOUND_MAPPING) {
return;
}

switch (ca_to_pa.apply().action_run) {
set_tunnel_mapping: {
vnet.apply();
}
}
}
}

#endif /* _DASH_STAGE_OUTBOUND_MAPPING_P4_ */
40 changes: 40 additions & 0 deletions dash-pipeline/bmv2/stages/outbound_routing.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef _DASH_STAGE_OUTBOUND_ROUTING_P4_
#define _DASH_STAGE_OUTBOUND_ROUTING_P4_

#include "../dash_routing_types.p4"

control outbound_routing_stage(inout headers_t hdr,
inout metadata_t meta)
{
DEFINE_TABLE_COUNTER(routing_counter)

@SaiTable[name = "outbound_routing", api = "dash_outbound_routing"]
table routing {
key = {
meta.eni_id : exact @SaiVal[type="sai_object_id_t"];
meta.is_overlay_ip_v6 : exact @SaiVal[name = "destination_is_v6"];
meta.dst_ip_addr : lpm @SaiVal[name = "destination"];
}

actions = {
route_vnet(hdr, meta); /* for expressroute - ecmp of overlay */
route_vnet_direct(hdr, meta);
route_direct(hdr, meta);
route_service_tunnel(hdr, meta);
drop(meta);
}
const default_action = drop(meta);

ATTACH_TABLE_COUNTER(routing_counter)
}

apply {
if (meta.target_stage != dash_pipeline_stage_t.OUTBOUND_ROUTING) {
return;
}

routing.apply();
}
}

#endif /* _DASH_STAGE_OUTBOUND_ROUTING_P4_ */

0 comments on commit 1d1c89d

Please sign in to comment.