bgpd: store the neighbor as identifier as a string

This identifier is used to display the peer configuration in
the running-config, like it has been configured.
The following commands are using a specific string attribute:
- neighbor .. remote-as ASN
- neighbor .. local-as ASN

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2022-11-18 16:02:55 +01:00
parent e84c7c12f2
commit de76ed8a0e
4 changed files with 67 additions and 35 deletions

View File

@ -553,7 +553,7 @@ static void bgp_accept(struct thread *thread)
peer1->host);
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
peer1->as, peer1->as_type, NULL, false);
peer1->as, peer1->as_type, NULL, false, NULL);
peer_xfer_config(peer, peer1);
bgp_peer_gr_flags_update(peer);

View File

@ -4586,11 +4586,12 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
/* Check if existing interface peer */
peer = peer_lookup_by_conf_if(bgp, peer_str);
ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type);
ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, as_str);
/* if not interface peer, check peer-group settings */
if (ret < 0 && !peer) {
ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
ret = peer_group_remote_as(bgp, peer_str, &as, as_type,
as_str);
if (ret < 0) {
vty_out(vty,
"%% Create the peer-group or interface first\n");
@ -4604,7 +4605,7 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
"%% Can not configure the local system as neighbor\n");
return CMD_WARNING_CONFIG_FAILED;
}
ret = peer_remote_as(bgp, &su, NULL, &as, as_type);
ret = peer_remote_as(bgp, &su, NULL, &as, as_type, as_str);
}
return bgp_vty_return(vty, ret);
@ -4763,10 +4764,11 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
peer = peer_lookup_by_conf_if(bgp, conf_if);
if (peer) {
if (as_str)
ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type);
ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
as_str);
} else {
peer = peer_create(NULL, conf_if, bgp, bgp->as, as, as_type,
NULL, true);
NULL, true, as_str);
if (!peer) {
vty_out(vty, "%% BGP failed to create peer\n");
@ -5071,7 +5073,7 @@ DEFUN (no_neighbor_interface_peer_group_remote_as,
/* look up for neighbor by interface name config. */
peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
if (peer) {
peer_as_change(peer, 0, AS_UNSPECIFIED);
peer_as_change(peer, 0, AS_UNSPECIFIED, NULL);
return CMD_SUCCESS;
}
@ -5109,7 +5111,7 @@ DEFUN (neighbor_local_as,
return CMD_WARNING_CONFIG_FAILED;
}
ret = peer_local_as_set(peer, as, 0, 0);
ret = peer_local_as_set(peer, as, 0, 0, argv[idx_number]->arg);
return bgp_vty_return(vty, ret);
}
@ -5138,7 +5140,7 @@ DEFUN (neighbor_local_as_no_prepend,
return CMD_WARNING_CONFIG_FAILED;
}
ret = peer_local_as_set(peer, as, 1, 0);
ret = peer_local_as_set(peer, as, 1, 0, argv[idx_number]->arg);
return bgp_vty_return(vty, ret);
}
@ -5168,7 +5170,7 @@ DEFUN (neighbor_local_as_no_prepend_replace_as,
return CMD_WARNING_CONFIG_FAILED;
}
ret = peer_local_as_set(peer, as, 1, 1);
ret = peer_local_as_set(peer, as, 1, 1, argv[idx_number]->arg);
return bgp_vty_return(vty, ret);
}
@ -17302,7 +17304,7 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
vty_out(vty, " peer-group %s", peer->group->name);
if_pg_printed = true;
} else if (peer->as_type == AS_SPECIFIED) {
vty_out(vty, " remote-as %u", peer->as);
vty_out(vty, " remote-as %s", peer->as_pretty);
if_ras_printed = true;
} else if (peer->as_type == AS_INTERNAL) {
vty_out(vty, " remote-as internal");
@ -17322,8 +17324,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) {
if (peer->as_type == AS_SPECIFIED) {
vty_out(vty, " neighbor %s remote-as %u\n",
addr, peer->as);
vty_out(vty, " neighbor %s remote-as %s\n",
addr, peer->as_pretty);
} else if (peer->as_type == AS_INTERNAL) {
vty_out(vty,
" neighbor %s remote-as internal\n",
@ -17351,8 +17353,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
if (!if_ras_printed) {
if (peer->as_type == AS_SPECIFIED) {
vty_out(vty, " neighbor %s remote-as %u\n",
addr, peer->as);
vty_out(vty, " neighbor %s remote-as %s\n",
addr, peer->as_pretty);
} else if (peer->as_type == AS_INTERNAL) {
vty_out(vty,
" neighbor %s remote-as internal\n",
@ -17367,8 +17369,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
/* local-as */
if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS)) {
vty_out(vty, " neighbor %s local-as %u", addr,
peer->change_local_as);
vty_out(vty, " neighbor %s local-as %s", addr,
peer->change_local_as_pretty);
if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND))
vty_out(vty, " no-prepend");
if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS))

View File

@ -1185,6 +1185,11 @@ static void peer_free(struct peer *peer)
FOREACH_AFI_SAFI (afi, safi)
bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE);
if (peer->change_local_as_pretty)
XFREE(MTYPE_BGP, peer->change_local_as_pretty);
if (peer->as_pretty)
XFREE(MTYPE_BGP, peer->as_pretty);
bgp_unlock(peer->bgp);
memset(peer, 0, sizeof(struct peer));
@ -1766,7 +1771,7 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
struct peer *peer_create(union sockunion *su, const char *conf_if,
struct bgp *bgp, as_t local_as, as_t remote_as,
int as_type, struct peer_group *group,
bool config_node)
bool config_node, const char *as_str)
{
int active;
struct peer *peer;
@ -1791,6 +1796,9 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
}
peer->local_as = local_as;
peer->as = remote_as;
/* internal and external values do not use as_pretty */
if (as_str && asn_str2asn(as_str, NULL))
peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
peer->as_type = as_type;
peer->local_id = bgp->router_id;
peer->v_holdtime = bgp->default_holdtime;
@ -1894,7 +1902,8 @@ bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi)
}
/* Change peer's AS number. */
void peer_as_change(struct peer *peer, as_t as, int as_specified)
void peer_as_change(struct peer *peer, as_t as, int as_specified,
const char *as_str)
{
enum bgp_peer_sort origtype, newtype;
@ -1909,6 +1918,12 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
}
origtype = peer_sort_lookup(peer);
peer->as = as;
if (as_specified == AS_SPECIFIED && as_str) {
if (peer->as_pretty)
XFREE(MTYPE_BGP, peer->as_pretty);
peer->as_pretty = XSTRDUP(MTYPE_BGP, as_str);
} else if (peer->as_type == AS_UNSPECIFIED && peer->as_pretty)
XFREE(MTYPE_BGP, peer->as_pretty);
peer->as_type = as_specified;
if (bgp_config_check(peer->bgp, BGP_CONFIG_CONFEDERATION)
@ -1966,7 +1981,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
/* If peer does not exist, create new one. If peer already exists,
set AS number to the peer. */
int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
as_t *as, int as_type)
as_t *as, int as_type, const char *as_str)
{
struct peer *peer;
as_t local_as;
@ -2020,7 +2035,7 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
/* Existing peer's AS number change. */
if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
|| (peer->as_type != as_type))
peer_as_change(peer, *as, as_type);
peer_as_change(peer, *as, as_type, as_str);
} else {
if (conf_if)
return BGP_ERR_NO_INTERFACE_CONFIG;
@ -2035,7 +2050,7 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
local_as = bgp->as;
peer_create(su, conf_if, bgp, local_as, *as, as_type, NULL,
true);
true, as_str);
}
return 0;
@ -2816,7 +2831,7 @@ static void peer_group2peer_config_copy(struct peer_group *group,
/* Peer group's remote AS configuration. */
int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
int as_type)
int as_type, const char *as_str)
{
struct peer_group *group;
struct peer *peer;
@ -2832,12 +2847,12 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
/* When we setup peer-group AS number all peer group member's AS
number must be updated to same number. */
peer_as_change(group->conf, *as, as_type);
peer_as_change(group->conf, *as, as_type, as_str);
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
if (((peer->as_type == AS_SPECIFIED) && peer->as != *as)
|| (peer->as_type != as_type))
peer_as_change(peer, *as, as_type);
peer_as_change(peer, *as, as_type, as_str);
}
return 0;
@ -3144,7 +3159,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
}
peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
group->conf->as_type, group, true);
group->conf->as_type, group, true, NULL);
peer = peer_lock(peer); /* group->peer list reference */
listnode_add(group->peer, peer);
@ -4051,7 +4066,7 @@ struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
/* Create peer first; we've already checked group config is valid. */
peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
group->conf->as_type, group, true);
group->conf->as_type, group, true, NULL);
if (!peer)
return NULL;
@ -6234,7 +6249,7 @@ int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi)
}
int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
bool replace_as)
bool replace_as, const char *as_str)
{
bool old_no_prepend, old_replace_as;
struct bgp *bgp = peer->bgp;
@ -6259,6 +6274,9 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
&& old_replace_as == replace_as)
return 0;
peer->change_local_as = as;
if (as_str)
peer->change_local_as_pretty = XSTRDUP(MTYPE_BGP, as_str);
(void)peer_sort(peer);
/* Check if handling a regular peer. */
@ -6292,6 +6310,9 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS,
replace_as);
member->change_local_as = as;
if (as_str)
member->change_local_as_pretty =
XSTRDUP(MTYPE_BGP, as_str);
}
return 0;
@ -6317,6 +6338,7 @@ int peer_local_as_unset(struct peer *peer)
peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND);
peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS);
peer->change_local_as = 0;
XFREE(MTYPE_BGP, peer->change_local_as_pretty);
}
/* Check if handling a regular peer. */
@ -6347,6 +6369,7 @@ int peer_local_as_unset(struct peer *peer)
UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
member->change_local_as = 0;
XFREE(MTYPE_BGP, member->change_local_as_pretty);
/* Send notification or stop peer depending on state. */
if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) {

View File

@ -1124,6 +1124,8 @@ struct peer {
/* Peer's remote AS number. */
int as_type;
as_t as;
/* for vty as format */
char *as_pretty;
/* Peer's local AS number. */
as_t local_as;
@ -1132,6 +1134,8 @@ struct peer {
/* Peer's Change local AS number. */
as_t change_local_as;
/* for vty as format */
char *change_local_as_pretty;
/* Remote router ID. */
struct in_addr remote_id;
@ -2138,7 +2142,7 @@ extern void bgp_recalculate_all_bestpaths(struct bgp *bgp);
extern struct peer *peer_create(union sockunion *su, const char *conf_if,
struct bgp *bgp, as_t local_as, as_t remote_as,
int as_type, struct peer_group *group,
bool config_node);
bool config_node, const char *as_str);
extern struct peer *peer_create_accept(struct bgp *);
extern void peer_xfer_config(struct peer *dst, struct peer *src);
extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
@ -2208,10 +2212,13 @@ extern void bgp_listen_limit_unset(struct bgp *bgp);
extern bool bgp_update_delay_active(struct bgp *);
extern bool bgp_update_delay_configured(struct bgp *);
extern bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi);
extern void peer_as_change(struct peer *, as_t, int);
extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
int);
extern int peer_group_remote_as(struct bgp *, const char *, as_t *, int);
extern void peer_as_change(struct peer *peer, as_t as, int as_type,
const char *as_str);
extern int peer_remote_as(struct bgp *bgp, union sockunion *su,
const char *conf_if, as_t *as, int as_type,
const char *as_str);
extern int peer_group_remote_as(struct bgp *bgp, const char *peer_str, as_t *as,
int as_type, const char *as_str);
extern int peer_delete(struct peer *peer);
extern void peer_notify_unconfig(struct peer *peer);
extern int peer_group_delete(struct peer_group *);
@ -2290,8 +2297,8 @@ extern int peer_distribute_unset(struct peer *, afi_t, safi_t, int);
extern int peer_allowas_in_set(struct peer *, afi_t, safi_t, int, int);
extern int peer_allowas_in_unset(struct peer *, afi_t, safi_t);
extern int peer_local_as_set(struct peer *, as_t, bool no_prepend,
bool replace_as);
extern int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend,
bool replace_as, const char *as_str);
extern int peer_local_as_unset(struct peer *);
extern int peer_prefix_list_set(struct peer *, afi_t, safi_t, int,