Skip to content

Commit

Permalink
Merge "Process LLGR routes properly as suggested by LLGR spec"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Apr 17, 2016
2 parents 0a49053 + 823d8c5 commit 915a374
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 66 deletions.
7 changes: 7 additions & 0 deletions src/bgp/bgp_path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "bgp/bgp_route.h"
#include "bgp/bgp_peer.h"
#include "net/community_type.h"

using std::string;
using std::vector;
Expand Down Expand Up @@ -61,6 +62,12 @@ int BgpPath::PathCompare(const BgpPath &rhs, bool allow_ecmp) const {
// Compare sequence_number in reverse order as larger is better.
KEY_COMPARE(rattr->sequence_number(), attr_->sequence_number());

// Route without LLGR_STALE community is always preferred over one with.
KEY_COMPARE(attr_->community() &&
attr_->community()->ContainsValue(CommunityType::LlgrStale),
rattr->community() && rattr->community()->ContainsValue(
CommunityType::LlgrStale));

// For ECMP paths, above checks should suffice
if (allow_ecmp)
return 0;
Expand Down
47 changes: 36 additions & 11 deletions src/bgp/bgp_peer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,23 @@ class BgpPeer::PeerClose : public IPeerClose {
void Close() {

// Process closure through close manager only if this is a flip.
if (manager_->state() != PeerCloseManager::GR_TIMER ||
if ((manager_->state() != PeerCloseManager::GR_TIMER &&
manager_->state() != PeerCloseManager::LLGR_TIMER) ||
peer_->state_machine()->get_state() == StateMachine::ESTABLISHED) {
manager_->Close();
return;
}

if (peer_->IsDeleted()) {
peer_->RetryDelete();
} else {
Delete();
CloseComplete();
}
}

virtual void Delete() {
peer_->gr_params().Initialize();
peer_->llgr_params().Initialize();
peer_->graceful_restart_families().clear();
peer_->long_lived_graceful_restart_families().clear();
if (peer_->IsDeleted()) {
Expand All @@ -75,14 +82,17 @@ class BgpPeer::PeerClose : public IPeerClose {
}
}

// Return the time to wait for, in seconds to exit GR_TIMER state.
virtual const int GetGracefulRestartTime() const {
int time = peer_->gr_params_.time * 1000;
time += peer_->llgr_params_.time * 1000;
return peer_->gr_params_.time;
}

return time;
// Return the time to wait for, in seconds to exit LLGR_TIMER state.
virtual const int GetLongLivedGracefulRestartTime() const {
return peer_->llgr_params_.time;
}

bool IsGRReady() {
bool IsGRReady() const {
// Check if GR is supported by the peer.
if (peer_->gr_params().families.empty())
return false;
Expand Down Expand Up @@ -115,7 +125,7 @@ class BgpPeer::PeerClose : public IPeerClose {

// If the peer is deleted or administratively held down, do not attempt
// graceful restart
virtual bool IsCloseGraceful() {
virtual bool IsCloseGraceful() const {
if (peer_->IsDeleted() || peer_->IsAdminDown())
return false;
if (peer_->server()->IsDeleted())
Expand All @@ -125,6 +135,19 @@ class BgpPeer::PeerClose : public IPeerClose {
return true;
}

// Check if we need to trigger Long Lived Graceful Restart. In addition to
// normal GR checks, we also need to check LLGR capability was negotiated
// and non-zero restart time was inferred.
virtual bool IsCloseLongLivedGraceful() const {
if (!IsCloseGraceful())
return false;
if (peer_->llgr_params().families.empty())
return false;
if (!peer_->llgr_params().time)
return false;
return true;
}

// Close process for this peer is complete. Restart the state machine and
// attempt to bring up session with the neighbor
virtual void CloseComplete() {
Expand Down Expand Up @@ -882,8 +905,9 @@ bool BgpPeer::IsCloseInProgress() const {

// trigger is set only after defer_close is reset
assert(!(defer_close_ && trigger_.IsSet()));
return (defer_close_ || trigger_.IsSet() ||
peer_close_->close_manager()->IsCloseInProgress());
return defer_close_ || trigger_.IsSet() ||
(peer_close_->close_manager()->IsCloseInProgress() &&
!peer_close_->close_manager()->IsInGracefulRestartTimerWait());
}

StateMachine::State BgpPeer::GetState() const {
Expand Down Expand Up @@ -1198,8 +1222,9 @@ bool BgpPeer::SetGRCapabilities(BgpPeerInfoData *peer_info) {
// If GR is no longer supported, terminate GR right away. This can happen
// due to mis-match between gr and llgr afis. For now, we expect an
// identical set.
if (peer_close_->close_manager()->state() == PeerCloseManager::GR_TIMER &&
!peer_close_->IsGRReady()) {
if ((peer_close_->close_manager()->state() == PeerCloseManager::GR_TIMER ||
peer_close_->close_manager()->state() == PeerCloseManager::LLGR_TIMER)
&& !peer_close_->IsGRReady()) {
Close();
return false;
}
Expand Down
9 changes: 6 additions & 3 deletions src/bgp/bgp_peer.sandesh
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,14 @@ struct PeerCloseInfo {
5: u64 nested;
6: u64 deletes;
7: u64 stale;
15: u64 llgr_stale;
8: u64 sweep;
9: u64 gr_timer;
14: u64 llgr_timer;
10: u64 deleted_state_paths;
11: u64 deleted_paths;
12: u64 marked_state_paths;
12: u64 marked_stale_paths;
13: u64 marked_llgr_stale_paths;
}

struct BgpNeighborResp {
Expand Down Expand Up @@ -87,8 +90,8 @@ struct BgpNeighborResp {
45: optional list<string> auth_keys;
38: optional list<string> configured_address_families;
39: optional list<string> negotiated_address_families;
56: optional list<string> graceful_restart_address_families;
57: optional list<string> long_lived_graceful_restart_address_families;
57: optional list<string> graceful_restart_address_families;
58: optional list<string> long_lived_graceful_restart_address_families;
49: optional list<ShowBgpNeighborFamily> family_attributes_list;
40: optional u32 configured_hold_time;
41: u32 negotiated_hold_time;
Expand Down

0 comments on commit 915a374

Please sign in to comment.