diff options
author | David Schweizer <dschweizer@opensourcerouting.org> | 2020-10-20 16:49:58 +0200 |
---|---|---|
committer | David Schweizer <dschweizer@opensourcerouting.org> | 2020-10-20 16:49:58 +0200 |
commit | 6c537a18cffeee854a3f80cef1fb459d85f37a15 (patch) | |
tree | 414f15c8399655cd10bc113876c957e329831e30 /bgpd/bgpd.c | |
parent | Merge pull request #7645 from sworleys/NHG-IFP-Error2Log (diff) | |
download | frr-6c537a18cffeee854a3f80cef1fb459d85f37a15.tar.xz frr-6c537a18cffeee854a3f80cef1fb459d85f37a15.zip |
bgpd: RFC 4271 DelayOpenTimer
Changes implement the DelayOpenTimer functionality proposed in RFC 4271.
Signed-off-by: David Schweizer <dschweizer@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgpd.c')
-rw-r--r-- | bgpd/bgpd.c | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 82ce0c388..f1454aaee 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -491,12 +491,13 @@ time_t bgp_clock(void) /* BGP timer configuration. */ void bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime, - uint32_t connect_retry) + uint32_t connect_retry, uint32_t delayopen) { bgp->default_keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3); bgp->default_holdtime = holdtime; bgp->default_connect_retry = connect_retry; + bgp->default_delayopen = delayopen; } /* mostly for completeness - CLI uses its own defaults */ @@ -505,6 +506,7 @@ void bgp_timers_unset(struct bgp *bgp) bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; bgp->default_connect_retry = BGP_DEFAULT_CONNECT_RETRY; + bgp->default_delayopen = BGP_DEFAULT_DELAYOPEN; } /* BGP confederation configuration. */ @@ -1410,10 +1412,12 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src) peer_dst->holdtime = peer_src->holdtime; peer_dst->keepalive = peer_src->keepalive; peer_dst->connect = peer_src->connect; + peer_dst->delayopen = peer_src->delayopen; peer_dst->v_holdtime = peer_src->v_holdtime; peer_dst->v_keepalive = peer_src->v_keepalive; peer_dst->routeadv = peer_src->routeadv; peer_dst->v_routeadv = peer_src->v_routeadv; + peer_dst->v_delayopen = peer_src->v_delayopen; /* password apply */ if (peer_src->password && !peer_dst->password) @@ -2577,6 +2581,14 @@ static void peer_group2peer_config_copy(struct peer_group *group, peer->v_connect = peer->bgp->default_connect_retry; } + if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TIMER_DELAYOPEN)) { + PEER_ATTR_INHERIT(peer, group, delayopen); + if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_DELAYOPEN)) + peer->v_delayopen = conf->delayopen; + else + peer->v_delayopen = peer->bgp->default_delayopen; + } + /* advertisement-interval apply */ if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_ROUTEADV)) { PEER_ATTR_INHERIT(peer, group, routeadv); @@ -4018,6 +4030,7 @@ static const struct peer_flag_action peer_flag_action_list[] = { {PEER_FLAG_ROUTEADV, 0, peer_change_none}, {PEER_FLAG_TIMER, 0, peer_change_none}, {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none}, + {PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none}, {PEER_FLAG_PASSWORD, 0, peer_change_none}, {PEER_FLAG_LOCAL_AS, 0, peer_change_none}, {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none}, @@ -5403,6 +5416,90 @@ int peer_advertise_interval_unset(struct peer *peer) return 0; } +/* set the peers RFC 4271 DelayOpen session attribute flag and DelayOpenTimer + * interval + */ +int peer_timers_delayopen_set(struct peer *peer, uint32_t delayopen) +{ + struct peer *member; + struct listnode *node; + + /* Set peers session attribute flag and timer interval. */ + peer_flag_set(peer, PEER_FLAG_TIMER_DELAYOPEN); + peer->delayopen = delayopen; + peer->v_delayopen = delayopen; + + /* Skip group mechanics for regular peers. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + return 0; + + /* Set flag and configuration on all peer-group members, unless they are + * explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->flags_override, + PEER_FLAG_TIMER_DELAYOPEN)) + continue; + + /* Set session attribute flag and timer intervals on peer-group + * member. + */ + SET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN); + member->delayopen = delayopen; + member->v_delayopen = delayopen; + } + + return 0; +} + +/* unset the peers RFC 4271 DelayOpen session attribute flag and reset the + * DelayOpenTimer interval to the default value. + */ +int peer_timers_delayopen_unset(struct peer *peer) +{ + struct peer *member; + struct listnode *node; + + /* Inherit configuration from peer-group if peer is member. */ + if (peer_group_active(peer)) { + peer_flag_inherit(peer, PEER_FLAG_TIMER_DELAYOPEN); + PEER_ATTR_INHERIT(peer, peer->group, delayopen); + } else { + /* Otherwise remove session attribute flag and set timer + * interval to default value. + */ + peer_flag_unset(peer, PEER_FLAG_TIMER_DELAYOPEN); + peer->delayopen = peer->bgp->default_delayopen; + } + + /* Set timer value to zero */ + peer->v_delayopen = 0; + + /* Skip peer-group mechanics for regular peers. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + return 0; + + /* Remove flag and configuration from all peer-group members, unless + * they are explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS_RO(peer->group->peer, node, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->flags_override, + PEER_FLAG_TIMER_DELAYOPEN)) + continue; + + /* Remove session attribute flag, reset the timer interval to + * the default value and set the timer value to zero. + */ + UNSET_FLAG(member->flags, PEER_FLAG_TIMER_DELAYOPEN); + member->delayopen = peer->bgp->default_delayopen; + member->v_delayopen = 0; + } + + return 0; +} + /* neighbor interface */ void peer_interface_set(struct peer *peer, const char *str) { |