diff --git a/holo-bgp/src/events.rs b/holo-bgp/src/events.rs index 331ca0f8..176f8cd0 100644 --- a/holo-bgp/src/events.rs +++ b/holo-bgp/src/events.rs @@ -166,6 +166,7 @@ fn process_nbr_update( rib, reach.prefixes.clone(), attrs, + instance.config.asn, instance.shared, &instance.state.policy_apply_tasks, ); @@ -192,6 +193,7 @@ fn process_nbr_update( rib, prefixes, attrs, + instance.config.asn, instance.shared, &instance.state.policy_apply_tasks, ); @@ -208,6 +210,7 @@ fn process_nbr_update( rib, prefixes, attrs, + instance.config.asn, instance.shared, &instance.state.policy_apply_tasks, ); @@ -257,7 +260,8 @@ fn process_nbr_reach_prefixes( nbr: &Neighbor, rib: &mut Rib, nlri_prefixes: Vec, - attrs: Attrs, + mut attrs: Attrs, + local_asn: u32, shared: &InstanceShared, policy_apply_tasks: &PolicyApplyTasks, ) where @@ -278,6 +282,12 @@ fn process_nbr_reach_prefixes( PeerType::External => RouteType::External, }; + if nbr.config.as_path_options.replace_peer_as { + // Replace occurrences of the peer's AS in the AS_PATH with the local + // autonomous system number. + attrs.base.as_path.replace(nbr.config.peer_as, local_asn); + } + // Update pre-policy Adj-RIB-In routes. let table = A::table(&mut rib.tables); let route_attrs = rib.attr_sets.get_route_attr_sets(attrs.clone()); diff --git a/holo-bgp/src/packet/attribute.rs b/holo-bgp/src/packet/attribute.rs index f53ea767..aa9c99bd 100644 --- a/holo-bgp/src/packet/attribute.rs +++ b/holo-bgp/src/packet/attribute.rs @@ -705,6 +705,16 @@ impl AsPath { } } + pub(crate) fn replace(&mut self, from: u32, to: u32) { + for segment in self.segments.iter_mut() { + for member in segment.members.iter_mut() { + if *member == from { + *member = to; + } + } + } + } + pub(crate) fn contains(&self, asn: u32) -> bool { self.segments.iter().any(|segment| segment.contains(asn)) }