struct assegment *seg = aspath->segments;
as_t highest = 0;
unsigned int i;
-
+
while (seg)
{
for (i = 0; i < seg->length; i++)
- if (seg->as[i] > highest
- && (seg->as[i] < BGP_PRIVATE_AS_MIN
- || seg->as[i] > BGP_PRIVATE_AS_MAX))
+ if (seg->as[i] > highest && !BGP_AS_IS_PRIVATE(seg->as[i]))
highest = seg->as[i];
seg = seg->next;
}
aspath_private_as_check (struct aspath *aspath)
{
struct assegment *seg;
-
+
if ( !(aspath && aspath->segments) )
return 0;
-
+
seg = aspath->segments;
while (seg)
{
int i;
-
+
for (i = 0; i < seg->length; i++)
{
- if ( (seg->as[i] < BGP_PRIVATE_AS_MIN)
- || (seg->as[i] > BGP_PRIVATE_AS_MAX &&
- seg->as[i] < BGP_PRIVATE_AS4_MIN)
- || (seg->as[i] > BGP_PRIVATE_AS4_MAX))
+ if (!BGP_AS_IS_PRIVATE(seg->as[i]))
return 0;
}
seg = seg->next;
return 1;
}
+/* Replace all private ASNs with our own ASN */
+struct aspath *
+aspath_replace_private_asns (struct aspath *aspath, as_t asn)
+{
+ struct aspath *new;
+ struct assegment *seg;
+
+ new = aspath_dup(aspath);
+ seg = new->segments;
+
+ while (seg)
+ {
+ int i;
+
+ for (i = 0; i < seg->length; i++)
+ {
+ if (BGP_AS_IS_PRIVATE(seg->as[i]))
+ seg->as[i] = asn;
+ }
+ seg = seg->next;
+ }
+
+ aspath_str_update(new);
+ return new;
+}
+
+/* Remove all private ASNs */
+struct aspath *
+aspath_remove_private_asns (struct aspath *aspath)
+{
+ struct aspath *new;
+ struct assegment *seg;
+ struct assegment *new_seg;
+ struct assegment *last_new_seg;
+ int i;
+ int j;
+ int public = 0;
+
+ new = XCALLOC (MTYPE_AS_PATH, sizeof (struct aspath));
+
+ new_seg = NULL;
+ last_new_seg = NULL;
+ seg = aspath->segments;
+ while (seg)
+ {
+ public = 0;
+ for (i = 0; i < seg->length; i++)
+ {
+ // ASN is public
+ if (!BGP_AS_IS_PRIVATE(seg->as[i]))
+ {
+ public++;
+ }
+ }
+
+ // 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)
+ {
+ new_seg = assegment_dup (seg);
+ }
+
+ // The segment is a mix of public and private ASNs. Copy as many spots as
+ // there are public ASNs then come back and fill in only the public ASNs.
+ else
+ {
+ 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]))
+ {
+ new_seg->as[j] = seg->as[i];
+ j++;
+ }
+ }
+ }
+
+ // This is the first segment so set the aspath segments pointer to this one
+ if (!last_new_seg)
+ new->segments = new_seg;
+ else
+ last_new_seg->next = new_seg;
+
+ last_new_seg = new_seg;
+ seg = seg->next;
+ }
+
+ aspath_str_update(new);
+ return new;
+}
+
/* AS path confed check. If aspath contains confed set or sequence then return 1. */
int
aspath_confed_check (struct aspath *aspath)
return RMAP_PERMIT;
}
+
+/* If this is an EBGP peer with remove-private-AS */
+void
+bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
+ struct peer *peer, struct attr *attr)
+{
+ if (peer->sort == BGP_PEER_EBGP &&
+ peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS))
+ {
+ // Take action on the entire aspath
+ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
+ {
+ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+ attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
+
+ // The entire aspath consists of private ASNs so create an empty aspath
+ else if (aspath_private_as_check (attr->aspath))
+ attr->aspath = aspath_empty_get ();
+
+ // There are some public and some private ASNs, remove the private ASNs
+ else
+ attr->aspath = aspath_remove_private_asns (attr->aspath);
+ }
+
+ // 'all' was not specified so the entire aspath must be private ASNs
+ // for us to do anything
+ else if (aspath_private_as_check (attr->aspath))
+ {
+ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+ attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
+ else
+ attr->aspath = aspath_empty_get ();
+ }
+ }
+}
+
static int
bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi)
}
#endif /* HAVE_IPV6 */
- /* If this is EBGP peer and remove-private-AS is set. */
- if (peer->sort == BGP_PEER_EBGP
- && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
- && aspath_private_as_check (attr->aspath))
- attr->aspath = aspath_empty_get ();
+ bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
/* Route map & unsuppress-map apply. */
if (ROUTE_MAP_OUT_NAME (filter)
struct bgp_info info;
struct peer *from;
struct attr *riattr;
+ struct bgp *bgp;
from = ri->peer;
filter = &rsclient->filter[afi][safi];
+ bgp = rsclient->bgp;
riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
if (DISABLE_BGP_ANNOUNCE)
}
#endif /* HAVE_IPV6 */
-
- /* If this is EBGP peer and remove-private-AS is set. */
- if (rsclient->sort == BGP_PEER_EBGP
- && peer_af_flag_check (rsclient, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
- && aspath_private_as_check (attr->aspath))
- attr->aspath = aspath_empty_get ();
+ bgp_peer_remove_private_as(bgp, afi, safi, rsclient, attr);
/* Route map & unsuppress-map apply. */
if (ROUTE_MAP_OUT_NAME (filter) || (ri->extra && ri->extra->suppress) )
str = "Invalid command. Not an internal neighbor";
break;
case BGP_ERR_REMOVE_PRIVATE_AS:
- str = "Private AS cannot be removed for IBGP peers";
+ str = "remove-private-AS cannot be configured for IBGP peers";
break;
case BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP:
str = "Local-AS allowed only for EBGP peers";
NEIGHBOR_CMD2 "remove-private-AS",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Remove private AS number from outbound updates\n")
+ "Remove private ASNs in outbound updates\n")
{
+ peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
bgp_node_safi (vty),
PEER_FLAG_REMOVE_PRIVATE_AS);
}
+DEFUN (neighbor_remove_private_as_all,
+ neighbor_remove_private_as_all_cmd,
+ NEIGHBOR_CMD2 "remove-private-AS all",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Remove private ASNs in outbound updates\n"
+ "Apply to all AS numbers")
+{
+ peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
+ return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_REMOVE_PRIVATE_AS|
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
+}
+
+DEFUN (neighbor_remove_private_as_replace_as,
+ neighbor_remove_private_as_replace_as_cmd,
+ NEIGHBOR_CMD2 "remove-private-AS replace-AS",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Remove private ASNs in outbound updates\n"
+ "Replace private ASNs with our ASN in outbound updates\n")
+{
+ peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
+ return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_REMOVE_PRIVATE_AS|
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
+}
+
+DEFUN (neighbor_remove_private_as_all_replace_as,
+ neighbor_remove_private_as_all_replace_as_cmd,
+ NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Remove private ASNs in outbound updates\n"
+ "Apply to all AS numbers"
+ "Replace private ASNs with our ASN in outbound updates\n")
+{
+ return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_REMOVE_PRIVATE_AS|
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
+}
+
DEFUN (no_neighbor_remove_private_as,
no_neighbor_remove_private_as_cmd,
NO_NEIGHBOR_CMD2 "remove-private-AS",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Remove private AS number from outbound updates\n")
+ "Remove private ASNs in outbound updates\n")
{
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
bgp_node_safi (vty),
- PEER_FLAG_REMOVE_PRIVATE_AS);
+ PEER_FLAG_REMOVE_PRIVATE_AS|
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
}
+ALIAS (no_neighbor_remove_private_as,
+ no_neighbor_remove_private_as_all_cmd,
+ NO_NEIGHBOR_CMD2 "remove-private-AS all",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Remove private ASNs in outbound updates\n"
+ "Apply to all AS numbers")
+
+ALIAS (no_neighbor_remove_private_as,
+ no_neighbor_remove_private_as_replace_as_cmd,
+ NO_NEIGHBOR_CMD2 "remove-private-AS replace-AS",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Remove private ASNs in outbound updates\n"
+ "Replace private ASNs with our ASN in outbound updates\n")
+
+ALIAS (no_neighbor_remove_private_as,
+ no_neighbor_remove_private_as_all_replace_as_cmd,
+ NO_NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Remove private ASNs in outbound updates\n"
+ "Apply to all AS numbers"
+ "Replace private ASNs with our ASN in outbound updates\n")
+
+
/* neighbor send-community. */
DEFUN (neighbor_send_community,
neighbor_send_community_cmd,
vty_out (vty, " Route-Server Client%s", VTY_NEWLINE);
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
vty_out (vty, " Inbound soft reconfiguration allowed%s", VTY_NEWLINE);
- if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
- vty_out (vty, " Private AS number removed from updates to this neighbor%s", VTY_NEWLINE);
- if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF))
+ if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+ vty_out (vty, " Private AS numbers replaced in updates to this neighbor%s", VTY_NEWLINE);
+ else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
+ vty_out (vty, " Private AS numbers removed in updates to this neighbor%s", VTY_NEWLINE);
+
+ if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) ||
+ CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF_ALL))
vty_out (vty, " NEXT_HOP is always this router%s", VTY_NEWLINE);
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED))
vty_out (vty, " AS_PATH is propagated unchanged to this neighbor%s", VTY_NEWLINE);
/* "neighbor remove-private-AS" commands. */
install_element (BGP_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV4_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV4M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_IPV6M_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_IPV6M_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_all_cmd);
+ install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_all_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_replace_as_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_remove_private_as_all_replace_as_cmd);
+ install_element (BGP_VPNV4_NODE, &no_neighbor_remove_private_as_all_replace_as_cmd);
/* "neighbor send-community" commands.*/
install_element (BGP_NODE, &neighbor_send_community_cmd);
{ PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out },
{ PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out },
{ PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out },
+ { PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out },
+ { PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE,1, peer_change_reset_out },
{ PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in },
{ PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset },
{ PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF_ALL) ?
" all" : "", VTY_NEWLINE);
- /* Remove private AS. */
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
- && ! peer->af_group[afi][safi])
- vty_out (vty, " neighbor %s remove-private-AS%s",
- addr, VTY_NEWLINE);
+ /* remove-private-AS */
+ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS) && !peer->af_group[afi][safi])
+ {
+ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL) &&
+ peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+ vty_out (vty, " neighbor %s remove-private-AS all replace-AS%s", addr, VTY_NEWLINE);
+
+ else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+ vty_out (vty, " neighbor %s remove-private-AS replace-AS%s", addr, VTY_NEWLINE);
+
+ else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
+ vty_out (vty, " neighbor %s remove-private-AS all%s", addr, VTY_NEWLINE);
+
+ else
+ vty_out (vty, " neighbor %s remove-private-AS%s", addr, VTY_NEWLINE);
+ }
/* send-community print. */
if (! peer->af_group[afi][safi])