Skip to content

Commit

Permalink
Merge pull request #1 from opencomputeproject/master
Browse files Browse the repository at this point in the history
merge from upstream
  • Loading branch information
mikeberesford authored Apr 20, 2021
2 parents 3dcf1f2 + 2c8dd5c commit 02636a4
Show file tree
Hide file tree
Showing 23 changed files with 1,227 additions and 106 deletions.
39 changes: 39 additions & 0 deletions azure-pipelines.yml
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"
114 changes: 114 additions & 0 deletions doc/Override-VRF.md
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
158 changes: 158 additions & 0 deletions doc/Pre-Ingress-ACL.md
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.
Loading

0 comments on commit 02636a4

Please sign in to comment.