Skip to content

Commit

Permalink
Add tunnel member and next hop table.
Browse files Browse the repository at this point in the history
  • Loading branch information
r12f committed Sep 28, 2024
1 parent 6d963e5 commit 0d3d887
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 25 deletions.
22 changes: 12 additions & 10 deletions dash-pipeline/SAI/templates/saiapi.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,16 @@ static sai_status_t dash_sai_create_{{ table.name }}(

matchActionEntry->set_table_id(tableId);

{% if table['keys'] | length== 1 %}
// SAI object table with single P4 key - object ID itself is the P4 table key
// Generate a SAI object ID and fill it as the P4 table key
auto mf = matchActionEntry->add_match();
mf->set_field_id({{table['keys'][0].id}});
auto mf_exact = mf->mutable_exact();
//{{table['keys'][0].field}}SetVal(objId, mf_exact, {{table['keys'][0].bitwidth}});
{{table['keys'][0].field}}SetVal(static_cast<uint{{ table['keys'][0].bitwidth }}_t>(objId), mf_exact, {{ table['keys'][0].bitwidth }});
{% else %}
{% for key in table['keys'] %}
{% if key.is_object_key %}
auto key_mf = matchActionEntry->add_match();
key_mf->set_field_id({{key.id}});
auto key_mf_exact = key_mf->mutable_exact();
// {{key.field}}SetVal(objId, key_mf_exact, {{key.bitwidth}});
{{key.field}}SetVal(static_cast<uint{{ key.bitwidth }}_t>(objId), key_mf_exact, {{ key.bitwidth }});
{% endif %}
{% endfor %}

// SAI object table with multiple P4 table keys
// Copy P4 table keys from appropriate SAI attributes
for (uint32_t i = 0; i < attr_count; i++)
Expand All @@ -79,6 +80,7 @@ static sai_status_t dash_sai_create_{{ table.name }}(
switch(attr_list[i].id)
{
{% for key in table['keys'] %}
{% if not key.is_object_key %}
case SAI_{{ table.name | upper }}_ATTR_{{ key.name | upper }}:
{
auto mf = matchActionEntry->add_match();
Expand Down Expand Up @@ -138,6 +140,7 @@ static sai_status_t dash_sai_create_{{ table.name }}(
{% endif %}
break;
}
{% endif%}
{% endfor %}
{% if table['keys'] | selectattr('match_type', 'ne', 'exact') | list | length > 0 %}
{% if table['keys'] | selectattr('match_type', 'eq', 'lpm') | list | length == 0 %}
Expand All @@ -154,7 +157,6 @@ static sai_status_t dash_sai_create_{{ table.name }}(
break;
}
}
{% endif %}

// If there is only one action, simply set it.
// Else, search in the attrs.
Expand Down
10 changes: 7 additions & 3 deletions dash-pipeline/SAI/utils/dash_p4/dash_p4_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,13 @@ def create_sai_stats(self, sai_api: SaiApi) -> None:

def create_sai_attributes(self, sai_api: SaiApi) -> None:
# If the table is an object with more one key (table entry id), we need to add all the keys into the attributes.
if self.is_object == "true" and len(self.keys) > 1:
for key in self.keys:
sai_api.attributes.extend(key.to_sai_attribute(self.name, create_only=True))
if self.is_object == "true":
if len(self.keys) == 1:
self.keys[0].is_object_key = True
elif len(self.keys) > 1:
for key in self.keys:
if not key.is_object_key:
sai_api.attributes.extend(key.to_sai_attribute(self.name, create_only=True))

# Add all the action parameters into the attributes.
for attr in self.sai_attributes:
Expand Down
3 changes: 3 additions & 0 deletions dash-pipeline/SAI/utils/dash_p4/dash_p4_table_attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def __init__(self):
self.skipattr: Optional[str] = None
self.match_type: str = ""
self.validonly: Optional[str] = None
self.is_object_key: bool = False

def _parse_sai_table_attribute_annotation(
self, p4rt_anno_list: Dict[str, Any]
Expand Down Expand Up @@ -66,6 +67,8 @@ def _parse_sai_table_attribute_annotation(
self.match_type = str(kv["value"]["stringValue"])
elif kv["key"] == "validonly":
self.validonly = str(kv["value"]["stringValue"])
elif kv["key"] == "is_object_key":
self.is_object_key = kv["value"]["stringValue"] == "true"
else:
raise ValueError("Unknown attr annotation " + kv["key"])

Expand Down
3 changes: 3 additions & 0 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ struct metadata_t {
encap_data_t tunnel_data;
overlay_rewrite_data_t overlay_data;
bit<16> dash_tunnel_id;
bit<16> dash_tunnel_member_index;
bit<16> dash_tunnel_member_id;
bit<16> dash_tunnel_next_hop_id;
bit<32> meter_class;
bit<8> local_region_id;
}
Expand Down
101 changes: 89 additions & 12 deletions dash-pipeline/bmv2/stages/tunnel_stage.p4
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ control tunnel_stage(
inout metadata_t meta)
{
action set_tunnel_attrs(
@SaiVal[type="sai_ip_address_t"]
IPv4Address dip,
@SaiVal[type="sai_dash_encapsulation_t", default_value="SAI_DASH_ENCAPSULATION_VXLAN"]
dash_encapsulation_t dash_encapsulation,
bit<24> tunnel_key) {
push_action_static_encap(hdr = hdr,
meta = meta,
encap = dash_encapsulation,
vni = tunnel_key,
underlay_sip = hdr.u0_ipv4.src_addr,
underlay_dip = dip,
overlay_dmac = hdr.u0_ethernet.dst_addr);
@SaiVal[type="sai_ip_address_t"]
IPv4Address dip,
@SaiVal[type="sai_dash_encapsulation_t", default_value="SAI_DASH_ENCAPSULATION_VXLAN"]
dash_encapsulation_t dash_encapsulation,
bit<24> tunnel_key)
{
push_action_static_encap(hdr = hdr,
meta = meta,
encap = dash_encapsulation,
vni = tunnel_key,
underlay_sip = hdr.u0_ipv4.src_addr,
underlay_dip = dip,
overlay_dmac = hdr.u0_ethernet.dst_addr);
}

@SaiTable[name = "dash_tunnel", api = "dash_tunnel", order = 0, isobject="true"]
Expand All @@ -31,8 +32,84 @@ control tunnel_stage(
}
}

action select_tunnel_member(
bit<16> dash_tunnel_member_id)
{
meta.dash_tunnel_member_id = dash_tunnel_member_id;
}

// This table is a helper table that used to select the tunnel member based on the index.
// The entry of this table is created by DASH data plane app, when the tunnel member is created.
@SaiTable[ignored = "true"]
table tunnel_member_select {
key = {
meta.dash_tunnel_member_index : exact @SaiVal[type="sai_object_id_t", is_object_key="true"];
meta.dash_tunnel_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
select_tunnel_member;
}
}

action set_tunnel_member_attrs(
@SaiVal[type="sai_object_id_t"] bit<16> dash_tunnel_id,
@SaiVal[type="sai_object_id_t"] bit<16> dash_tunnel_next_hop_id)
{
// dash_tunnel_id in tunnel member must match the metadata
assert(meta.dash_tunnel_id == dash_tunnel_id);

meta.dash_tunnel_next_hop_id = dash_tunnel_next_hop_id;
}

@SaiTable[name = "dash_tunnel_member", api = "dash_tunnel", order = 1, isobject="true"]
table tunnel_member {
key = {
meta.dash_tunnel_member_id : exact @SaiVal[type="sai_object_id_t", is_object_key="true"];
}

actions = {
set_tunnel_member_attrs;
}
}

action set_tunnel_next_hop_attrs(
@SaiVal[type="sai_ip_address_t"]
IPv4Address dip,
@SaiVal[type="sai_dash_encapsulation_t", default_value="SAI_DASH_ENCAPSULATION_VXLAN"]
dash_encapsulation_t dash_encapsulation,
bit<24> tunnel_key)
{
push_action_static_encap(hdr = hdr,
meta = meta,
encap = dash_encapsulation,
vni = tunnel_key,
underlay_sip = hdr.u0_ipv4.src_addr,
underlay_dip = dip,
overlay_dmac = hdr.u0_ethernet.dst_addr);
}

@SaiTable[name = "dash_tunnel_next_hop", api = "dash_tunnel", order = 2, isobject="true"]
table tunnel_next_hop{
key = {
meta.dash_tunnel_next_hop_id : exact @SaiVal[type="sai_object_id_t"];
}

actions = {
set_tunnel_next_hop_attrs;
}
}

apply {
tunnel.apply();

// TODO: Calculate based on packet and tunnel member size.
// Currently, we will have to use 0 here, because we don't know how many tunnel members we will have.
meta.dash_tunnel_member_index = 0;
tunnel_member_select.apply();

tunnel_member.apply();
tunnel_next_hop.apply();
}
}

Expand Down

0 comments on commit 0d3d887

Please sign in to comment.