}
else
{
- aspath = aspath_add_seq (aspath, peer->local_as);
- if (peer->change_local_as)
+ if (peer->change_local_as) {
+ /* If replace-as is specified, we only use the change_local_as when
+ advertising routes. */
+ if( ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ) {
+ aspath = aspath_add_seq (aspath, peer->local_as);
+ }
aspath = aspath_add_seq (aspath, peer->change_local_as);
+ } else {
+ aspath = aspath_add_seq (aspath, peer->local_as);
+ }
}
}
else if (peer->sort == BGP_PEER_CONFED)
if (! peer)
return CMD_WARNING;
- ret = peer_local_as_set (peer, atoi (argv[1]), 0);
+ ret = peer_local_as_set (peer, atoi (argv[1]), 0, 0);
return bgp_vty_return (vty, ret);
}
if (! peer)
return CMD_WARNING;
- ret = peer_local_as_set (peer, atoi (argv[1]), 1);
+ ret = peer_local_as_set (peer, atoi (argv[1]), 1, 0);
return bgp_vty_return (vty, ret);
}
+DEFUN (neighbor_local_as_no_prepend_replace_as,
+ neighbor_local_as_no_prepend_replace_as_cmd,
+ NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE " no-prepend replace-as",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify a local-as number\n"
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n"
+ "Do not prepend local-as to updates from ibgp peers\n")
+{
+ struct peer *peer;
+ int ret;
+
+ peer = peer_and_group_lookup_vty (vty, argv[0]);
+ if (! peer)
+ return CMD_WARNING;
+
+ ret = peer_local_as_set (peer, atoi (argv[1]), 1, 1);
+ return bgp_vty_return (vty, ret);
+}
+
+
DEFUN (no_neighbor_local_as,
no_neighbor_local_as_cmd,
NO_NEIGHBOR_CMD2 "local-as",
"Specify a local-as number\n"
"AS number used as local AS\n"
"Do not prepend local-as to updates from ebgp peers\n")
+
+ALIAS (no_neighbor_local_as,
+ no_neighbor_local_as_val3_cmd,
+ NO_NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE " no-prepend replace-as",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify a local-as number\n"
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n"
+ "Do not prepend local-as to updates from ibgp peers\n")
\f
DEFUN (neighbor_password,
neighbor_password_cmd,
/* Configured IP address. */
vty_out (vty, "BGP neighbor is %s, ", p->host);
vty_out (vty, "remote AS %u, ", p->as);
- vty_out (vty, "local AS %u%s, ",
+ vty_out (vty, "local AS %u%s%s, ",
p->change_local_as ? p->change_local_as : p->local_as,
CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
- " no-prepend" : "");
+ " no-prepend" : "",
+ CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ?
+ " replace-as" : "");
vty_out (vty, "%s link%s",
p->as == p->local_as ? "internal" : "external",
VTY_NEWLINE);
/* "neighbor local-as" commands. */
install_element (BGP_NODE, &neighbor_local_as_cmd);
install_element (BGP_NODE, &neighbor_local_as_no_prepend_cmd);
+ install_element (BGP_NODE, &neighbor_local_as_no_prepend_replace_as_cmd);
install_element (BGP_NODE, &no_neighbor_local_as_cmd);
install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
+ install_element (BGP_NODE, &no_neighbor_local_as_val3_cmd);
/* "neighbor password" commands. */
install_element (BGP_NODE, &neighbor_password_cmd);
{
peer->change_local_as = 0;
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
+ UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
}
}
{
group->conf->change_local_as = 0;
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
+ UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
}
}
}
\f
int
-peer_local_as_set (struct peer *peer, as_t as, int no_prepend)
+peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)
{
struct bgp *bgp = peer->bgp;
struct peer_group *group;
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
+ if (peer->as == as)
+ return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
+
if (peer->change_local_as == as &&
((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
- || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)))
+ || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)) &&
+ ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && replace_as)
+ || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && ! replace_as)))
return 0;
peer->change_local_as = as;
else
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
+ if (replace_as)
+ SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
+ else
+ UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
+
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
else
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
+ if (replace_as)
+ SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
+ else
+ UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
+
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
peer->change_local_as = 0;
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
+ UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
{
peer->change_local_as = 0;
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
+ UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
if (peer->status == Established)
{
/* local-as. */
if (peer->change_local_as)
if (! peer_group_active (peer))
- vty_out (vty, " neighbor %s local-as %u%s%s", addr,
+ vty_out (vty, " neighbor %s local-as %u%s%s%s", addr,
peer->change_local_as,
CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
- " no-prepend" : "", VTY_NEWLINE);
+ " no-prepend" : "",
+ CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ?
+ " replace-as" : "", VTY_NEWLINE);
/* Description. */
if (peer->desc)
#define PEER_FLAG_DYNAMIC_CAPABILITY (1 << 5) /* dynamic capability */
#define PEER_FLAG_DISABLE_CONNECTED_CHECK (1 << 6) /* disable-connected-check */
#define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 7) /* local-as no-prepend */
+#define PEER_FLAG_LOCAL_AS_REPLACE_AS (1 << 8) /* local-as no-prepend replace-as */
/* NSF mode (graceful restart) */
u_char nsf[AFI_MAX][SAFI_MAX];
#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -30
#define BGP_ERR_NO_IBGP_WITH_TTLHACK -31
#define BGP_ERR_MAX -32
+#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -33
extern struct bgp_master *bm;
extern int peer_allowas_in_set (struct peer *, afi_t, safi_t, int);
extern int peer_allowas_in_unset (struct peer *, afi_t, safi_t);
-extern int peer_local_as_set (struct peer *, as_t, int);
+extern int peer_local_as_set (struct peer *, as_t, int, int);
extern int peer_local_as_unset (struct peer *);
extern int peer_prefix_list_set (struct peer *, afi_t, safi_t, int, const char *);