return 1;
}
+/* Return True if the entire ASPATH consist of the specified ASN */
+int
+aspath_single_asn_check (struct aspath *aspath, as_t asn)
+{
+ 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] != asn)
+ return 0;
+ }
+ seg = seg->next;
+ }
+ return 1;
+}
+
+/* Replace all instances of the target ASN with our own ASN */
+struct aspath *
+aspath_replace_specific_asn (struct aspath *aspath, as_t target_asn,
+ as_t our_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 (seg->as[i] == target_asn)
+ seg->as[i] = our_asn;
+ }
+ seg = seg->next;
+ }
+
+ aspath_str_update(new);
+ return new;
+}
+
/* Replace all private ASNs with our own ASN */
struct aspath *
aspath_replace_private_asns (struct aspath *aspath, as_t asn)
extern unsigned int aspath_key_make (void *);
extern int aspath_loop_check (struct aspath *, as_t);
extern int aspath_private_as_check (struct aspath *);
+extern int aspath_single_asn_check (struct aspath *, as_t asn);
+extern struct aspath *aspath_replace_specific_asn (struct aspath *aspath, 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);
extern int aspath_firstas_check (struct aspath *, as_t);
}
}
+/* If this is an EBGP peer with as-override */
+static void
+bgp_peer_as_override(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_AS_OVERRIDE))
+ {
+ if (aspath_single_asn_check (attr->aspath, peer->as))
+ attr->aspath = aspath_replace_specific_asn (attr->aspath, peer->as, bgp->as);
+ }
+}
+
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 */
bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
+ bgp_peer_as_override(bgp, afi, safi, peer, attr);
/* Route map & unsuppress-map apply. */
if (ROUTE_MAP_OUT_NAME (filter)
#endif /* HAVE_IPV6 */
bgp_peer_remove_private_as(bgp, afi, safi, rsclient, attr);
+ bgp_peer_as_override(bgp, afi, safi, rsclient, attr);
/* Route map & unsuppress-map apply. */
if (ROUTE_MAP_OUT_NAME (filter) || (ri->extra && ri->extra->suppress) )
case BGP_ERR_NO_IBGP_WITH_TTLHACK:
str = "ttl-security only allowed for EBGP peers";
break;
+ case BGP_ERR_AS_OVERRIDE:
+ str = "as-override cannot be configured for IBGP peers";
+ break;
}
if (str)
{
PEER_FLAG_NEXTHOP_SELF|PEER_FLAG_NEXTHOP_SELF_ALL);
}
+/* neighbor as-override */
+DEFUN (neighbor_as_override,
+ neighbor_as_override_cmd,
+ NEIGHBOR_CMD2 "as-override",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Override ASNs in outbound updates if aspath equals remote-as\n")
+{
+ return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_AS_OVERRIDE);
+}
+
+DEFUN (no_neighbor_as_override,
+ no_neighbor_as_override_cmd,
+ NO_NEIGHBOR_CMD2 "as-override",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Override ASNs in outbound updates if aspath equals remote-as\n")
+{
+ return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty),
+ PEER_FLAG_AS_OVERRIDE);
+}
+
/* neighbor remove-private-AS. */
DEFUN (neighbor_remove_private_as,
neighbor_remove_private_as_cmd,
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_AS_OVERRIDE))
+ vty_out (vty, " Override ASNs in outbound updates if aspath equals remote-as%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);
install_element (BGP_VPNV4_NODE, &neighbor_nexthop_self_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_nexthop_self_cmd);
+ /* "neighbor as-override" commands. */
+ install_element (BGP_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV4_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV4M_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_IPV6M_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_IPV6M_NODE, &no_neighbor_as_override_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_as_override_cmd);
+ install_element (BGP_VPNV4_NODE, &no_neighbor_as_override_cmd);
+
/* "neighbor remove-private-AS" commands. */
install_element (BGP_NODE, &neighbor_remove_private_as_cmd);
install_element (BGP_NODE, &no_neighbor_remove_private_as_cmd);
{ PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
{ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
{ PEER_FLAG_NEXTHOP_SELF_ALL, 1, peer_change_reset_out },
+ { PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out },
{ 0, 0, 0 }
};
&& peer_sort (peer) == BGP_PEER_IBGP)
return BGP_ERR_REMOVE_PRIVATE_AS;
+ /* as-override is not allowed for IBGP peers */
+ if (flag & PEER_FLAG_AS_OVERRIDE
+ && peer_sort (peer) == BGP_PEER_IBGP)
+ return BGP_ERR_AS_OVERRIDE;
+
/* When unset the peer-group member's flag we have to check
peer-group configuration. */
if (! set && peer->af_group[afi][safi])
vty_out (vty, " neighbor %s remove-private-AS%s", addr, VTY_NEWLINE);
}
+ /* as-override */
+ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_AS_OVERRIDE) &&
+ !peer->af_group[afi][safi])
+ vty_out (vty, " neighbor %s as-override%s", addr, VTY_NEWLINE);
+
/* send-community print. */
if (! peer->af_group[afi][safi])
{
#define PEER_FLAG_NEXTHOP_SELF_ALL (1 << 17) /* next-hop-self all */
#define PEER_FLAG_REMOVE_PRIVATE_AS_ALL (1 << 18) /* remove-private-as all */
#define PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE (1 << 19) /* remove-private-as replace-as */
+#define PEER_FLAG_AS_OVERRIDE (1 << 20) /* as-override */
/* MD5 password */
char *password;
#define BGP_ERR_NO_IBGP_WITH_TTLHACK -31
#define BGP_ERR_NO_INTERFACE_CONFIG -32
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -33
-#define BGP_ERR_MAX -34
+#define BGP_ERR_AS_OVERRIDE -34
+#define BGP_ERR_MAX -35
extern struct bgp_master *bm;