Check roles in OPEN and prevent route leaks with Only to Customer (RFC 9234)
A peer's configured role now does three more things: - Our OPEN carries the BGP Role capability with what we are to the peer. A peer whose own says it is something that does not pair with that, or that sends two different roles, is refused with OPEN Message Error / Role Mismatch. A peer that says nothing is accepted unless require_role is set. A role on a peer in our own AS is a configuration error. - Routes from a provider, a peer or a route server are marked Only to Customer on the way in if they are not already, and our routes are marked on the way out to a customer, a peer or a route server client. - A marked route from a customer or route server client, or from a peer with someone else's mark, is a leak and is refused. No policy setting turns that off. The packet crate gains the Only to Customer attribute (malformed: treat-as-withdraw), and the Role Mismatch subcode is corrected from 8 to 11. The status page shows whether the peer confirmed its role. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
8086aa994f
commit
f9ef781d51
30 files changed
+1128
-25
No files matched your search
@@ -358,13 +358,28 @@ impl AttrStore {
|
||||
wire: &[u8],
|
||||
next_hop: Option<&NlriNextHop>,
|
||||
) -> Option<Arc<AttrSet>> {
|
||||
let Some(next_hop) = next_hop else {
|
||||
self.intern_received_with(wire, &[], next_hop)
|
||||
}
|
||||
|
||||
/// As [`AttrStore::intern_received`], with attributes of our own after
|
||||
/// the peer's: `added` is one or more whole attributes in the same
|
||||
/// form, of types that `wire` does not have.
|
||||
pub fn intern_received_with(
|
||||
&self,
|
||||
wire: &[u8],
|
||||
added: &[u8],
|
||||
next_hop: Option<&NlriNextHop>,
|
||||
) -> Option<Arc<AttrSet>> {
|
||||
if added.is_empty() && next_hop.is_none() {
|
||||
return self.intern_wire(wire);
|
||||
};
|
||||
let mut with_next_hop = BytesMut::with_capacity(wire.len() + 36);
|
||||
with_next_hop.put_slice(wire);
|
||||
encode_next_hop(next_hop, &mut with_next_hop);
|
||||
self.intern_wire(&with_next_hop)
|
||||
}
|
||||
let mut whole = BytesMut::with_capacity(wire.len() + added.len() + 36);
|
||||
whole.put_slice(wire);
|
||||
whole.put_slice(added);
|
||||
if let Some(next_hop) = next_hop {
|
||||
encode_next_hop(next_hop, &mut whole);
|
||||
}
|
||||
self.intern_wire(&whole)
|
||||
}
|
||||
|
||||
/// How many distinct sets are stored.
|
||||
|
||||
Reference in new issue
Block a user