summaryrefslogtreecommitdiffstats
path: root/bgpd/bgpd.c
diff options
context:
space:
mode:
authorDon Slice <dslice@cumulusnetworks.com>2018-12-27 17:03:38 +0100
committerDon Slice <dslice@cumulusnetworks.com>2019-01-23 13:23:47 +0100
commitfaa16034cba68ee902318dad8f6cc2abc1bb6407 (patch)
tree5154c17242b0275012efcbe242f6aee017d3f051 /bgpd/bgpd.c
parentMerge pull request #3630 from opensourcerouting/fix-show-import-check (diff)
downloadfrr-faa16034cba68ee902318dad8f6cc2abc1bb6407.tar.xz
frr-faa16034cba68ee902318dad8f6cc2abc1bb6407.zip
bgpd: improve peer-group remote-as definitions
Problem reported that with certain sequences of defining the remote-as on the peer-group and the members, the configuration would become wrong, with configured remote-as settings not reflected in the config but peers unable to come up. This fix resolves these inconsistencies. Ticket: CM-19560 Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Diffstat (limited to 'bgpd/bgpd.c')
-rw-r--r--bgpd/bgpd.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 5b8ceb054..6411865d4 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) {