Skip to content

Add initial prefix filter#1441

Open
ElodinLaarz wants to merge 19 commits intomasterfrom
afts-filter
Open

Add initial prefix filter#1441
ElodinLaarz wants to merge 19 commits intomasterfrom
afts-filter

Conversation

@ElodinLaarz
Copy link
Copy Markdown
Contributor

@ElodinLaarz ElodinLaarz commented Mar 11, 2026

Change Scope

  • We add a new container to filter the afts tree based on a named routing policy.
  • The change is backwards compatible, though it marks afts as a rw container rather than a ro container since we're adding a configuration leaf.

Platform Implementations

This request is being made without any existing implementations that I know of. We will be requesting this from the vendors. (and so we will need at least 2 approvals from different vendors)

Tree View

-        +--ro afts
+        +--rw afts
         |  +--ro ipv4-unicast
         |  |  +--ro ipv4-entry* [prefix]
         |  |     +--ro prefix    -> ../state/prefix
         |  |     +--ro state
         |  |        +--ro prefix?               oc-inet:ipv4-prefix
         |  |        +--ro counters
         |  |        |  x--ro packets-forwarded?          oc-yang:counter64
         |  |        |  x--ro octets-forwarded?           oc-yang:counter64
         |  |        |  x--ro packets-forwarded-backup?   oc-yang:counter64
         |  |        |  x--ro octets-forwarded-backup?    oc-yang:counter64
         |  |        +--ro entry-metadata?       binary
         |  |        +--ro origin-protocol?      identityref
         |  |        +--ro decapsulate-header?   oc-aftt:encapsulation-header-type
         |  +--ro ipv6-unicast
         |  |  +--ro ipv6-entry* [prefix]
         |  |     +--ro prefix    -> ../state/prefix
         |  |     +--ro state
         |  |        +--ro prefix?               oc-inet:ipv6-prefix
         |  |        +--ro counters
         |  |        |  x--ro packets-forwarded?          oc-yang:counter64
         |  |        |  x--ro octets-forwarded?           oc-yang:counter64
         |  |        |  x--ro packets-forwarded-backup?   oc-yang:counter64
         |  |        |  x--ro octets-forwarded-backup?    oc-yang:counter64
         |  |        +--ro entry-metadata?       binary
         |  |        +--ro origin-protocol?      identityref
         |  |        +--ro decapsulate-header?   oc-aftt:encapsulation-header-type
         |  +--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 counters
         |  |        |  x--ro packets-forwarded?   oc-yang:counter64
         |  |        |  x--ro octets-forwarded?    oc-yang:counter64
         |  |        +--ro entry-metadata?   binary
         |  +--ro mpls
         |  |  +--ro label-entry* [label]
         |  |     +--ro label    -> ../state/label
         |  |     +--ro state
         |  |        +--ro label?                     oc-mplst:mpls-label
         |  |        +--ro counters
         |  |        |  x--ro packets-forwarded?   oc-yang:counter64
         |  |        |  x--ro octets-forwarded?    oc-yang:counter64
         |  |        +--ro entry-metadata?            binary
         |  |        +--ro popped-mpls-label-stack*   oc-mplst:mpls-label
         |  +--ro ethernet
         |  |  +--ro mac-entry* [mac-address]
         |  |     +--ro mac-address    -> ../state/mac-address
         |  |     +--ro state
         |  |        +--ro mac-address?      oc-yang:mac-address
         |  |        +--ro counters
         |  |        |  x--ro packets-forwarded?   oc-yang:counter64
         |  |        |  x--ro octets-forwarded?    oc-yang:counter64
         |  |        +--ro entry-metadata?   binary
         |  +--ro state-synced
         |  |  +--ro state
         |  |     +--ro ipv4-unicast?   boolean
         |  |     +--ro ipv6-unicast?   boolean
         |  +--ro next-hop-groups
         |  |  +--ro next-hop-group* [id]
         |  |     +--ro id             -> ../state/id
         |  |     +--ro state
         |  |     |  +--ro id?                      uint64
         |  |     |  +--ro next-hop-group-name?     string
         |  |     |  +--ro programmed-id?           uint64
         |  |     |  +--ro color?                   uint64
         |  |     |  +--ro backup-next-hop-group?   -> ../../../next-hop-group/state/id
         |  |     |  +--ro backup-active?           boolean
         |  |     +--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 conditional
         |  |        +--ro condition* [id]
         |  |           +--ro id                  -> ../state/id
         |  |           +--ro state
         |  |           |  +--ro id?               uint64
         |  |           |  +--ro dscp*             oc-inet:dscp
         |  |           |  +--ro next-hop-group?   -> ../../../../../next-hop-group/state/id
         |  |           +--ro input-interfaces
         |  |              +--ro input-interface* [id]
         |  |                 +--ro id       -> ../state/id
         |  |                 +--ro state
         |  |                    +--ro id?             string
         |  |                    +--ro interface?      -> /oc-if:interfaces/interface/name
         |  |                    +--ro subinterface?   -> /oc-if:interfaces/interface[oc-if:name=current()/../interface]/subinterfaces/subinterface/index
         |  +--ro next-hops
-        |     +--ro next-hop* [index]
-        |        +--ro index            -> ../state/index
-        |        +--ro state
-        |        |  +--ro index?                     uint64
-        |        |  +--ro programmed-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 origin-protocol?           identityref
-        |        |  +--ro lsp-name?                  string
-        |        |  +--ro counters
-        |        |  |  x--ro packets-forwarded?   oc-yang:counter64
-        |        |  |  x--ro octets-forwarded?    oc-yang:counter64
-        |        |  +--ro vni-label?                 oc-evpn-types:evi-id
-        |        |  +--ro tunnel-src-ip-address?     oc-inet:ip-address
-        |        +--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:ipv4-address
-        |        |     |     +--ro dst-ip?         oc-inet:ipv4-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:ipv6-address
-        |        |     |     +--ro dst-ip?         oc-inet:ipv6-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 vxlan
-        |        |        +--ro state
-        |        |           +--ro vni-label?               oc-evpn-types:evi-id
-        |        |           +--ro tunnel-src-ip-address?   oc-inet:ip-address
-        |        +--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
+        |  |  +--ro next-hop* [index]
+        |  |     +--ro index            -> ../state/index
+        |  |     +--ro state
+        |  |     |  +--ro index?                     uint64
+        |  |     |  +--ro programmed-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 origin-protocol?           identityref
+        |  |     |  +--ro lsp-name?                  string
+        |  |     |  +--ro counters
+        |  |     |  |  x--ro packets-forwarded?   oc-yang:counter64
+        |  |     |  |  x--ro octets-forwarded?    oc-yang:counter64
+        |  |     |  +--ro vni-label?                 oc-evpn-types:evi-id
+        |  |     |  +--ro tunnel-src-ip-address?     oc-inet:ip-address
+        |  |     +--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:ipv4-address
+        |  |     |     |     +--ro dst-ip?         oc-inet:ipv4-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:ipv6-address
+        |  |     |     |     +--ro dst-ip?         oc-inet:ipv6-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 vxlan
+        |  |     |        +--ro state
+        |  |     |           +--ro vni-label?               oc-evpn-types:evi-id
+        |  |     |           +--ro tunnel-src-ip-address?   oc-inet:ip-address
+        |  |     +--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
+        |  +--rw global-filter
+        |     +--rw config
+        |     |  +--rw ipv4-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name
+        |     |  +--rw ipv6-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name
+        |     +--ro state
+        |        +--ro ipv4-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name
+        |        +--ro ipv6-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name

Notably,

+        |  +--rw global-filter
+        |     +--rw config
+        |     |  +--rw ipv4-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name
+        |     |  +--rw ipv6-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name
+        |     +--ro state
+        |        +--ro ipv4-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name
+        |        +--ro ipv6-policy?   -> /oc-rpol:routing-policy/policy-definitions/policy-definition/config/name

Is the part being added (and the rest are part of the diff because there's an extra | at the start of the line).

Feature Profile Testing

Some of the functionality / expected behavior can be found in this feature profile PR.

@OpenConfigBot
Copy link
Copy Markdown

OpenConfigBot commented Mar 11, 2026

No major YANG version changes in commit e4534cb

Copy link
Copy Markdown
Contributor

@earies earies left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some instance data examples might also assist here. While a policy reference is meant to act as a filter that needs to evaluate to true, are all combinations of match/actions permitted here or will this focus on a subset in policy modeling (and if policy modeling expands over time)

@earies
Copy link
Copy Markdown
Contributor

earies commented Mar 11, 2026

Also in case its not obvious - if we think holistically, this could apply to many scenarios across subtrees where filtering is desirable on either policy matches or beyond - has there been consideration to other domains and if so, could this lead down a path of potential common filter block reuse

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

Some instance data examples might also assist here. While a policy reference is meant to act as a filter that needs to evaluate to true, are all combinations of match/actions permitted here or will this focus on a subset in policy modeling (and if policy modeling expands over time)

Added some info the description, and more details are in the test plan.

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

Also in case its not obvious - if we think holistically, this could apply to many scenarios across subtrees where filtering is desirable on either policy matches or beyond - has there been consideration to other domains and if so, could this lead down a path of potential common filter block reuse

In this case, we did do some internal discussion on whether or not it made sense to do the filtering at subscribe time, but in general it is a very hard problem-- in this case, we want to do the filtering at config time to give the box the ability to do some optimizations in matching against the policy-- otherwise, you need some sort of internal mechanism where the gnmi agents will need to have nontrivial interaction with other daemons on the device to learn how to do filtering. -- Also subscription time filtering would be less performant.

So, this change is purposely scoped to be very "narrow."

@ElodinLaarz ElodinLaarz moved this to Ready to discuss in OC Operator Review Mar 16, 2026
Copy link
Copy Markdown
Member

@dplore dplore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed in March 17, 2026 OC Operators meeting without objection. Setting to last call for March 31, 2026

@dplore dplore moved this from Ready to discuss to last-call in OC Operator Review Mar 17, 2026
@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

@ElodinLaarz
Copy link
Copy Markdown
Contributor Author

/gcbrun

Comment on lines +38 to +43
"Reference to a routing policy that is used to filter the
IPv6 prefixes that are present in the FIB. Only prefixes
that are accepted by the referenced policy are streamed.
The policy may, for example, use an explicit prefix set to
match prefixes, or match prefixes that are more specific than
a given prefix.";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Reference to a routing policy that is used to filter the
IPv6 prefixes that are present in the FIB. Only prefixes
that are accepted by the referenced policy are streamed.
The policy may, for example, use an explicit prefix set to
match prefixes, or match prefixes that are more specific than
a given prefix.";
"Reference to a routing policy that is used to filter the
IPv6 prefixes that are streamed from the FIB. This does
not affect which prefixes are installed in the FIB.
The policy may, for example, use an explicit prefix set to
match prefixes, or match prefixes that are more specific than
a given prefix.";

}
description
"Reference to a routing policy that is used to filter the
IPv4 prefixes that are in the FIB. Only prefixes
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above to clarify this only affects the streaming of prefixes.

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

Projects

Status: last-call

Development

Successfully merging this pull request may close these issues.

5 participants