Work In Progress
This document describes the design and implementation to support dynamic configuration in Segment Routing.
What is Dynamic Interface Configuration?
When the interface configuration is updated after its initial configuration is set up, corresponding flow rules are also needed to be updated.
Dynamic Interface Configuration allows to update those flow table entries when the interface configuration is updated.
How It Works?
- Interface configuration is updated by REST API. (/network/configuration)
- REST API only allows to update one interface at a time.
- Among the interface configuration, following four entities are considered:
- ips: Array of String
- vlan-untagged: Integer
- vlan-tagged: Array of Integer
- vlan-native: Integer
- Old configuration and new configuration are compared to find out the removed entities and added entities (IP addresses, subnet configuration, and vlan IDs).
- Flow rules corresponding to the removed IP addresses, subnet, and vlan IDs are revoked.
- Flow rules corresponding to the added IP addresses, subnet, and vlan IDs are populated.
Changes made to the flow rules in detail
- IP address/subnet update
- Subnet population (Unicast Routing Table)
- Flow rules toward the interface's newly introduced subnet are populated in all other leaf switches.
- Flow rules toward the interface's subnet that is removed in the new configuration are revoked in all other leaf switches.
- Interface IP punt (ACL Table)
- Packets destined to the interface IP needs to be punted to the controller. IP punt rule is also updated according to the interface’s IP address change.
- Packets destined to the interface IP needs to be punted to the controller. IP punt rule is also updated according to the interface’s IP address change.
- Host unicast routing rule (Unicast Routing Table)
- For the hosts that are connected to the interface and not in the interface’s subnet with the updated configuration, unicast routing rule to that host will be revoked.
- Also, for the hosts that are connected to the interface and in the newly added subnet, unicast routing rule to that host will be populated.
- Subnet population (Unicast Routing Table)
- VLAN update
- Filtering rules (VLAN Table)
- Filtering rules are updated to accept only packets from hosts with valid vlan configuration.
- Subnet broadcast rules / cross-connect / L2FG (Bridging Table, L2 Flood Group)
- When a vlan ID is removed from an interface configuration, corresponding port is also removed from L2FG for that vlan ID.
- When a vlan ID is added to an interface configuration, corresponding port is also added to L2FG for that vlan ID.
- Unicast bridging (Bridging Table)
- Bridging rules for the hosts attached to the interface are updated.
- In case of vlan mismatch between host configuration and updated interface configuration, bridging rule for the host is not populated.
- For example, if a host is untagged but the port becomes tagged without native vlan configuration, bridging rule to the host will not be populated.
- L2IG / L3 UG (L2 Interface Group, L3 Unicast Group)
- L2IG: The action applied to the packet (pop vlan) is updated according to the type of vlan in the new configuration.
- L3UG: Flow rule is updated to forward packets to the updated L2IG.
- Filtering rules (VLAN Table)
Examples
(Initial configuration and topology are from trellis.json.)
Case 1: Changing VLAN tag for untagged port
Configuration change is as follows:
Initial configuration
{ "ports" : { "of:0000000000000204/4" : { "interfaces" : [ { "ips" : [ "10.0.2.254/24" ], "vlan-untagged": 20 } ] } } }
Updated configuration
{ "ports" : { "of:0000000000000204/4" : { "interfaces" : [ { "ips" : [ "10.0.2.254/24" ], "vlan-untagged": 40 } ] } } }
Followings are the result of dynamic interface configuration.
(Unnecessary information and flow rules are omitted.)
Flow Rules (before update)
{tableId=10, appId=org.onosproject.segmentrouting, selector=[IN_PORT:4, VLAN_VID:None], treatment=DefaultTrafficTreatment{immediate=[VLAN_PUSH:vlan, VLAN_ID:20], transition=TABLE:20}} {tableId=20, appId=org.onosproject.segmentrouting, selector=[IN_PORT:4, ETH_DST:00:00:00:00:02:04, ETH_TYPE:ipv4, VLAN_VID:20], treatment=DefaultTrafficTreatment{transition=TABLE:30}} {tableId=20, appId=org.onosproject.segmentrouting, selector=[IN_PORT:4, ETH_DST:00:00:00:00:02:04, ETH_TYPE:mpls_unicast, VLAN_VID:20], treatment=DefaultTrafficTreatment{transition=TABLE:23}} {tableId=50, appId=org.onosproject.segmentrouting, selector=[VLAN_VID:20], treatment=DefaultTrafficTreatment{immediate=[], deferred=[GROUP:0x40140000], transition=TABLE:60}} {tableId=50, appId=org.onosproject.segmentrouting, selector=[VLAN_VID:40], treatment=DefaultTrafficTreatment{immediate=[], deferred=[GROUP:0x40280000], transition=TABLE:60}}
Flow rules (after update)
{tableId=10, appId=org.onosproject.segmentrouting, selector=[IN_PORT:4, VLAN_VID:None], treatment=DefaultTrafficTreatment{immediate=[VLAN_PUSH:vlan, VLAN_ID:40], transition=TABLE:20}} {tableId=20, appId=org.onosproject.segmentrouting, selector=[IN_PORT:4, ETH_DST:00:00:00:00:02:04, ETH_TYPE:ipv4, VLAN_VID:40], treatment=DefaultTrafficTreatment{transition=TABLE:30}} {tableId=20, appId=org.onosproject.segmentrouting, selector=[IN_PORT:4, ETH_DST:00:00:00:00:02:04, ETH_TYPE:mpls_unicast, VLAN_VID:40], treatment=DefaultTrafficTreatment{transition=TABLE:23}} {tableId=50, appId=org.onosproject.segmentrouting, selector=[VLAN_VID:20], treatment=DefaultTrafficTreatment{immediate=[], deferred=[GROUP:0x40140000], transition=TABLE:60}} {tableId=50, appId=org.onosproject.segmentrouting, selector=[VLAN_VID:40], treatment=DefaultTrafficTreatment{immediate=[], deferred=[GROUP:0x40280000], transition=TABLE:60}}
Groups (before update)
id=0x40140000, type=ALL, appId=org.onosproject.segmentrouting id=0x40140000, bucket=1, actions=[GROUP:0x140004] id=0x40140000, bucket=2, actions=[GROUP:0x140003] id=0x40280000, type=ALL, appId=org.onosproject.segmentrouting id=0x40280000, bucket=1, actions=[GROUP:0x280005] id=0x40280000, bucket=2, actions=[GROUP:0x280006] id=0x140003, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x140003, bucket=1, actions=[VLAN_POP, OUTPUT:3] id=0x140004, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x140004, bucket=1, actions=[VLAN_POP, OUTPUT:4] id=0x280005, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x280005, bucket=1, actions=[VLAN_POP, OUTPUT:5] id=0x280006, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x280006, bucket=1, actions=[VLAN_POP, OUTPUT:6]
Groups (after update)
id=0x40140000, type=ALL, appId=org.onosproject.segmentrouting id=0x40140000, bucket=1, actions=[GROUP:0x140003] id=0x40280000, type=ALL, appId=org.onosproject.segmentrouting id=0x40280000, bucket=1, actions=[GROUP:0x280005] id=0x40280000, bucket=2, actions=[GROUP:0x280006] id=0x40280000, bucket=3, actions=[GROUP:0x280004] id=0x140003, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x140003, bucket=1, actions=[VLAN_POP, OUTPUT:3] id=0x280004, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x280004, bucket=1, actions=[VLAN_POP, OUTPUT:4] id=0x280005, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x280005, bucket=1, actions=[VLAN_POP, OUTPUT:5] id=0x280006, type=INDIRECT, appId=org.onosproject.segmentrouting id=0x280006, bucket=1, actions=[VLAN_POP, OUTPUT:6]