}
/* Replace all private ASNs with our own ASN */
-struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn)
+struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn,
+ as_t peer_asn)
{
struct aspath *new;
struct assegment *seg;
int i;
for (i = 0; i < seg->length; i++) {
- if (BGP_AS_IS_PRIVATE(seg->as[i]))
+ /* Don't replace if public ASN or peer's ASN */
+ if (BGP_AS_IS_PRIVATE(seg->as[i])
+ && (seg->as[i] != peer_asn))
seg->as[i] = asn;
}
seg = seg->next;
}
/* Remove all private ASNs */
-struct aspath *aspath_remove_private_asns(struct aspath *aspath)
+struct aspath *aspath_remove_private_asns(struct aspath *aspath, as_t peer_asn)
{
struct aspath *new;
struct assegment *seg;
}
}
- // The entire segment is private so skip it
- if (!public) {
- seg = seg->next;
- continue;
- }
-
// The entire segment is public so copy it
- else if (public == seg->length) {
+ if (public == seg->length)
new_seg = assegment_dup(seg);
- }
// The segment is a mix of public and private ASNs. Copy as many
// spots as
new_seg = assegment_new(seg->type, public);
j = 0;
for (i = 0; i < seg->length; i++) {
- // ASN is public
- if (!BGP_AS_IS_PRIVATE(seg->as[i])) {
+ // keep ASN if public or matches peer's ASN
+ if (!BGP_AS_IS_PRIVATE(seg->as[i])
+ || (seg->as[i] == peer_asn)) {
new_seg->as[j] = seg->as[i];
j++;
}
as_t target_asn,
as_t our_asn);
extern struct aspath *aspath_replace_private_asns(struct aspath *aspath,
- as_t asn);
-extern struct aspath *aspath_remove_private_asns(struct aspath *aspath);
+ as_t asn, as_t peer_asn);
+extern struct aspath *aspath_remove_private_asns(struct aspath *aspath,
+ as_t peer_asn);
extern int aspath_firstas_check(struct aspath *, as_t);
extern int aspath_confed_check(struct aspath *);
extern int aspath_left_confed_check(struct aspath *);
peer, afi, safi,
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
attr->aspath = aspath_replace_private_asns(
- attr->aspath, bgp->as);
+ attr->aspath, bgp->as, peer->as);
// The entire aspath consists of private ASNs so create
// an empty aspath
// the private ASNs
else
attr->aspath = aspath_remove_private_asns(
- attr->aspath);
+ attr->aspath, peer->as);
}
// 'all' was not specified so the entire aspath must be private
peer, afi, safi,
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
attr->aspath = aspath_replace_private_asns(
- attr->aspath, bgp->as);
+ attr->aspath, bgp->as, peer->as);
else
attr->aspath = aspath_empty_get();
}