Skip to content

Commit e39249b

Browse files
authored
[dash-p4] Add support to generate flow resimulation APIs (#553)
This change updates the P4 pipeline to generate the flow resimulation APIs. The change is following the DASH flow resimulation HLD defined in the PR here: #543. The flow resimulation could not be directly implemented using plain p4 api call. The actual pipeline implementation will be postponed until data plane app is ready. For the generated SAI API, the routing actions type will be generated as flag defined as below: ![image](https://github.com/sonic-net/DASH/assets/1533278/6c28c649-8b74-42f2-b32b-0990abe8d645)
1 parent aba7cfa commit e39249b

27 files changed

+292
-79
lines changed

dash-pipeline/SAI/sai_api_gen.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
import jinja2
1010
import typing
11+
import base64
1112
import jsonpath_ng.ext as jsonpath_ext
1213
import jsonpath_ng as jsonpath
1314
from utils.dash_p4 import DashP4SAIExtensions

dash-pipeline/SAI/templates/saienums.j2

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
{% for enum in sai_enums %}
2+
/**
3+
* @brief Defines a list of enums for {{ enum.name }}
4+
{% if enum.explicit_value %}
5+
*
6+
* @flags strict
7+
{% endif %}
8+
*/
29
typedef enum _sai_{{ enum.name }}_t
310
{
411
{% for member in enum.members %}
12+
{% if enum.explicit_value %}
13+
SAI_{{ enum.name | upper }}_{{ member.name | upper }} = {{ member.enum_value }},
14+
{% else %}
515
SAI_{{ enum.name | upper }}_{{ member.name | upper }},
16+
{% endif %}
617

718
{% endfor %}
819
} sai_{{ enum.name }}_t;

dash-pipeline/SAI/utils/dash_p4/dash_p4_enum.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def __init__(self):
1414
super().__init__()
1515
self.bitwidth: int = 0
1616
self.members: List[DashP4EnumMember] = []
17+
self.explicit_value: bool = False
1718

1819
def parse_p4rt(self, p4rt_enum: Dict[str, Any]) -> None:
1920
"""
@@ -39,6 +40,18 @@ def parse_p4rt(self, p4rt_enum: Dict[str, Any]) -> None:
3940
for enum_member in p4rt_enum[MEMBERS_TAG]
4041
]
4142

43+
# Check if all enum values are starting from 0 and contiguous.
44+
expected_value = 0
45+
for member in self.members:
46+
if member.enum_value != expected_value:
47+
self.explicit_value = True
48+
break
49+
expected_value += 1
50+
51+
print(
52+
f"Enum parsed: {self.name}, Bitwidth = {self.bitwidth}, MemberCount = {len(self.members)}, ExplicitValue = {self.explicit_value}"
53+
)
54+
4255
# Register enum type info.
4356
SAITypeSolver.register_sai_type(
4457
"sai_" + self.name + "_t",

dash-pipeline/SAI/utils/dash_p4/dash_p4_enum_member.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import base64
12
from .common import *
23

34

@@ -9,7 +10,7 @@ class DashP4EnumMember(DashP4Object):
910

1011
def __init__(self):
1112
super().__init__()
12-
self.p4rt_value: str = ""
13+
self.enum_value: int = ""
1314

1415
def parse_p4rt(self, p4rt_member: Dict[str, Any]) -> None:
1516
"""
@@ -19,4 +20,5 @@ def parse_p4rt(self, p4rt_member: Dict[str, Any]) -> None:
1920
2021
{ "name": "INVALID", "value": "AAA=" }
2122
"""
22-
self.p4rt_value = str(p4rt_member["value"])
23+
decoded_bytes = base64.b64decode(str(p4rt_member["value"]))
24+
self.enum_value = int.from_bytes(decoded_bytes, byteorder="big")

dash-pipeline/bmv2/dash_counters.p4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ DEFINE_ENI_HIT_COUNTER(flow_created, order=1)
5151
DEFINE_ENI_HIT_COUNTER(flow_create_failed, order=1)
5252
DEFINE_ENI_HIT_COUNTER(flow_updated, order=1)
5353
DEFINE_ENI_HIT_COUNTER(flow_update_failed, order=1)
54+
DEFINE_ENI_HIT_COUNTER(flow_updated_by_resimulation, order=1)
55+
DEFINE_ENI_HIT_COUNTER(flow_update_by_resimulation_failed, order=1)
5456
DEFINE_ENI_HIT_COUNTER(flow_deleted, order=1)
5557
DEFINE_ENI_HIT_COUNTER(flow_delete_failed, order=1)
5658
DEFINE_ENI_HIT_COUNTER(flow_aged, order=1)

dash-pipeline/bmv2/dash_metadata.p4

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#define MAX_HA_SET 1
88

99
enum bit<32> dash_routing_actions_t {
10-
NONE = 0,
1110
STATIC_ENCAP = (1 << 0),
1211
NAT = (1 << 1),
1312
NAT46 = (1 << 2),

dash-pipeline/bmv2/dash_pipeline.p4

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ control dash_ingress(
109109
ACL_GROUPS_PARAM(inbound_v6),
110110
ACL_GROUPS_PARAM(outbound_v4),
111111
ACL_GROUPS_PARAM(outbound_v6),
112-
bit<1> disable_fast_path_icmp_flow_redirection) {
112+
bit<1> disable_fast_path_icmp_flow_redirection,
113+
bit<1> full_flow_resimulation_requested,
114+
bit<64> max_resimulated_flow_per_second)
115+
{
113116
meta.eni_data.cps = cps;
114117
meta.eni_data.pps = pps;
115118
meta.eni_data.flows = flows;

dash-pipeline/bmv2/dash_routing_types.p4

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ action route_vnet(
2727
inout metadata_t meta,
2828
@SaiVal[type="sai_object_id_t"] bit<16> dst_vnet_id,
2929
bit<32> meter_class_or,
30-
@SaiVal[default_value="4294967295"] bit<32> meter_class_and)
30+
@SaiVal[default_value="4294967295"] bit<32> meter_class_and,
31+
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation)
3132
{
3233
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_MAPPING;
3334
meta.dst_vnet_id = dst_vnet_id;
@@ -45,7 +46,8 @@ action route_vnet_direct(
4546
@SaiVal[type="sai_ip_address_t"]
4647
IPv4ORv6Address overlay_ip,
4748
bit<32> meter_class_or,
48-
@SaiVal[default_value="4294967295"] bit<32> meter_class_and)
49+
@SaiVal[default_value="4294967295"] bit<32> meter_class_and,
50+
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation)
4951
{
5052
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_MAPPING;
5153
meta.dst_vnet_id = dst_vnet_id;
@@ -61,7 +63,8 @@ action route_direct(
6163
inout headers_t hdr,
6264
inout metadata_t meta,
6365
bit<32> meter_class_or,
64-
@SaiVal[default_value="4294967295"] bit<32> meter_class_and)
66+
@SaiVal[default_value="4294967295"] bit<32> meter_class_and,
67+
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation)
6568
{
6669
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_PRE_ROUTING_ACTION_APPLY;
6770
set_meter_attrs(meta, meter_class_or, meter_class_and);
@@ -89,7 +92,8 @@ action route_service_tunnel(
8992
dash_encapsulation_t dash_encapsulation,
9093
bit<24> tunnel_key,
9194
bit<32> meter_class_or,
92-
@SaiVal[default_value="4294967295"] bit<32> meter_class_and)
95+
@SaiVal[default_value="4294967295"] bit<32> meter_class_and,
96+
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation)
9397
{
9498
/* Assume the overlay addresses provided are always IPv6 and the original are IPv4 */
9599
/* assert(overlay_dip_is_v6 == 1 && overlay_sip_is_v6 == 1);
@@ -128,7 +132,9 @@ action set_tunnel_mapping(
128132
@SaiVal[type="sai_ip_address_t"] IPv4Address underlay_dip,
129133
EthernetAddress overlay_dmac,
130134
bit<1> use_dst_vnet_vni,
131-
bit<32> meter_class_or)
135+
bit<32> meter_class_or,
136+
bit<1> flow_resimulation_requested,
137+
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation)
132138
{
133139
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_PRE_ROUTING_ACTION_APPLY;
134140

@@ -152,7 +158,9 @@ action set_private_link_mapping(
152158
IPv6Address overlay_dip,
153159
@SaiVal[type="sai_dash_encapsulation_t"] dash_encapsulation_t dash_encapsulation,
154160
bit<24> tunnel_key,
155-
bit<32> meter_class_or)
161+
bit<32> meter_class_or,
162+
bit<1> flow_resimulation_requested,
163+
dash_routing_actions_t routing_actions_disabled_in_flow_resimulation)
156164
{
157165
meta.target_stage = dash_pipeline_stage_t.OUTBOUND_PRE_ROUTING_ACTION_APPLY;
158166

dash-pipeline/tests/libsai/vnet_out/vnet_out.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ int main(int argc, char **argv)
211211
attr.value.booldata = false;
212212
attrs.push_back(attr);
213213

214+
attr.id = SAI_ENI_ATTR_FULL_FLOW_RESIMULATION_REQUESTED;
215+
attr.value.booldata = false;
216+
attrs.push_back(attr);
217+
218+
attr.id = SAI_ENI_ATTR_MAX_RESIMULATED_FLOW_PER_SECOND;
219+
attr.value.u64 = 0;
220+
attrs.push_back(attr);
221+
214222
status = dash_eni_api->create_eni(&eni_id, switch_id, attrs.size(), attrs.data());
215223

216224
if (status != SAI_STATUS_SUCCESS)

dash-pipeline/tests/saithrift/pytest/vnet/test_saithrift_vnet.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ def test_sai_thrift_create_eni(saithrift_client):
7575
outbound_v6_stage3_dash_acl_group_id = 0,
7676
outbound_v6_stage4_dash_acl_group_id = 0,
7777
outbound_v6_stage5_dash_acl_group_id = 0,
78-
disable_fast_path_icmp_flow_redirection = 0)
78+
disable_fast_path_icmp_flow_redirection = 0,
79+
full_flow_resimulation_requested = False,
80+
max_resimulated_flow_per_second = 0)
7981
assert (eni != SAI_NULL_OBJECT_ID);
8082

8183
eam = sai_thrift_eni_ether_address_map_entry_t(switch_id=switch_id, address = eth_addr)

0 commit comments

Comments
 (0)