bgp/policy: fix match-prefix-set to accept covered sub-prefixes#122
Open
kroudy wants to merge 1 commit into
Open
bgp/policy: fix match-prefix-set to accept covered sub-prefixes#122kroudy wants to merge 1 commit into
kroudy wants to merge 1 commit into
Conversation
The MatchPrefixSet condition currently requires exact network-address equality between the candidate prefix and the prefix-set entry's ip-prefix. This rejects sub-prefixes that are tree-wise covered by the entry's ip-prefix even when their length falls within the mask-length range. The ietf-routing-policy YANG module shipped with Holo (published as RFC 9067, "A YANG Data Model for Routing Policy") describes the `prefix` grouping as expressing a mask-length range for a covering ip-prefix. The YANG text's worked example is ambiguous on whether "range" means literal same-network-address-with-varying-length or tree-wise containment, but peer implementations converge on the containment reading: FRR (lib/plist.c), BIRD (filter/tree.c), Cisco IOS `ip prefix-list ... le N`, and Juniper `prefix-list-filter` all treat the entry as a covering pattern. That is also what operators reach for by default, so containment is the principle of least surprise. Switch to IpNetwork::contains(prefix.ip()), which returns true when the candidate's network address lies within the range's covering prefix. The match logic lives as a `PrefixSet::matches` method in holo-utils so it can be unit-tested directly and reused by other protocol crates; holo-bgp's MatchPrefixSet condition calls `set.matches(prefix)`. Semantics change disclosure: this is strictly more permissive. Existing `mask-length-lower == mask-length-upper` entries (the IETF "exact-match" pattern, which the existing topo1-1 conformance tests use) are unaffected because the length constraint still rules out any prefix whose length differs from the anchor. Ranged entries start matching covered sub-prefixes as intended. Non-canonical ip-prefix entries (stored verbatim by the northbound) are now interpreted as their covering network rather than matching only a literal host IP; this is consistent with how FRR/BIRD/Cisco/Juniper treat the same input. Nine unit tests cover exact-length entries, ranged entries, length-bound rejection, supernet and disjoint rejection, multi-entry OR semantics, IPv6 parity, the `0.0.0.0/0 [0, 32]` match-any pattern, empty prefix-sets, and non-canonical anchor behavior.
27a561a to
1f4ce5c
Compare
Contributor
Author
|
Good call — done. The logic now lives as Verified: |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The MatchPrefixSet condition currently requires exact network-address equality between the candidate prefix and the prefix-set entry's ip-prefix. This rejects sub-prefixes that are tree-wise covered by the entry's ip-prefix even when their length falls within the mask-length range.
The ietf-routing-policy YANG module shipped with Holo (published as RFC 9067, "A YANG Data Model for Routing Policy") describes the
prefixgrouping as expressing a mask-length range for a covering ip-prefix. The YANG text's worked example is ambiguous on whether "range" means literal same-network-address-with-varying-length or tree-wise containment, but peer implementations converge on the containment reading: FRR (lib/plist.c), BIRD (filter/tree.c), Cisco IOSip prefix-list ... le N, and Juniperprefix-list-filterall treat the entry as a covering pattern. That is also what operators reach for by default, so containment is the principle of least surprise.Switch to IpNetwork::contains(prefix.ip()), which returns true when the candidate's network address lies within the range's covering prefix. The match logic lives as a
PrefixSet::matchesmethod in holo-utils so it can be unit-tested directly and reused by other protocol crates; holo-bgp's MatchPrefixSet condition callsset.matches(prefix).Semantics change disclosure: this is strictly more permissive. Existing
mask-length-lower == mask-length-upperentries (the IETF "exact-match" pattern, which the existing topo1-1 conformance tests use) are unaffected because the length constraint still rules out any prefix whose length differs from the anchor. Ranged entries start matching covered sub-prefixes as intended. Non-canonical ip-prefix entries (stored verbatim by the northbound) are now interpreted as their covering network rather than matching only a literal host IP; this is consistent with how FRR/BIRD/Cisco/Juniper treat the same input.Nine unit tests cover exact-length entries, ranged entries, length-bound rejection, supernet and disjoint rejection, multi-entry OR semantics, IPv6 parity, the
0.0.0.0/0 [0, 32]match-any pattern, empty prefix-sets, and non-canonical anchor behavior.