Skip to content

Conversation

@cscarpitta
Copy link

This pull request introduces a YANG model necessary to support the configuration of SRv6 through gRIBI.

Signed-off-by: Carmine Scarpitta <[email protected]>
@google-cla
Copy link

google-cla bot commented Dec 5, 2025

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@robshakir
Copy link
Member

Existing tree:

module: gribi-aft
  +--ro afts
     +--ro ipv4-unicast
     |  +--ro ipv4-entry* [prefix]
     |     +--ro prefix    -> ../state/prefix
     |     +--ro state
     |        +--ro prefix?                            oc-inet:ipv4-prefix
     |        +--ro entry-metadata?                    binary
     |        +--ro decapsulate-header?                oc-aftt:encapsulation-header-type
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro ipv6-unicast
     |  +--ro ipv6-entry* [prefix]
     |     +--ro prefix    -> ../state/prefix
     |     +--ro state
     |        +--ro prefix?                            oc-inet:ipv6-prefix
     |        +--ro entry-metadata?                    binary
     |        +--ro decapsulate-header?                oc-aftt:encapsulation-header-type
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro policy-forwarding
     |  +--ro policy-forwarding-entry* [index]
     |     +--ro index    -> ../state/index
     |     +--ro state
     |        +--ro index?                             uint64
     |        +--ro ip-prefix?                         oc-inet:ip-prefix
     |        +--ro mac-address?                       oc-yang:mac-address
     |        +--ro mpls-label?                        oc-mplst:mpls-label
     |        +--ro mpls-tc?                           oc-mplst:mpls-tc
     |        +--ro ip-dscp?                           oc-inet:dscp
     |        +--ro ip-protocol?                       oc-pkt-match-types:ip-protocol-type
     |        +--ro l4-src-port?                       oc-inet:port-number
     |        +--ro l4-dst-port?                       oc-inet:port-number
     |        +--ro entry-metadata?                    binary
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro mpls
     |  +--ro label-entry* [label]
     |     +--ro label    -> ../state/label
     |     +--ro state
     |        +--ro label?                             oc-mplst:mpls-label
     |        +--ro entry-metadata?                    binary
     |        +--ro popped-mpls-label-stack*           oc-mplst:mpls-label
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro ethernet
     |  +--ro mac-entry* [mac-address]
     |     +--ro mac-address    -> ../state/mac-address
     |     +--ro state
     |        +--ro mac-address?                       oc-yang:mac-address
     |        +--ro entry-metadata?                    binary
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro next-hop-groups
     |  +--ro next-hop-group* [id]
     |     +--ro id           -> ../state/id
     |     +--ro state
     |     |  +--ro id?                      uint64
     |     |  +--ro color?                   uint64
     |     |  +--ro backup-next-hop-group?   -> ../../../next-hop-group/state/id
     |     +--ro next-hops
     |        +--ro next-hop* [index]
     |           +--ro index    -> ../state/index
     |           +--ro state
     |              +--ro index?    -> ../../../../../../next-hops/next-hop/state/index
     |              +--ro weight?   uint64
     +--ro next-hops
        +--ro next-hop* [index]
           +--ro index            -> ../state/index
           +--ro state
           |  +--ro index?                     uint64
           |  +--ro ip-address?                oc-inet:ip-address
           |  +--ro mac-address?               oc-yang:mac-address
           |  +--ro pop-top-label?             boolean
           |  +--ro pushed-mpls-label-stack*   oc-mplst:mpls-label
           |  +--ro encapsulate-header?        oc-aftt:encapsulation-header-type
           |  +--ro decapsulate-header?        oc-aftt:encapsulation-header-type
           |  +--ro vni-label?                 oc-evpn-types:evi-id
           |  +--ro tunnel-src-ip-address?     oc-inet:ip-address
           |  +--ro network-instance?          string
           +--ro ip-in-ip
           |  +--ro state
           |     +--ro src-ip?   oc-inet:ip-address
           |     +--ro dst-ip?   oc-inet:ip-address
           +--ro gre
           |  +--ro state
           |     +--ro src-ip?   oc-inet:ip-address
           |     +--ro dst-ip?   oc-inet:ip-address
           |     +--ro ttl?      uint8
           +--ro encap-headers
           |  +--ro encap-header* [index]
           |     +--ro index     -> ../state/index
           |     +--ro state
           |     |  +--ro index?   uint8
           |     |  +--ro type?    oc-aftt:encapsulation-header-type
           |     +--ro gre
           |     |  +--ro state
           |     |     +--ro src-ip?   oc-inet:ip-address
           |     |     +--ro dst-ip?   oc-inet:ip-address
           |     |     +--ro ttl?      uint8
           |     +--ro ipv4
           |     |  +--ro state
           |     |     +--ro src-ip?   oc-inet:ip-address
           |     |     +--ro dst-ip?   oc-inet:ip-address
           |     +--ro ipv6
           |     |  +--ro state
           |     |     +--ro src-ip?   oc-inet:ip-address
           |     |     +--ro dst-ip?   oc-inet:ip-address
           |     +--ro mpls
           |     |  +--ro state
           |     |     +--ro traffic-class?      oc-mplst:mpls-tc
           |     |     +--ro mpls-label-stack*   oc-mplst:mpls-label
           |     +--ro udp-v4
           |     |  +--ro state
           |     |     +--ro src-ip?         oc-inet:ip-address
           |     |     +--ro dst-ip?         oc-inet:ip-address
           |     |     +--ro dscp?           oc-inet:dscp
           |     |     +--ro src-udp-port?   oc-inet:port-number
           |     |     +--ro dst-udp-port?   oc-inet:port-number
           |     |     +--ro ip-ttl?         uint8
           |     +--ro udp-v6
           |        +--ro state
           |           +--ro src-ip?         oc-inet:ip-address
           |           +--ro dst-ip?         oc-inet:ip-address
           |           +--ro dscp?           oc-inet:dscp
           |           +--ro src-udp-port?   oc-inet:port-number
           |           +--ro dst-udp-port?   oc-inet:port-number
           |           +--ro ip-ttl?         uint8
           +--ro interface-ref
              +--ro state
                 +--ro interface?      -> /oc-if:interfaces/interface/name
                 +--ro subinterface?   -> /oc-if:interfaces/interface[oc-if:name=current()/../interface]/subinterfaces/subinterface/index

@robshakir
Copy link
Member

Proposed tree:

module: gribi-aft
  +--ro afts
     +--ro ipv4-unicast
     |  +--ro ipv4-entry* [prefix]
     |     +--ro prefix    -> ../state/prefix
     |     +--ro state
     |        +--ro prefix?                            oc-inet:ipv4-prefix
     |        +--ro entry-metadata?                    binary
     |        +--ro decapsulate-header?                oc-aftt:encapsulation-header-type
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro ipv6-unicast
     |  +--ro ipv6-entry* [prefix]
     |     +--ro prefix    -> ../state/prefix
     |     +--ro state
     |        +--ro prefix?                            oc-inet:ipv6-prefix
     |        +--ro entry-metadata?                    binary
     |        +--ro decapsulate-header?                oc-aftt:encapsulation-header-type
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro policy-forwarding
     |  +--ro policy-forwarding-entry* [index]
     |     +--ro index    -> ../state/index
     |     +--ro state
     |        +--ro index?                             uint64
     |        +--ro ip-prefix?                         oc-inet:ip-prefix
     |        +--ro mac-address?                       oc-yang:mac-address
     |        +--ro mpls-label?                        oc-mplst:mpls-label
     |        +--ro mpls-tc?                           oc-mplst:mpls-tc
     |        +--ro ip-dscp?                           oc-inet:dscp
     |        +--ro ip-protocol?                       oc-pkt-match-types:ip-protocol-type
     |        +--ro l4-src-port?                       oc-inet:port-number
     |        +--ro l4-dst-port?                       oc-inet:port-number
     |        +--ro entry-metadata?                    binary
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro mpls
     |  +--ro label-entry* [label]
     |     +--ro label    -> ../state/label
     |     +--ro state
     |        +--ro label?                             oc-mplst:mpls-label
     |        +--ro entry-metadata?                    binary
     |        +--ro popped-mpls-label-stack*           oc-mplst:mpls-label
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro ethernet
     |  +--ro mac-entry* [mac-address]
     |     +--ro mac-address    -> ../state/mac-address
     |     +--ro state
     |        +--ro mac-address?                       oc-yang:mac-address
     |        +--ro entry-metadata?                    binary
     |        +--ro next-hop-group?                    uint64
     |        +--ro next-hop-group-network-instance?   string
     +--ro srv6
     |  +--ro srv6-sid-entry* [sid]
     |     +--ro sid      -> ../state/sid
     |     +--ro state
     |        +--ro sid?              oc-inet:ipv6-prefix
     |        +--ro sid-params
     |        |  +--ro behavior-type              uint16
     |        |  +--ro lookup-network-instance?   string
     |        |  +--ro interface?                 if:interface-ref
     |        |  +--ro next-hop?                  oc-inet:ip-address
     |        |  +--ro encap-object-bsid
     |        |     +--ro encap-type?            enumeration
     |        |     +--ro srv6-sidlist*          oc-inet:ipv6-address
     |        |     +--ro sr-mpls-label-stack*   oc-mplst:mpls-label
     |        +--ro counters
     |        |  +--ro packets-forwarded?   oc-yang:counter64
     |        |  +--ro octets-forwarded?    oc-yang:counter64
     |        +--ro entry-metadata?   binary
     +--ro next-hop-groups
     |  +--ro next-hop-group* [id]
     |     +--ro id           -> ../state/id
     |     +--ro state
     |     |  +--ro id?                      uint64
     |     |  +--ro color?                   uint64
     |     |  +--ro backup-next-hop-group?   -> ../../../next-hop-group/state/id
     |     +--ro next-hops
     |        +--ro next-hop* [index]
     |           +--ro index    -> ../state/index
     |           +--ro state
     |              +--ro index?    -> ../../../../../../next-hops/next-hop/state/index
     |              +--ro weight?   uint64
     +--ro next-hops
        +--ro next-hop* [index]
           +--ro index            -> ../state/index
           +--ro state
           |  +--ro index?                     uint64
           |  +--ro ip-address?                oc-inet:ip-address
           |  +--ro mac-address?               oc-yang:mac-address
           |  +--ro pop-top-label?             boolean
           |  +--ro pushed-mpls-label-stack*   oc-mplst:mpls-label
           |  +--ro encapsulate-header?        oc-aftt:encapsulation-header-type
           |  +--ro decapsulate-header?        oc-aftt:encapsulation-header-type
           |  +--ro vni-label?                 oc-evpn-types:evi-id
           |  +--ro tunnel-src-ip-address?     oc-inet:ip-address
           |  +--ro network-instance?          string
           +--ro ip-in-ip
           |  +--ro state
           |     +--ro src-ip?          oc-inet:ip-address
           |     +--ro dst-ip?          oc-inet:ip-address
           |     +--ro srv6-sid-list*   oc-inet:ipv6-address
           |     +--ro flow-label?      uint32
           |     +--ro traffic-class?   uint8
           |     +--ro hop-limit?       uint8
           +--ro gre
           |  +--ro state
           |     +--ro src-ip?   oc-inet:ip-address
           |     +--ro dst-ip?   oc-inet:ip-address
           |     +--ro ttl?      uint8
           +--ro encap-headers
           |  +--ro encap-header* [index]
           |     +--ro index     -> ../state/index
           |     +--ro state
           |     |  +--ro index?   uint8
           |     |  +--ro type?    oc-aftt:encapsulation-header-type
           |     +--ro gre
           |     |  +--ro state
           |     |     +--ro src-ip?   oc-inet:ip-address
           |     |     +--ro dst-ip?   oc-inet:ip-address
           |     |     +--ro ttl?      uint8
           |     +--ro ipv4
           |     |  +--ro state
           |     |     +--ro src-ip?          oc-inet:ip-address
           |     |     +--ro dst-ip?          oc-inet:ip-address
           |     |     +--ro srv6-sid-list*   oc-inet:ipv6-address
           |     |     +--ro flow-label?      uint32
           |     |     +--ro traffic-class?   uint8
           |     |     +--ro hop-limit?       uint8
           |     +--ro ipv6
           |     |  +--ro state
           |     |     +--ro src-ip?          oc-inet:ip-address
           |     |     +--ro dst-ip?          oc-inet:ip-address
           |     |     +--ro srv6-sid-list*   oc-inet:ipv6-address
           |     |     +--ro flow-label?      uint32
           |     |     +--ro traffic-class?   uint8
           |     |     +--ro hop-limit?       uint8
           |     +--ro mpls
           |     |  +--ro state
           |     |     +--ro traffic-class?      oc-mplst:mpls-tc
           |     |     +--ro mpls-label-stack*   oc-mplst:mpls-label
           |     +--ro udp-v4
           |     |  +--ro state
           |     |     +--ro src-ip?         oc-inet:ip-address
           |     |     +--ro dst-ip?         oc-inet:ip-address
           |     |     +--ro dscp?           oc-inet:dscp
           |     |     +--ro src-udp-port?   oc-inet:port-number
           |     |     +--ro dst-udp-port?   oc-inet:port-number
           |     |     +--ro ip-ttl?         uint8
           |     +--ro udp-v6
           |        +--ro state
           |           +--ro src-ip?         oc-inet:ip-address
           |           +--ro dst-ip?         oc-inet:ip-address
           |           +--ro dscp?           oc-inet:dscp
           |           +--ro src-udp-port?   oc-inet:port-number
           |           +--ro dst-udp-port?   oc-inet:port-number
           |           +--ro ip-ttl?         uint8
           +--ro interface-ref
              +--ro state
                 +--ro interface?      -> /oc-if:interfaces/interface/name
                 +--ro subinterface?   -> /oc-if:interfaces/interface[oc-if:name=current()/../interface]/subinterfaces/subinterface/index

@robshakir
Copy link
Member

Diff from tree view:

➜  gribi git:(srv6_support) diff -prauwN ~/tmp/gribi-tree ~/tmp/gribi-tree-srv6
--- /Users/robjs/tmp/gribi-tree	2025-12-09 10:14:50
+++ /Users/robjs/tmp/gribi-tree-srv6	2025-12-09 10:15:16
@@ -51,6 +51,24 @@ module: gribi-aft
      |        +--ro entry-metadata?                    binary
      |        +--ro next-hop-group?                    uint64
      |        +--ro next-hop-group-network-instance?   string
+     +--ro srv6
+     |  +--ro srv6-sid-entry* [sid]
+     |     +--ro sid      -> ../state/sid
+     |     +--ro state
+     |        +--ro sid?              oc-inet:ipv6-prefix
+     |        +--ro sid-params
+     |        |  +--ro behavior-type              uint16
+     |        |  +--ro lookup-network-instance?   string
+     |        |  +--ro interface?                 if:interface-ref
+     |        |  +--ro next-hop?                  oc-inet:ip-address
+     |        |  +--ro encap-object-bsid
+     |        |     +--ro encap-type?            enumeration
+     |        |     +--ro srv6-sidlist*          oc-inet:ipv6-address
+     |        |     +--ro sr-mpls-label-stack*   oc-mplst:mpls-label
+     |        +--ro counters
+     |        |  +--ro packets-forwarded?   oc-yang:counter64
+     |        |  +--ro octets-forwarded?    oc-yang:counter64
+     |        +--ro entry-metadata?   binary
      +--ro next-hop-groups
      |  +--ro next-hop-group* [id]
      |     +--ro id           -> ../state/id
@@ -82,6 +100,10 @@ module: gribi-aft
            |  +--ro state
            |     +--ro src-ip?   oc-inet:ip-address
            |     +--ro dst-ip?   oc-inet:ip-address
+           |     +--ro srv6-sid-list*   oc-inet:ipv6-address
+           |     +--ro flow-label?      uint32
+           |     +--ro traffic-class?   uint8
+           |     +--ro hop-limit?       uint8
            +--ro gre
            |  +--ro state
            |     +--ro src-ip?   oc-inet:ip-address
@@ -102,10 +124,18 @@ module: gribi-aft
            |     |  +--ro state
            |     |     +--ro src-ip?   oc-inet:ip-address
            |     |     +--ro dst-ip?   oc-inet:ip-address
+           |     |     +--ro srv6-sid-list*   oc-inet:ipv6-address
+           |     |     +--ro flow-label?      uint32
+           |     |     +--ro traffic-class?   uint8
+           |     |     +--ro hop-limit?       uint8
            |     +--ro ipv6
            |     |  +--ro state
            |     |     +--ro src-ip?   oc-inet:ip-address
            |     |     +--ro dst-ip?   oc-inet:ip-address
+           |     |     +--ro srv6-sid-list*   oc-inet:ipv6-address
+           |     |     +--ro flow-label?      uint32
+           |     |     +--ro traffic-class?   uint8
+           |     |     +--ro hop-limit?       uint8
            |     +--ro mpls
            |     |  +--ro state
            |     |     +--ro traffic-class?      oc-mplst:mpls-tc

@robshakir
Copy link
Member

Paths diff:

➜  gribi git:(master) diff -prawuN /tmp/existing-paths /tmp/srv6-paths
--- /tmp/existing-paths	2025-12-09 10:19:29
+++ /tmp/srv6-paths	2025-12-09 10:19:15
@@ -50,6 +50,24 @@
 /afts/ethernet/mac-entry/state/entry-metadata
 /afts/ethernet/mac-entry/state/next-hop-group
 /afts/ethernet/mac-entry/state/next-hop-group-network-instance
+/afts/srv6
+/afts/srv6/srv6-sid-entry
+/afts/srv6/srv6-sid-entry/sid
+/afts/srv6/srv6-sid-entry/state
+/afts/srv6/srv6-sid-entry/state/sid
+/afts/srv6/srv6-sid-entry/state/sid-params
+/afts/srv6/srv6-sid-entry/state/sid-params/behavior-type
+/afts/srv6/srv6-sid-entry/state/sid-params/lookup-network-instance
+/afts/srv6/srv6-sid-entry/state/sid-params/interface
+/afts/srv6/srv6-sid-entry/state/sid-params/next-hop
+/afts/srv6/srv6-sid-entry/state/sid-params/encap-object-bsid
+/afts/srv6/srv6-sid-entry/state/sid-params/encap-object-bsid/encap-type
+/afts/srv6/srv6-sid-entry/state/sid-params/encap-object-bsid/srv6-sidlist
+/afts/srv6/srv6-sid-entry/state/sid-params/encap-object-bsid/sr-mpls-label-stack
+/afts/srv6/srv6-sid-entry/state/counters
+/afts/srv6/srv6-sid-entry/state/counters/packets-forwarded
+/afts/srv6/srv6-sid-entry/state/counters/octets-forwarded
+/afts/srv6/srv6-sid-entry/state/entry-metadata
 /afts/next-hop-groups
 /afts/next-hop-groups/next-hop-group
 /afts/next-hop-groups/next-hop-group/id
@@ -81,6 +99,10 @@
 /afts/next-hops/next-hop/ip-in-ip/state
 /afts/next-hops/next-hop/ip-in-ip/state/src-ip
 /afts/next-hops/next-hop/ip-in-ip/state/dst-ip
+/afts/next-hops/next-hop/ip-in-ip/state/srv6-sid-list
+/afts/next-hops/next-hop/ip-in-ip/state/flow-label
+/afts/next-hops/next-hop/ip-in-ip/state/traffic-class
+/afts/next-hops/next-hop/ip-in-ip/state/hop-limit
 /afts/next-hops/next-hop/gre
 /afts/next-hops/next-hop/gre/state
 /afts/next-hops/next-hop/gre/state/src-ip
@@ -101,10 +123,18 @@
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state/src-ip
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state/dst-ip
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state/srv6-sid-list
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state/flow-label
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state/traffic-class
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv4/state/hop-limit
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv6
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state/src-ip
 /afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state/dst-ip
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state/srv6-sid-list
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state/flow-label
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state/traffic-class
+/afts/next-hops/next-hop/encap-headers/encap-header/ipv6/state/hop-limit
 /afts/next-hops/next-hop/encap-headers/encap-header/mpls
 /afts/next-hops/next-hop/encap-headers/encap-header/mpls/state
 /afts/next-hops/next-hop/encap-headers/encap-header/mpls/state/traffic-class

@robshakir
Copy link
Member

A few comments:

  • Let's discuss what the difference between an SRv6 entry and an IPv6 entry is -- we should clarify how a device is intended to handle the two in terms of lookup logic.
  • lookup-network-instance is likely not required to match the current structure. The AFT subtree for telemetry is rooted under /network-instances/network-instance and the gRIBI proto itself has a network_instance field that is used to determine which VRF is being populated.
  • For the interface and next-hop leaves that are under the srv6-entry. I think this structure breaks how the current fundamental layout of the AFTs are in gRIBI. Particularly:
    • An XX-entry (IPv4 prefix, IPv6 prefix, MPLS label...) links to a next-hop-group which can be in the local or another network-instance. These entries tend to not have actions associated with them -- although an exception is a "pop" action for MPLS.
    • A next-hop-group contains a set of next-hops that have weights associated with them.
    • A next-hop then has where the packet is to be forwarded and any actions associated with it.
    • Based on this, I think I'd expect that the interface and next-hop can be programmed within a next-hop entry, and the SRv6 entries themselves don't include this. WDYT?
  • For the encap-object-bsid leaves. Can you explain to me why these are different to other encapsulation types? For SR-MPLS, how we have been doing this thus far is that we have a MPLS, IPv4 or IPv6 entry which has a NHG and then NH - each NH has a pushed-mpls-label-stack (although with the recent changes to encap-headers it would now have one or more entries in that list). Is there a reason that such an approach wouldn't work for the SRv6 SID list?
  • We probably need to modify the way that the flow-label, traffic-class and hop-limit are being specified since they now show up for IPv4 too. I think it sounds reasonable to add these (although I am not sure that all silicon can implement them today).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants