You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
bgp/policy: fix match-prefix-set to accept covered sub-prefixes
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 is extracted into a private
prefix_set_contains helper so it can be unit-tested directly.
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.
0 commit comments