Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Implement neighbor X remote-as auto #16345

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4468,6 +4468,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
bgp_packet_mpattr_end(s, mpattrlen_pos);
}

(void)peer_sort(peer);

/* Origin attribute. */
stream_putc(s, BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_ORIGIN);
Expand Down
2 changes: 1 addition & 1 deletion bgpd/bgp_evpn_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -4840,7 +4840,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary, show_bgp_l2vpn_evpn_summary_cmd,
char *vrf = NULL;
char *neighbor = NULL;
as_t as = 0; /* 0 means AS filter not set */
int as_type = AS_UNSPECIFIED;
enum peer_asn_type as_type = AS_UNSPECIFIED;
uint16_t show_flags = 0;

if (argv_find(argv, argc, "vrf", &idx_vrf))
Expand Down
8 changes: 8 additions & 0 deletions bgpd/bgp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1977,6 +1977,14 @@ static int bgp_open_receive(struct peer_connection *connection,
BGP_NOTIFY_OPEN_BAD_PEER_AS,
notify_data_remote_as, 2);
return BGP_Stop;
} else if (peer->as_type == AS_AUTO) {
if (remote_as == peer->bgp->as) {
peer->as = peer->local_as;
SET_FLAG(peer->as_type, AS_INTERNAL);
} else {
peer->as = remote_as;
SET_FLAG(peer->as_type, AS_EXTERNAL);
}
} else if (peer->as_type == AS_INTERNAL) {
if (remote_as != peer->bgp->as) {
if (bgp_debug_neighbor_events(peer))
Expand Down
7 changes: 6 additions & 1 deletion bgpd/bgp_updgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,12 @@ static unsigned int updgrp_hash_key_make(const void *p)

key = 0;

key = jhash_1word(peer->sort, key); /* EBGP or IBGP */
/* `remote-as auto` technically uses identical peer->sort.
* After OPEN message is parsed, this is updated accordingly, but
* we need to call the peer_sort() here also to properly create
* separate subgroups.
*/
key = jhash_1word(peer_sort((struct peer *)peer), key);
key = jhash_1word(peer->sub_sort, key); /* OAD */
key = jhash_1word((peer->flags & PEER_UPDGRP_FLAGS), key);
key = jhash_1word((flags & PEER_UPDGRP_AF_FLAGS), key);
Expand Down
85 changes: 55 additions & 30 deletions bgpd/bgp_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -4862,7 +4862,7 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
as_t as;
int as_type = AS_SPECIFIED;
enum peer_asn_type as_type = AS_SPECIFIED;
union sockunion su;

if (as_str[0] == 'i') {
Expand All @@ -4871,6 +4871,9 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
} else if (as_str[0] == 'e') {
as = 0;
as_type = AS_EXTERNAL;
} else if (as_str[0] == 'a') {
as = 0;
as_type = AS_AUTO;
} else if (!asn_str2asn(as_str, &as))
as_type = AS_UNSPECIFIED;

Expand Down Expand Up @@ -4976,13 +4979,14 @@ ALIAS(no_bgp_shutdown, no_bgp_shutdown_msg_cmd,

DEFUN (neighbor_remote_as,
neighbor_remote_as_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <ASNUM|internal|external>",
"neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <ASNUM|internal|external|auto>",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
"External BGP peer\n"
"Automatically detect remote ASN\n")
{
int idx_peer = 1;
int idx_remote_as = 3;
Expand Down Expand Up @@ -5037,7 +5041,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
as_t as = 0;
int as_type = AS_UNSPECIFIED;
enum peer_asn_type as_type = AS_UNSPECIFIED;
struct peer *peer;
struct peer_group *group;
int ret = 0;
Expand All @@ -5054,6 +5058,8 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
as_type = AS_INTERNAL;
} else if (as_str[0] == 'e') {
as_type = AS_EXTERNAL;
} else if (as_str[0] == 'a') {
as_type = AS_AUTO;
} else {
/* Get AS number. */
if (asn_str2asn(as_str, &as))
Expand Down Expand Up @@ -5170,14 +5176,15 @@ DEFUN (neighbor_interface_config_v6only,

DEFUN (neighbor_interface_config_remote_as,
neighbor_interface_config_remote_as_cmd,
"neighbor WORD interface remote-as <ASNUM|internal|external>",
"neighbor WORD interface remote-as <ASNUM|internal|external|auto>",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP on interface\n"
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
"External BGP peer\n"
"Automatically detect remote ASN\n")
{
int idx_word = 1;
int idx_remote_as = 4;
Expand All @@ -5187,15 +5194,16 @@ DEFUN (neighbor_interface_config_remote_as,

DEFUN (neighbor_interface_v6only_config_remote_as,
neighbor_interface_v6only_config_remote_as_cmd,
"neighbor WORD interface v6only remote-as <ASNUM|internal|external>",
"neighbor WORD interface v6only remote-as <ASNUM|internal|external|auto>",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP with v6 link-local only\n"
"Enable BGP on interface\n"
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
"External BGP peer\n"
"Automatically detect remote ASN\n")
{
int idx_word = 1;
int idx_remote_as = 5;
Expand Down Expand Up @@ -5232,14 +5240,15 @@ DEFUN (neighbor_peer_group,

DEFUN (no_neighbor,
no_neighbor_cmd,
"no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
"no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external|auto>]>",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
"External BGP peer\n"
"Automatically detect remote ASN\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_peer = 2;
Expand Down Expand Up @@ -5310,7 +5319,7 @@ DEFUN (no_neighbor,

DEFUN (no_neighbor_interface_config,
no_neighbor_interface_config_cmd,
"no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]",
"no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external|auto>]",
NO_STR
NEIGHBOR_STR
"Interface name\n"
Expand All @@ -5321,7 +5330,8 @@ DEFUN (no_neighbor_interface_config,
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
"External BGP peer\n"
"Automatically detect remote ASN\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_word = 2;
Expand Down Expand Up @@ -5378,14 +5388,15 @@ DEFUN (no_neighbor_peer_group,

DEFUN (no_neighbor_interface_peer_group_remote_as,
no_neighbor_interface_peer_group_remote_as_cmd,
"no neighbor WORD remote-as <ASNUM|internal|external>",
"no neighbor WORD remote-as <ASNUM|internal|external|auto>",
NO_STR
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
"External BGP peer\n"
"Automatically detect remote ASN\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_word = 2;
Expand Down Expand Up @@ -11876,7 +11887,8 @@ static char *bgp_peer_description_stripped(char *desc, uint32_t size)

/* Determine whether var peer should be filtered out of the summary. */
static bool bgp_show_summary_is_peer_filtered(struct peer *peer,
struct peer *fpeer, int as_type,
struct peer *fpeer,
enum peer_asn_type as_type,
as_t as)
{

Expand All @@ -11887,7 +11899,7 @@ static bool bgp_show_summary_is_peer_filtered(struct peer *peer,
/* filter remote-as (internal|external) */
if (as_type != AS_UNSPECIFIED) {
if (peer->as_type == AS_SPECIFIED) {
if (as_type == AS_INTERNAL) {
if (CHECK_FLAG(as_type, AS_INTERNAL)) {
if (peer->as != peer->local_as)
return true;
} else if (peer->as == peer->local_as)
Expand All @@ -11910,8 +11922,8 @@ static bool bgp_show_summary_is_peer_filtered(struct peer *peer,
* whitespaces and the whole output will be tricky.
*/
static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
struct peer *fpeer, int as_type, as_t as,
uint16_t show_flags)
struct peer *fpeer, enum peer_asn_type as_type,
as_t as, uint16_t show_flags)
{
struct peer *peer;
struct listnode *node, *nnode;
Expand Down Expand Up @@ -12718,10 +12730,9 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
}

static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
safi_t safi,
const char *neighbor,
int as_type, as_t as,
uint16_t show_flags)
safi_t safi, const char *neighbor,
enum peer_asn_type as_type,
as_t as, uint16_t show_flags)
{
struct listnode *node, *nnode;
struct bgp *bgp;
Expand Down Expand Up @@ -12763,8 +12774,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
}

int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
safi_t safi, const char *neighbor, int as_type,
as_t as, uint16_t show_flags)
safi_t safi, const char *neighbor,
enum peer_asn_type as_type, as_t as,
uint16_t show_flags)
{
struct bgp *bgp;
bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
Expand Down Expand Up @@ -12879,6 +12891,8 @@ DEFPY(show_ip_bgp_summary, show_ip_bgp_summary_cmd,
as_type = AS_INTERNAL;
else if (argv[idx + 1]->arg[0] == 'e')
as_type = AS_EXTERNAL;
else if (argv[idx + 1]->arg[0] == 'a')
as_type = AS_AUTO;
else if (!asn_str2asn(argv[idx + 1]->arg, &as)) {
vty_out(vty,
"%% Invalid neighbor remote-as value: %s\n",
Expand Down Expand Up @@ -14002,9 +14016,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
json_object_boolean_true_add(json_neigh,
"localAsReplaceAs");
} else {
if ((p->as_type == AS_SPECIFIED) ||
(p->as_type == AS_EXTERNAL) ||
(p->as_type == AS_INTERNAL)) {
if (p->as_type == AS_SPECIFIED ||
CHECK_FLAG(p->as_type, AS_AUTO) ||
CHECK_FLAG(p->as_type, AS_EXTERNAL) ||
CHECK_FLAG(p->as_type, AS_INTERNAL)) {
vty_out(vty, "remote AS ");
vty_out(vty, ASN_FORMAT(bgp->asnotation), &p->as);
vty_out(vty, ", ");
Expand All @@ -14023,7 +14038,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
: "");
}
/* peer type internal or confed-internal */
if ((p->as == p->local_as) || (p->as_type == AS_INTERNAL)) {
if ((p->as == p->local_as) || (CHECK_FLAG(p->as_type, AS_INTERNAL))) {
if (use_json) {
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
json_object_boolean_true_add(
Expand Down Expand Up @@ -17011,7 +17026,7 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group,
&conf->as);
vty_out(vty, "\n");
}
} else if (conf->as_type == AS_INTERNAL) {
} else if (CHECK_FLAG(conf->as_type, AS_INTERNAL)) {
if (json)
asn_asn2json(json, "remoteAs", group->bgp->as,
group->bgp->asnotation);
Expand All @@ -17023,7 +17038,8 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group,
vty_out(vty, "\nBGP peer-group %s\n", group->name);
}

if ((group->bgp->as == conf->as) || (conf->as_type == AS_INTERNAL)) {
if ((group->bgp->as == conf->as) ||
CHECK_FLAG(conf->as_type, AS_INTERNAL)) {
if (json)
json_object_string_add(json_peer_group, "type",
"internal");
Expand Down Expand Up @@ -18525,6 +18541,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
} else if (peer->as_type == AS_EXTERNAL) {
vty_out(vty, " remote-as external");
if_ras_printed = true;
} else if (CHECK_FLAG(peer->as_type, AS_AUTO)) {
vty_out(vty, " remote-as auto");
if_ras_printed = true;
}

vty_out(vty, "\n");
Expand All @@ -18547,6 +18566,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
vty_out(vty,
" neighbor %s remote-as external\n",
addr);
} else if (CHECK_FLAG(peer->as_type, AS_AUTO)) {
vty_out(vty, " neighbor %s remote-as auto\n",
addr);
}
}

Expand Down Expand Up @@ -18576,6 +18598,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
vty_out(vty,
" neighbor %s remote-as external\n",
addr);
} else if (CHECK_FLAG(peer->as_type, AS_AUTO)) {
vty_out(vty, " neighbor %s remote-as auto\n",
addr);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions bgpd/bgp_vty.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,9 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv,
int argc, struct bgp **bgp, bool use_json);
extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
safi_t safi, const char *neighbor, int as_type,
as_t as, uint16_t show_flags);
safi_t safi, const char *neighbor,
enum peer_asn_type as_type, as_t as,
uint16_t show_flags);
extern bool peergroup_flag_check(struct peer *peer, uint64_t flag);
extern bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi,
uint64_t flag);
Expand Down
Loading
Loading