summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2019-01-29 15:58:02 +0100
committerGitHub <noreply@github.com>2019-01-29 15:58:02 +0100
commitfc6da5170512b7c54243ed6210f2ef0ded12e701 (patch)
tree75a522b60220828fd9507845016e90c4609c4976 /bgpd
parentMerge pull request #3616 from donaldsharp/route_notification (diff)
parentbgpd: improve peer-group remote-as definitions (diff)
downloadfrr-fc6da5170512b7c54243ed6210f2ef0ded12e701.tar.xz
frr-fc6da5170512b7c54243ed6210f2ef0ded12e701.zip
Merge pull request #3653 from dslicenc/bgpd-remote-as
bgpd: improve peer-group remote-as definitions
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_vty.c19
-rw-r--r--bgpd/bgpd.c46
-rw-r--r--bgpd/bgpd.h3
3 files changed, 53 insertions, 15 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index f887ef766..43adf3424 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2847,13 +2847,11 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
switch (ret) {
case BGP_ERR_PEER_GROUP_MEMBER:
vty_out(vty,
- "%% Peer-group AS %u. Cannot configure remote-as for member\n",
- as);
+ "%% Peer-group member cannot override remote-as of peer-group\n");
return CMD_WARNING_CONFIG_FAILED;
case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
vty_out(vty,
- "%% The AS# can not be changed from %u to %s, peer-group members must be all internal or all external\n",
- as, as_str);
+ "%% Peer-group members must be all internal or all external\n");
return CMD_WARNING_CONFIG_FAILED;
}
return bgp_vty_return(vty, ret);
@@ -9213,8 +9211,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
? " replace-as"
: "");
}
- /* peer type internal, external, confed-internal or confed-external */
- if (p->as == p->local_as) {
+ /* peer type internal or confed-internal */
+ if ((p->as == p->local_as) || (p->as_type == AS_INTERNAL)) {
if (use_json) {
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
json_object_boolean_true_add(
@@ -9228,7 +9226,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
else
vty_out(vty, "internal link\n");
}
- } else {
+ /* peer type external or confed-external */
+ } else if (p->as || (p->as_type == AS_EXTERNAL)) {
if (use_json) {
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
json_object_boolean_true_add(
@@ -9242,6 +9241,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
else
vty_out(vty, "external link\n");
}
+ } else {
+ if (use_json)
+ json_object_boolean_true_add(json_neigh,
+ "nbrUnspecifiedLink");
+ else
+ vty_out(vty, "unspecified link\n");
}
/* Description. */
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 0fe1f8ed5..28f6239b8 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1001,7 +1001,26 @@ static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
return BGP_PEER_EBGP;
} else {
- if (peer->as_type != AS_SPECIFIED)
+ if (peer->as_type == AS_UNSPECIFIED) {
+ /* check if in peer-group with AS information */
+ if (peer->group
+ && (peer->group->conf->as_type != AS_UNSPECIFIED)) {
+ if (peer->group->conf->as_type
+ == AS_SPECIFIED) {
+ if (peer->local_as
+ == peer->group->conf->as)
+ return BGP_PEER_IBGP;
+ else
+ return BGP_PEER_EBGP;
+ } else if (peer->group->conf->as_type
+ == AS_INTERNAL)
+ return BGP_PEER_IBGP;
+ else
+ return BGP_PEER_EBGP;
+ }
+ /* no AS information anywhere, let caller know */
+ return BGP_PEER_UNSPECIFIED;
+ } else if (peer->as_type != AS_SPECIFIED)
return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP
: BGP_PEER_EBGP);
@@ -1711,20 +1730,32 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
/* When this peer is a member of peer-group. */
if (peer->group) {
- if (peer->group->conf->as) {
+ /* peer-group already has AS number/internal/external */
+ if (peer->group->conf->as
+ || peer->group->conf->as_type) {
/* Return peer group's AS number. */
*as = peer->group->conf->as;
return BGP_ERR_PEER_GROUP_MEMBER;
}
- if (peer_sort(peer->group->conf) == BGP_PEER_IBGP) {
- if ((as_type != AS_INTERNAL)
- && (bgp->as != *as)) {
+
+ bgp_peer_sort_t peer_sort_type =
+ peer_sort(peer->group->conf);
+
+ /* Explicit AS numbers used, compare AS numbers */
+ if (as_type == AS_SPECIFIED) {
+ if (((peer_sort_type == BGP_PEER_IBGP)
+ && (bgp->as != *as))
+ || ((peer_sort_type == BGP_PEER_EBGP)
+ && (bgp->as == *as))) {
*as = peer->as;
return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
}
} else {
- if ((as_type != AS_EXTERNAL)
- && (bgp->as == *as)) {
+ /* internal/external used, compare as-types */
+ if (((peer_sort_type == BGP_PEER_IBGP)
+ && (as_type != AS_INTERNAL))
+ || ((peer_sort_type == BGP_PEER_EBGP)
+ && (as_type != AS_EXTERNAL))) {
*as = peer->as;
return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
}
@@ -2688,6 +2719,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
if (peer->as_type == AS_UNSPECIFIED) {
peer->as_type = group->conf->as_type;
peer->as = group->conf->as;
+ peer->sort = group->conf->sort;
}
if (!group->conf->as) {
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 484fc105e..58ae119af 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -646,7 +646,8 @@ struct bgp_filter {
/* IBGP/EBGP identifier. We also have a CONFED peer, which is to say,
a peer who's AS is part of our Confederation. */
typedef enum {
- BGP_PEER_IBGP = 1,
+ BGP_PEER_UNSPECIFIED,
+ BGP_PEER_IBGP,
BGP_PEER_EBGP,
BGP_PEER_INTERNAL,
BGP_PEER_CONFED,