Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for metering #365

Merged
merged 1 commit into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions dash-pipeline/SAI/sai_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
'sai_ip_address_t': 'ipaddr',
'sai_ip_addr_family_t': 'u32',
'sai_uint32_t': 'u32',
'sai_uint64_t': 'u64',
'sai_mac_t': 'mac'
}

Expand All @@ -54,13 +55,26 @@ def p4_annotation_to_sai_attr(p4rt, sai_attr):
sai_attr['type'] = kv['value']['stringValue']
elif kv['key'] == 'isresourcetype':
sai_attr['isresourcetype'] = kv['value']['stringValue']
elif kv['key'] == 'isreadonly':
sai_attr['isreadonly'] = kv['value']['stringValue']
elif kv['key'] == 'objects':
sai_attr['objectName'] = kv['value']['stringValue']
elif kv['key'] == 'skipattr':
sai_attr['skipattr'] = kv['value']['stringValue']
else:
print("Unknown attr annotation " + kv['key'])
exit(1)
sai_attr['field'] = sai_type_to_field[sai_attr['type']]

def p4_annotation_to_sai_table(p4rt, sai_table):
for anno in p4rt[STRUCTURED_ANNOTATIONS_TAG]:
if anno[NAME_TAG] == SAI_TAG:
for kv in anno[KV_PAIR_LIST_TAG][KV_PAIRS_TAG]:
if kv['key'] == 'isobject':
sai_table['is_object'] = kv['value']['stringValue']
if kv['key'] == 'ignoretable':
vijasrin marked this conversation as resolved.
Show resolved Hide resolved
sai_table['ignore_table'] = kv['value']['stringValue']

def get_sai_key_type(key_size, key_header, key_field):
if key_size == 1:
return 'bool', "booldata"
Expand Down Expand Up @@ -252,7 +266,11 @@ def generate_sai_apis(program, ignore_tables):
sai_table_data[ACTIONS_TAG] = []
sai_table_data[ACTION_PARAMS_TAG] = []

if STRUCTURED_ANNOTATIONS_TAG in table['preamble']:
p4_annotation_to_sai_table(table['preamble'], sai_table_data)
table_control, table_name = table[PREAMBLE_TAG][NAME_TAG].split('.', 1)
if 'ignore_table' in sai_table_data.keys():
ignore_tables.append(table_name)
if table_name in ignore_tables:
continue

Expand Down Expand Up @@ -300,13 +318,14 @@ def generate_sai_apis(program, ignore_tables):
fill_action_params(sai_table_data[ACTION_PARAMS_TAG], param_names, all_actions[action_id])
sai_table_data[ACTIONS_TAG].append(all_actions[action_id])

if len(sai_table_data['keys']) == 1 and sai_table_data['keys'][0]['sai_key_name'].endswith(table_name.split('.')[-1] + '_id'):
sai_table_data['is_object'] = 'true'
elif len(sai_table_data['keys']) > 5:
sai_table_data['is_object'] = 'true'
else:
sai_table_data['is_object'] = 'false'
sai_table_data['name'] = sai_table_data['name'] + '_entry'
if 'is_object' not in sai_table_data.keys():
if len(sai_table_data['keys']) == 1 and sai_table_data['keys'][0]['sai_key_name'].endswith(table_name.split('.')[-1] + '_id'):
sai_table_data['is_object'] = 'true'
elif len(sai_table_data['keys']) > 5:
sai_table_data['is_object'] = 'true'
else:
sai_table_data['is_object'] = 'false'
sai_table_data['name'] = sai_table_data['name'] + '_entry'

table_names.append(sai_table_data[NAME_TAG])
is_new_api = True
Expand Down
50 changes: 28 additions & 22 deletions dash-pipeline/SAI/templates/saiapi.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ sai_status_t sai_create_{{ table.name }}(
// There shall be one and only one action_type
p4::v1::TableAction* entry = nullptr;
p4::v1::Action* action = nullptr;
auto expectedParams = 0;
auto matchedParams = 0;
//auto expectedParams = 0;
//auto matchedParams = 0;
sai_object_id_t objId = 0;
// Search the action
pi_p4_id_t actionId = 0;
Expand All @@ -58,8 +58,8 @@ sai_status_t sai_create_{{ table.name }}(
tableId = {{table.id}};
entry = matchActionEntry->mutable_action();
action = entry->mutable_action();
expectedParams = 0;
matchedParams = 0;
//expectedParams = 0;
//matchedParams = 0;
objId = 0;

matchActionEntry->set_table_id(tableId);
Expand Down Expand Up @@ -139,7 +139,7 @@ sai_status_t sai_create_{{ table.name }}(
{% if table.actions|length == 1 %}
{% for action in table.actions %}
actionId = {{action.id}}; // SAI_{{ table.name | upper }}_ACTION_{{ action.name | upper }}
expectedParams = {{ action.params|length }};
//expectedParams = {{ action.params|length }};
{% endfor %}
{% else %}
// Search the action
Expand All @@ -150,7 +150,7 @@ sai_status_t sai_create_{{ table.name }}(
{% for action in table.actions %}
case SAI_{{ table.name | upper }}_ACTION_{{ action.name | upper }}: {
actionId = {{action.id}};
expectedParams = {{ action.params|length }};
//expectedParams = {{ action.params|length }};
break;
}
{% endfor %}
Expand All @@ -165,31 +165,34 @@ sai_status_t sai_create_{{ table.name }}(
for (uint32_t i = 0; i < attr_count; i++) {
switch(attr_list[i].id) {
{% for param in table.actionParams %}
{% if param.skipattr == 'true' %}
{% else %}
case SAI_{{ table.name | upper }}_ATTR_{{ param.name | upper }}: {
auto param = action->add_params();
param->set_param_id({{param.id}});
{{param.field}}SetVal(attr_list[i].value, param, {{param.bitwidth}});
matchedParams++;
//matchedParams++;
{% if 'v4_or_v6_id' in param %}
{
// set v4_or_v6 field
auto param = action->add_params();
param->set_param_id({{param.v4_or_v6_id}});
booldataSetVal((attr_list[i].value.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, param, 1);
matchedParams++;
//matchedParams++;
}
{% endif %}
break;
}
{% endif %}
{% endfor %}
}
}

assert((matchedParams == expectedParams));
//assert((matchedParams == expectedParams));

if (matchedParams != expectedParams) {
goto ErrRet;
}
//if (matchedParams != expectedParams) {
// goto ErrRet;
//}
if (false == InsertInTable(matchActionEntry, &objId)) {
goto ErrRet;
}
Expand Down Expand Up @@ -284,8 +287,8 @@ sai_status_t sai_create_{{ table.name }}(
// There shall be one and only one action_type
auto entry = matchActionEntry->mutable_action();
auto action = entry->mutable_action();
auto expectedParams = 0;
auto matchedParams = 0;
//auto expectedParams = 0;
//auto matchedParams = 0;
pi_p4_id_t actionId;
grpc::StatusCode retCode;

Expand Down Expand Up @@ -327,7 +330,7 @@ sai_status_t sai_create_{{ table.name }}(
{% if table.actions|length == 1 %}
{% for action in table.actions %}
actionId = {{action.id}}; // SAI_{{ table.name | upper }}_ACTION_{{ action.name | upper }}
expectedParams = {{ action.params|length }};
//expectedParams = {{ action.params|length }};
{% endfor %}
{% else %}
// Search the action
Expand All @@ -336,7 +339,7 @@ sai_status_t sai_create_{{ table.name }}(
{% for action in table.actions %}
case SAI_{{ table.name | upper }}_ACTION_{{ action.name | upper }}: {
actionId = {{action.id}};
expectedParams = {{ action.params|length }};
//expectedParams = {{ action.params|length }};
break;
}
{% endfor %}
Expand All @@ -350,31 +353,34 @@ sai_status_t sai_create_{{ table.name }}(
for (uint32_t i = 0; i < attr_count; i++) {
switch(attr_list[i].id) {
{% for param in table.actionParams %}
{% if param.skipattr == 'true' %}
{% else %}
case SAI_{{ table.name | upper }}_ATTR_{{ param.name | upper }}: {
auto param = action->add_params();
param->set_param_id({{param.id}});
{{param.field}}SetVal(attr_list[i].value, param, {{param.bitwidth}});
matchedParams++;
//matchedParams++;
{% if 'v4_or_v6_id' in param %}
{
// set v4_or_v6 field
auto param = action->add_params();
param->set_param_id({{param.v4_or_v6_id}});
booldataSetVal((attr_list[i].value.ipaddr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) ? 0 : 1, param, 1);
matchedParams++;
//matchedParams++;
}
{% endif %}
break;
}
{% endif %}
{% endfor %}
}
}

assert((matchedParams == expectedParams));
//assert((matchedParams == expectedParams));

if (matchedParams != expectedParams) {
goto ErrRet;
}
//if (matchedParams != expectedParams) {
// goto ErrRet;
//}
// TODO: ternaly needs to set priority
retCode = MutateTableEntry(matchActionEntry, p4::v1::Update_Type_INSERT);
if (grpc::StatusCode::OK == retCode) {
Expand Down
11 changes: 11 additions & 0 deletions dash-pipeline/SAI/templates/saiapi.h.j2
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ typedef enum _sai_{{ table.name }}_attr_t
{% if table.is_object == 'true' %}
{% if table['keys'] | length > 1 %}
{% for key in table['keys'] %}
{% if key.isattribute != 'false' %}
/**
* @brief {{ key.match_type | capitalize | replace('Lpm', 'LPM') }} matched key {{ key.sai_key_name }}
*
Expand Down Expand Up @@ -149,16 +150,23 @@ typedef enum _sai_{{ table.name }}_attr_t
*/
SAI_{{ table.name | upper }}_ATTR_{{ key.sai_key_name | upper }}_MASK,

{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
{% for param in table.actionParams %}
{% if param.skipattr == 'true' %}
{% else %}
/**
* @brief Action {% for action in param.paramActions %}{{ action }}{{ ", " if not loop.last else "" }}{% endfor %} parameter {{ param.name | upper }}
*
* @type {{ param.type }}
{% if param.isreadonly == 'true' %}
* @flags READ_ONLY
{% else %}
* @flags CREATE_AND_SET
{% endif %}
{% if param.type == 'sai_uint16_t' %}
* @isvlan false
{% endif %}
Expand All @@ -177,8 +185,10 @@ typedef enum _sai_{{ table.name }}_attr_t
{% elif param.field == 's32' %}
* @default {{ param.default }}
{% else %}
{% if param.isreadonly != 'true' %}
* @default 0
{% endif %}
{% endif %}
{% if table.actions | length > 1 %}
{% if param.paramActions | length > 0 %}
* @validonly {% for action in param.paramActions %}SAI_{{ table.name | upper }}_ATTR_ACTION == SAI_{{ table.name | upper }}_ACTION_{{ action | upper }}{{ " or " if not loop.last else "" }}{% endfor %}
Expand All @@ -196,6 +206,7 @@ typedef enum _sai_{{ table.name }}_attr_t
SAI_{{ table.name | upper }}_ATTR_{{ param.name | upper }},
{% endif %}

{% endif %}
{% endfor %}
{% if table.with_counters == 'true' %}
/**
Expand Down
21 changes: 21 additions & 0 deletions dash-pipeline/SAI/templates/utils.h.j2
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,27 @@ void ipaddrSetVal(const sai_ip_address_t &value, T &t, int bits = -1){
}
}

template<typename T>
void ipaddrSetMask(const sai_attribute_value_t &value, T &t, int bits = -1){
ipaddrSetMask(value.ipaddr, t);
}

template<typename T>
void ipaddrSetMask(const sai_ip_address_t &value, T &t, int bits = -1){
switch(value.addr_family) {
case SAI_IP_ADDR_FAMILY_IPV4: {
uint32_t mask = value.addr.ip4;
t->set_mask(&mask, 4);
}
break;
case SAI_IP_ADDR_FAMILY_IPV6: {
t->set_mask(const_cast<uint8_t*>(&value.addr.ip6[0]), 16);
}
break;
default: assert(0 && "unrecognzed value.ipaddr.addr_family");
}
}

template<typename T>
void macSetVal(const sai_attribute_value_t &value, T &t, int bits = -1){
t->set_value(const_cast<uint8_t*>(&value.mac[0]), 6);
Expand Down
8 changes: 8 additions & 0 deletions dash-pipeline/bmv2/dash_metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ struct metadata_t {
bit<16> stage3_dash_acl_group_id;
bit<16> stage4_dash_acl_group_id;
bit<16> stage5_dash_acl_group_id;
bit<1> meter_policy_en;
bit<1> mapping_meter_class_override;
bit<16> meter_policy_id;
bit<16> policy_meter_class;
bit<16> route_meter_class;
bit<16> mapping_meter_class;
vijasrin marked this conversation as resolved.
Show resolved Hide resolved
bit<16> meter_class;
bit<32> meter_bucket_index;
tag_map_t src_tag_map;
tag_map_t dst_tag_map;
}
Expand Down
31 changes: 26 additions & 5 deletions dash-pipeline/bmv2/dash_outbound.p4
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,32 @@
control outbound(inout headers_t hdr,
inout metadata_t meta)
{
action route_vnet(bit<16> dst_vnet_id) {
action set_route_meter_attrs(bit<1> meter_policy_en,
bit<16> meter_class) {
meta.meter_policy_en = meter_policy_en;
meta.route_meter_class = meter_class;
}
action route_vnet(bit<16> dst_vnet_id,
bit<1> meter_policy_en,
bit<16> meter_class) {
meta.dst_vnet_id = dst_vnet_id;
set_route_meter_attrs(meter_policy_en, meter_class);
}

action route_vnet_direct(bit<16> dst_vnet_id,
bit<1> is_overlay_ip_v4_or_v6,
IPv4ORv6Address overlay_ip) {
IPv4ORv6Address overlay_ip,
bit<1> meter_policy_en,
bit<16> meter_class) {
meta.dst_vnet_id = dst_vnet_id;
meta.lkup_dst_ip_addr = overlay_ip;
meta.is_lkup_dst_ip_v6 = is_overlay_ip_v4_or_v6;
set_route_meter_attrs(meter_policy_en, meter_class);
}

action route_direct() {
action route_direct(bit<1> meter_policy_en,
bit<16> meter_class) {
set_route_meter_attrs(meter_policy_en, meter_class);
/* send to underlay router without any encap */
}

Expand All @@ -42,7 +55,9 @@ control outbound(inout headers_t hdr,
bit<1> is_underlay_sip_v4_or_v6,
IPv4ORv6Address underlay_sip,
dash_encapsulation_t dash_encapsulation,
bit<24> tunnel_key) {
bit<24> tunnel_key,
bit<1> meter_policy_en,
bit<16> meter_class) {
/* Assume the overlay addresses provided are always IPv6 and the original are IPv4 */
/* assert(is_overlay_dip_v4_or_v6 == 1 && is_overlay_sip_v4_or_v6 == 1);
assert(is_overlay_dip_mask_v4_or_v6 == 1 && is_overlay_sip_mask_v4_or_v6 == 1);
Expand All @@ -62,6 +77,7 @@ control outbound(inout headers_t hdr,
meta.encap_data.overlay_dmac = hdr.ethernet.dst_addr;
meta.encap_data.dash_encapsulation = dash_encapsulation;
meta.encap_data.service_tunnel_key = tunnel_key;
set_route_meter_attrs(meter_policy_en, meter_class);
}

#ifdef TARGET_BMV2_V1MODEL
Expand Down Expand Up @@ -102,13 +118,18 @@ control outbound(inout headers_t hdr,
#endif // TARGET_DPDK_PNA
}


action set_tunnel_mapping(IPv4Address underlay_dip,
EthernetAddress overlay_dmac,
bit<1> use_dst_vnet_vni) {
bit<1> use_dst_vnet_vni,
bit<16> meter_class,
bit<1> meter_class_override) {
if (use_dst_vnet_vni == 1)
meta.vnet_id = meta.dst_vnet_id;
meta.encap_data.overlay_dmac = overlay_dmac;
meta.encap_data.underlay_dip = underlay_dip;
meta.mapping_meter_class = meter_class;
meta.mapping_meter_class_override = meter_class_override;
}

#ifdef TARGET_BMV2_V1MODEL
Expand Down
Loading