forked from opencomputeproject/SAI
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from opencomputeproject/master
merge from upstream
- Loading branch information
Showing
23 changed files
with
1,227 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Starter pipeline | ||
# Start with a minimal pipeline that you can customize to build and deploy your code. | ||
# Add steps that build, run tests, deploy, and more: | ||
# https://aka.ms/yaml | ||
|
||
trigger: | ||
branches: | ||
include: | ||
- master | ||
|
||
pr: | ||
branches: | ||
include: | ||
- master | ||
|
||
pool: | ||
vmImage: ubuntu-20.04 | ||
|
||
stages: | ||
- stage: Build | ||
jobs: | ||
- job: | ||
|
||
container: | ||
image: sonicdev-microsoft.azurecr.io:443/sonic-slave-buster:latest | ||
|
||
displayName: "build" | ||
timeoutInMinutes: 60 | ||
steps: | ||
- checkout: self | ||
clean: true | ||
submodules: recursive | ||
displayName: 'Checkout code' | ||
- script: | | ||
set -ex | ||
export ANSI_COLORS_DISABLED=1 | ||
cd meta | ||
make | ||
displayName: "Metadata check" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
Override VRF | ||
------------------------------------------------------------------------------- | ||
Title | SAI Override VRF | ||
-------------|----------------------------------------------------------------- | ||
Authors | Jai Kumar, Broadcom Inc. | ||
Status | In review | ||
Type | Standards track | ||
Created | 02/18/2021 | ||
SAI-Version | 1.7.2 | ||
|
||
|
||
------------------------------------------------------------------------------- | ||
|
||
This spec talks about the override VRF usecase. | ||
|
||
SAI pipleine define L3 lookup block as an abstracted stage where route lookup is abstracted as a single operation. | ||
SAI pipeline do not specify how many parallel L3 lookups a device can/may support. | ||
|
||
Typically devices support multiple parallel L3 lookup to provide policy based forwarding. | ||
Following usecase 1 is already covered in SAI spec. This spec adds support for usecase 2 and 3. | ||
|
||
New switch level default override VRF is introduced. | ||
``` | ||
/** | ||
* @brief Default SAI Override Virtual Router ID | ||
* | ||
* Must return #SAI_STATUS_OBJECT_IN_USE when try to delete this VR ID. | ||
* | ||
* @type sai_object_id_t | ||
* @flags READ_ONLY | ||
* @objects SAI_OBJECT_TYPE_VIRTUAL_ROUTER | ||
* @default internal | ||
*/ | ||
SAI_SWITCH_ATTR_DEFAULT_OVERRIDE_VIRTUAL_ROUTER_ID, | ||
``` | ||
|
||
|
||
### Usecase 1: VRF Fallback | ||
In this case 2 parrallel lookups are performed | ||
``` | ||
Lookup 1: RIF/ACL -> VRF -> [VRF, DIP] -> R1 | ||
Lookup 2: Switch -> Deafault_VRF -> [Default_VRF, DIP] -> R2 | ||
if (R1) | ||
use R1; | ||
elif (R2) | ||
use R2; | ||
else | ||
MISS action; | ||
``` | ||
|
||
|
||
|
||
### Usecase 2: Override VRF | ||
In this case 2 parallel lookups are performed | ||
``` | ||
Lookup 1: Switch -> Override_VRF -> [Override_VRF, DIP] -> R1 | ||
Lookup 2: RIF/ACL -> VRF -> [VRF, DIP] -> R2 | ||
if (R1) | ||
use R1; | ||
elif (R2) | ||
use R2; | ||
else | ||
MISS action; | ||
``` | ||
|
||
### Usecase 3: Override VRF and VRF Fallback | ||
In this case 3 parallel lookups are performed | ||
``` | ||
Lookup 1: Switch -> Override_VRF -> [Override_VRF, DIP] -> R1 | ||
Lookup 2: RIF/ACL -> VRF -> [VRF, DIP] -> R2 | ||
Lookup 2: Switch -> Deafault_VRF -> [Default_VRF, DIP] -> R3 | ||
if (R1) | ||
use R1; | ||
elif (R2) | ||
use R2; | ||
elif (R3) | ||
use R3; | ||
else | ||
MISS action; | ||
``` | ||
|
||
Example WorkFlow: | ||
Since SAI_SWITCH_ATTR_DEFAULT_OVERRIDE_VIRTUAL_ROUTER_ID is a READ only attribute, SAI adapter creates a VRF object (virtual_router) during init. This object is emtpy and is returned when application quries for the override VRF. | ||
Application MUST provide this VRF in the route update API. | ||
``` | ||
typedef struct _sai_route_entry_t | ||
{ | ||
/** | ||
* @brief Switch ID | ||
* | ||
* @objects SAI_OBJECT_TYPE_SWITCH | ||
*/ | ||
sai_object_id_t switch_id; | ||
/** | ||
* @brief Virtual Router ID | ||
* | ||
* @objects SAI_OBJECT_TYPE_VIRTUAL_ROUTER | ||
*/ | ||
sai_object_id_t vr_id; | ||
/** | ||
* @brief IP Prefix Destination | ||
*/ | ||
sai_ip_prefix_t destination; | ||
} sai_route_entry_t; | ||
``` | ||
|
||
> SAI adapter should return error if platform do not support SAI_SWITCH_ATTR_DEFAULT_OVERRIDE_VIRTUAL_ROUTER_ID switch attribute |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
# Overview | ||
|
||
### Virtual Router derivation | ||
In a standard router, a packet is received on a port. Based on the port property and relevant packet header fields, the ingress interface is derived.\ | ||
L3 interfaces are assigned to a virtual router (VRF) when they are created. This VRF is used in route lookup. | ||
|
||
### Flexible Virtual Router assignment | ||
It can be beneficial to have some flexibility in VRF assignment. Specifically it is useful to have the ability to match on packet header fields to override the VRF derived from the router interface.\ | ||
An example use case would be to use the DSCP value from the packet’s header to set VRF in order to be able to forward high priority traffic on optimal paths. | ||
|
||
### Proposal | ||
#### Pre-Ingress ACL stage | ||
The packet header based VRF assignment functionality can be provided by an ACL that must be applied before the L3 forwarding lookup.\ | ||
To enable this a new ACL stage is defined | ||
|
||
``` | ||
inc/saitypes.h | ||
typedef enum _sai_acl_stage_t | ||
{ | ||
... | ||
/** Pre-ingress Stage */ | ||
SAI_ACL_STAGE_PRE_INGRESS, | ||
} sai_acl_stage_t; | ||
``` | ||
|
||
in addition to an attribute to bind ACLs with this stage to the switch. | ||
|
||
``` | ||
inc/saiswitch.h | ||
typedef enum _sai_switch_attr_t | ||
{ | ||
... | ||
/** | ||
* @brief Switch/Global bind point for pre-ingress ACL object | ||
* | ||
* Bind (or unbind) an pre-ingress ACL table or ACL group globally. Enable/Update | ||
* pre-ingress ACL table or ACL group filtering by assigning the list of valid | ||
* object id. Disable pre-ingress filtering by assigning SAI_NULL_OBJECT_ID | ||
* in the attribute value. | ||
* | ||
* @type sai_object_id_t | ||
* @flags CREATE_AND_SET | ||
* @objects SAI_OBJECT_TYPE_ACL_TABLE, SAI_OBJECT_TYPE_ACL_TABLE_GROUP | ||
* @allownull true | ||
* @default SAI_NULL_OBJECT_ID | ||
*/ | ||
SAI_SWITCH_ATTR_PRE_INGRESS_ACL, | ||
... | ||
} sai_switch_attr_t; | ||
``` | ||
Binding a Pre-Ingress ACL to the switch bind point allows all traffic to match on the rules before the L3 lookup. (This helps with scale when the rules in the Pre-Ingress ACL are not port specific)\ | ||
Pre-Ingress ACLs take effect before Ingress ACL. So Ingress ACLs can override any non-terminal actions taken by the Pre-Ingress ACL.\ | ||
The currently defined ACL match fields will be used for the Pre-Ingress ACL | ||
stage as well.\ | ||
|
||
#### Set VRF action | ||
This ACL will support a new ACL action to set VRF in the packet metadata.\ | ||
This VRF will take precedence over the VRF derived from the ingress interface. | ||
|
||
``` | ||
inc/saiacl.h | ||
typedef enum _sai_acl_action_type_t | ||
{ | ||
... | ||
/** Associate with virtual router */ | ||
SAI_ACL_ACTION_TYPE_SET_VRF | ||
} sai_acl_action_type_t; | ||
``` | ||
``` | ||
typedef enum _sai_acl_entry_attr_t | ||
{ | ||
... | ||
/** | ||
* @brief Set virtual router | ||
* | ||
* @type sai_acl_action_data_t sai_object_id_t | ||
* @flags CREATE_AND_SET | ||
* @objects SAI_OBJECT_TYPE_VIRTUAL_ROUTER | ||
* @default disabled | ||
*/ | ||
SAI_ACL_ENTRY_ATTR_ACTION_SET_VRF, | ||
... | ||
} sai_acl_entry_attr_t; | ||
``` | ||
|
||
|
||
|
||
|
||
### Usage | ||
Create an ACL table | ||
``` | ||
sai_object_id_t acl_table_id = 0ULL; | ||
acl_table_attrs[0].id = SAI_ACL_TABLE_ATTR_ACL_STAGE; | ||
acl_table_attrs[0].value.s32 = SAI_ACL_STAGE_PRE_INGRESS; | ||
acl_table_attrs[1].id = SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST; | ||
acl_table_attrs[1].value.objlist.count = 1; | ||
acl_table_attrs[1].value.objlist.list[0] = SAI_ACL_BIND_POINT_TYPE_SWITCH; | ||
acl_table_attrs[2].id = SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL; | ||
acl_table_attrs[2].value.booldata = true; | ||
status = sai_acl_api->create_acl_table(&acl_table_id, 3, acl_table_attrs); | ||
if (status != SAI_STATUS_SUCCESS) { | ||
return status; | ||
} | ||
``` | ||
|
||
Create an ACL entry | ||
``` | ||
sai_object_id_t acl_entry_id = 0ULL; | ||
acl_entry_attrs[0].id = SAI_ACL_ENTRY_ATTR_TABLE_ID; | ||
acl_entry_attrs[0].value.oid = acl_table_id; | ||
acl_entry_attrs[1].id = SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL; | ||
acl_entry_attrs[1].value.aclfield.data.u8 = 17; | ||
acl_entry_attrs[1].value.aclfield.mask.u8 = 255; | ||
acl_entry_attrs[2].id = SAI_ACL_ENTRY_ATTR_ACTION_SET_VRF; | ||
acl_entry_attrs[2].value.aclaction.enable = true; | ||
acl_entry_attrs[2].value.aclaction.parameter.oid = vrf_oid; | ||
status = sai_acl_api->create_acl_entry(&acl_entry_id, 3, acl_entry_attrs); | ||
if (status != SAI_STATUS_SUCCESS) { | ||
return status; | ||
} | ||
``` | ||
|
||
Bind ACL table to switch | ||
``` | ||
switch_attr.id = SAI_SWITCH_ATTR_PRE_INGRESS_ACL; | ||
switch_attr.value.oid = acl_table_id; | ||
status = sai_switch_api->set_switch_attribute(switch_id, &switch_attr); | ||
if (status != SAI_STATUS_SUCCESS) { | ||
return status; | ||
} | ||
``` | ||
|
||
### Questions raised in earlier meeting | ||
* Would this apply to non-L3 traffic? | ||
* Yes if ACL contains L2 only match fields, but the VRF would be ignored as L3 lookup will not happen | ||
* What VRF if any would be in the punted packet metadata | ||
* Should be the VRF used for L3 lookup | ||
* Is this before or after decap? | ||
* The intent is to override the VRF used for L3 lookup. Tunnel decap yields the Tunnel Interface which is part of a VRF. After decap the inner packet’s DIP is used for the forwarding lookup. Ideally the inner packet’s headers should be used for VRF override in case the tunnel decap has happened. | ||
* What about other RIF properties? | ||
* Only VRF is overridden, other RIF properties are retained. |
Oops, something went wrong.