Peer at link-local addresses: fe80::1%eth0
A peer's endpoint may be a link-local IPv6 address with the interface it is on. Such a peer is the address and the interface together, wherever peers are told apart: admission, collisions, hold-downs, the refusal log, the status page. The interface is looked up by name each time it is needed, so one that appears later or is made anew is found. Our routes go out with our link-local address in both places of MP_REACH_NLRI's next hop, as FRR sends its own. A peer's link-local next hop is taken alone, twice, or after "::" (BIRD), and resolved in the kernel on the interface of the session rather than by looking fe80::/64 up, which every interface has. The lab has a new phase, linklocal: sessions with FRR (by interface, with radvd beside the daemon) and BIRD over a LAN with link-local addresses only, both families, pings across, the interface down and up. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
92e013ca01
commit
fd2248feb5
38 files changed
+975
-151
No files matched your search
@@ -17,6 +17,7 @@ use bgp_primitives::ip_prefix::IpPrefix;
|
||||
use bgp_rib::table::{PeerIndex, RibTable, Route, RouteRef};
|
||||
use bgp_rib::{LocalRoute, RibStopped};
|
||||
use bgp_rpki::{CacheState, Update};
|
||||
use bgp_server::address::{PeerAddress, socket_text};
|
||||
use bgp_server::policy::PeerRole;
|
||||
use bgp_server::rpki::PathCheck;
|
||||
use bgp_server::session::{ConfiguredPeer, DialState, PeerId, SessionHandle, SessionRegistry};
|
||||
@@ -97,11 +98,11 @@ impl From<&SessionHandle> for PeerView {
|
||||
fn from(s: &SessionHandle) -> Self {
|
||||
Self {
|
||||
name: s.name.clone(),
|
||||
peer_addr: s.peer.addr.to_string(),
|
||||
peer_addr: socket_text(s.peer.addr),
|
||||
peer_asn: s.peer.asn,
|
||||
state: "Established".into(),
|
||||
direction: Some(s.direction.as_str().into()),
|
||||
local_addr: Some(s.local_addr.to_string()),
|
||||
local_addr: Some(socket_text(s.local_addr)),
|
||||
established_at_unix: Some(unix_secs(s.established_at)),
|
||||
uptime_secs: Some(s.established_at.elapsed().map(|d| d.as_secs()).unwrap_or(0)),
|
||||
four_octet_asn: Some(s.four_octet_asn),
|
||||
@@ -131,7 +132,7 @@ impl PeerView {
|
||||
};
|
||||
Self {
|
||||
name: Some(peer.name.clone()),
|
||||
peer_addr: peer.endpoint.to_string(),
|
||||
peer_addr: peer.endpoint.with_port(),
|
||||
peer_asn: peer.remote_asn,
|
||||
state: state_name.into(),
|
||||
direction: None,
|
||||
@@ -165,7 +166,7 @@ pub fn peer_views(registry: &SessionRegistry) -> Vec<PeerView> {
|
||||
.map(|(peer, state)| {
|
||||
match sessions
|
||||
.iter()
|
||||
.find(|s| s.peer.addr.ip() == peer.endpoint.ip() && s.peer.asn == peer.remote_asn)
|
||||
.find(|s| peer.endpoint.is_at(s.peer.addr.into()) && s.peer.asn == peer.remote_asn)
|
||||
{
|
||||
Some(session) => {
|
||||
claimed.insert(session.peer);
|
||||
@@ -332,11 +333,10 @@ impl PeerNames {
|
||||
|
||||
/// The peers that `wanted` names: by configured name, or by address.
|
||||
fn matching(&self, wanted: &str) -> Vec<PeerIndex> {
|
||||
let address: Option<IpAddr> = wanted.parse().ok();
|
||||
self.peers
|
||||
.iter()
|
||||
.filter(|(_, (peer, name, _))| {
|
||||
name.as_deref() == Some(wanted) || address == Some(peer.addr.ip())
|
||||
name.as_deref() == Some(wanted) || PeerAddress::from(peer.addr).is_called(wanted)
|
||||
})
|
||||
.map(|(index, _)| *index)
|
||||
.collect()
|
||||
@@ -351,7 +351,7 @@ impl PeerNames {
|
||||
let (attributes, next_hop) = route.attrs.attributes().unwrap_or_default();
|
||||
Some(ReceivedRouteView {
|
||||
peer_name: name.clone(),
|
||||
peer_addr: peer.addr.to_string(),
|
||||
peer_addr: socket_text(peer.addr),
|
||||
peer_asn: peer.asn,
|
||||
prefix: route.prefix.to_string(),
|
||||
path_id: route.path_id,
|
||||
@@ -972,7 +972,7 @@ pub async fn rejected_routes(
|
||||
query
|
||||
.peer
|
||||
.as_deref()
|
||||
.is_none_or(|wanted| record.label() == wanted || wanted.parse() == Ok(*address))
|
||||
.is_none_or(|wanted| record.label() == wanted || address.is_called(wanted))
|
||||
})
|
||||
.map(|(address, record)| RefusalsView {
|
||||
peer: record.label().to_string(),
|
||||
@@ -1023,6 +1023,7 @@ mod tests {
|
||||
asn: 65000 + u32::from(n),
|
||||
router_id: Ipv4Addr::new(10, 0, 0, n),
|
||||
address: Ipv4Addr::new(192, 0, 2, n).into(),
|
||||
interface: 0,
|
||||
ibgp: false,
|
||||
})
|
||||
.unwrap()
|
||||
|
||||
Reference in new issue
Block a user