Skip to content

Commit

Permalink
Add reverse routing stage support.
Browse files Browse the repository at this point in the history
  • Loading branch information
r12f committed Jul 16, 2024
1 parent 2c49ba4 commit 0b0d812
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 3 deletions.
3 changes: 3 additions & 0 deletions dash-pipeline/bmv2/dash_counters.p4
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,8 @@ DEFINE_ENI_PACKET_COUNTER(outbound_ca_pa_entry_miss_drop)
DEFINE_ENI_PACKET_COUNTER(inbound_routing_entry_miss_drop)
DEFINE_ENI_PACKET_COUNTER(outbound_routing_group_miss_drop)
DEFINE_ENI_PACKET_COUNTER(outbound_routing_group_disabled_drop)
DEFINE_ENI_PACKET_COUNTER(reverse_tunnel_miss_drop)
DEFINE_ENI_PACKET_COUNTER(reverse_tunnel_member_miss_drop)
DEFINE_ENI_PACKET_COUNTER(reverse_tunnel_next_hop_miss_drop)

#endif // __DASH_COUNTERS__
16 changes: 14 additions & 2 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ enum bit<32> dash_routing_actions_t {
NAT = (1 << 1),
NAT46 = (1 << 2),
NAT64 = (1 << 3),
NAT_PORT = (1 << 4)
NAT_PORT = (1 << 4),
TUNNEL = (1 << 5),
REVERSE_TUNNEL = (1 << 6)
};

enum bit<16> dash_direction_t {
Expand Down Expand Up @@ -155,6 +157,11 @@ struct eni_data_t {
outbound_routing_group_data_t outbound_routing_group_data;
}

struct outbound_reverse_routing_data_t {
bit<16> routing_group_id;
bool disabled;
};

struct meter_context_t {
bit<32> meter_class_or;
bit<32> meter_class_and;
Expand Down Expand Up @@ -236,6 +243,7 @@ struct metadata_t {
bit<16> dst_vnet_id;
bit<16> eni_id;
eni_data_t eni_data;
outbound_reverse_routing_data_t outbound_reverse_routing_data;
bit<16> inbound_vm_id;
bit<8> appliance_id;
bit<1> is_overlay_ip_v6;
Expand Down Expand Up @@ -274,9 +282,13 @@ struct metadata_t {
// encap_data is for underlay
encap_data_t encap_data;
// tunnel_data is used by dash_tunnel_id
bit<16> dash_tunnel_id;
encap_data_t tunnel_data;
bit<16> dash_reverse_tunnel_id;
bit<16> dash_reverse_tunnel_member_id;
bit<16> dash_reverse_tunnel_next_hop_id;
encap_data_t reverse_tunnel_data;
overlay_rewrite_data_t overlay_data;
bit<16> dash_tunnel_id;
bit<32> meter_class;
}

Expand Down
3 changes: 2 additions & 1 deletion dash-pipeline/bmv2/dash_pipeline.p4
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ control dash_ingress(
bit<1> disable_fast_path_icmp_flow_redirection,
bit<1> full_flow_resimulation_requested,
bit<64> max_resimulated_flow_per_second,
@SaiVal[type="sai_object_id_t"] bit<16> outbound_routing_group_id)
@SaiVal[type="sai_object_id_t"] bit<16> outbound_routing_group_id,
@SaiVal[type="sai_object_id_t"] bit<16> outbound_reverse_routing_group_id)
{
meta.eni_data.cps = cps;
meta.eni_data.pps = pps;
Expand Down
107 changes: 107 additions & 0 deletions dash-pipeline/bmv2/routing_actions/routing_action_reverse_tunnel.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#ifndef _DASH_ROUTING_ACTION_REVERSE_TUNNEL_P4_
#define _DASH_ROUTING_ACTION_REVERSE_TUNNEL_P4_

action push_action_reverse_tunnel(
in headers_t hdr,
inout metadata_t meta,
in bit<16> dash_reverse_tunnel_id)
{
meta.routing_actions = meta.routing_actions | dash_routing_actions_t.REVERSE_TUNNEL;

meta.dash_reverse_tunnel_id = dash_reverse_tunnel_id;
}

control do_action_reverse_tunnel(
inout headers_t hdr,
inout metadata_t meta)
{
//
// Reverse Tunnel
//
action set_reverse_tunnel_attrs(
@SaiVal[type="sai_dash_encapsulation_t", default_value="SAI_DASH_ENCAPSULATION_VXLAN"] dash_encapsulation_t dash_encapsulation,
bit<24> tunnel_key
) {
meta.reverse_tunnel_data.dash_encapsulation = dash_encapsulation;
meta.reverse_tunnel_data.vni = tunnel_key;
}

@SaiTable[name = "dash_reverse_tunnel", api = "dash_reverse_tunnel", order = 0, isobject="true"]
table reverse_tunnel {
key = {
meta.dash_reverse_tunnel_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_reverse_tunnel_attrs;
}
}

//
// Reverse tunnel member
//
action set_reverse_tunnel_member_attrs(
@SaiVal[type="sai_object_id_t"] bit<16> dash_reverse_tunnel_next_hop_id
) {
meta.dash_reverse_tunnel_next_hop_id = dash_reverse_tunnel_next_hop_id;
}

@SaiTable[name = "dash_reverse_tunnel", api = "dash_reverse_tunnel", order = 1, isobject="true"]
table reverse_tunnel_member {
key = {
meta.dash_reverse_tunnel_id : exact @SaiVal[type="sai_object_id_t"];
meta.dash_reverse_tunnel_member_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_reverse_tunnel_member_attrs;
}
}

//
// Reverse tunnel next hop
//
action set_reverse_tunnel_next_hop_attrs(
@SaiVal[type="sai_ip_address_t"] IPv4Address dip,
@SaiVal[type="sai_ip_address_t"] IPv4Address sip
) {
meta.reverse_tunnel_data.underlay_dip = dip;
meta.reverse_tunnel_data.underlay_sip = sip;
}

@SaiTable[name = "dash_reverse_tunnel", api = "dash_reverse_tunnel", order = 2, isobject="true"]
table reverse_tunnel_next_hop {
key = {
meta.dash_reverse_tunnel_next_hop_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_reverse_tunnel_next_hop_attrs;
}
}

apply {
if (meta.routing_actions & dash_routing_actions_t.REVERSE_TUNNEL == 0) {
return;
}

if (!reverse_tunnel.apply().hit) {
UPDATE_ENI_COUNTER(reverse_tunnel_miss_drop);
return;
}

meta.dash_reverse_tunnel_member_id = 0; // TODO: ECMP group selection!

if (!reverse_tunnel_member.apply().hit) {
UPDATE_ENI_COUNTER(reverse_tunnel_member_miss_drop);
return;
}

if (!reverse_tunnel_next_hop.apply().hit) {
UPDATE_ENI_COUNTER(reverse_tunnel_next_hop_miss_drop);
return;
}
}
}

#endif /* _DASH_ROUTING_ACTION_REVERSE_TUNNEL_P4_ */
1 change: 1 addition & 0 deletions dash-pipeline/bmv2/routing_actions/routing_actions.p4
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
#include "routing_action_static_encap.p4"
#include "routing_action_nat46.p4"
#include "routing_action_nat64.p4"
#include "routing_action_reverse_tunnel.p4"

#endif /* _DASH_ROUTING_ACTIONS_P4_ */
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _DASH_STAGE_OUTBOUND_PRE_ROUTING_ACTION_APPLY_P4_
#define _DASH_STAGE_OUTBOUND_PRE_ROUTING_ACTION_APPLY_P4_

#include "outbound_reverse_routing.p4"

control outbound_pre_routing_action_apply_stage(
inout headers_t hdr,
inout metadata_t meta)
Expand All @@ -11,6 +13,8 @@ control outbound_pre_routing_action_apply_stage(
return;
}

outbound_reverse_routing_stage.apply(hdr, meta);

// Once it is done, move to routing action apply stage.
meta.target_stage = dash_pipeline_stage_t.ROUTING_ACTION_APPLY;
}
Expand Down
70 changes: 70 additions & 0 deletions dash-pipeline/bmv2/stages/outbound_reverse_routing.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef _DASH_STAGE_OUTBOUND_REVERSE_reverse_routing_P4_
#define _DASH_STAGE_OUTBOUND_REVERSE_reverse_routing_P4_

control outbound_reverse_routing_stage(
inout headers_t hdr,
inout metadata_t meta
) {
//
// Reverse routing group table
//
action set_outbound_reverse_routing_group_attr(bit<1> disabled) {
meta.outbound_reverse_routing_data.disabled = (bool)disabled;
}

@SaiTable[name = "outbound_reverse_routing_group", api = "dash_outbound_reverse_routing", order = 1, isobject="true"]
table outbound_reverse_routing_group {
key = {
meta.outbound_reverse_routing_data.routing_group_id: exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_outbound_reverse_routing_group_attr;
}
}

//
// Reverse routing table
//
action set_outbound_reverse_routing_entry_attr(
@SaiVal[type="sai_object_id_t"] bit<16> dash_reverse_tunnel_id,
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation
) {
push_action_reverse_tunnel(hdr, meta, dash_reverse_tunnel_id);
}

DEFINE_TABLE_COUNTER(reverse_routing_counter)

@SaiTable[name = "outbound_reverse_routing", api = "dash_outbound_reverse_routing"]
table reverse_routing {
key = {
meta.outbound_reverse_routing_data.routing_group_id : exact @SaiVal[type="sai_object_id_t"];
meta.is_overlay_ip_v6 : exact @SaiVal[name = "source_is_v6"];
meta.src_ip_addr : lpm @SaiVal[name = "source"];
}

actions = {
set_outbound_reverse_routing_entry_attr;
}

size = 4 * 1024 * 1024;

ATTACH_TABLE_COUNTER(reverse_routing_counter)
}

apply {
// If reverse routing stage tables are not hit, we don't need to drop the packet.
// This simply means no reverse routing is needed, and we can continue to the next stage.
if (!outbound_reverse_routing_group.apply().hit) {
return;
}

if (meta.outbound_reverse_routing_data.disabled) {
return;
}

reverse_routing.apply();
}
}

#endif /* _DASH_STAGE_OUTBOUND_REVERSE_reverse_routing_P4_ */

0 comments on commit 0b0d812

Please sign in to comment.