@ -441,14 +441,12 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
struct ROUTE_TABLE * rt = conn - > instance - > rt ;
struct ROUTE_TABLE * rt = conn - > instance - > rt ;
// Remove this connection from all nodes' path lists
// Remove this connection from all nodes' path lists
bool need_withdraw = false ;
int nodes_removed = 0 ;
int nodes_removed = 0 ;
struct ll_entry * node_entry = bgp - > nodes ? bgp - > nodes - > head : NULL ;
struct ll_entry * node_entry = bgp - > nodes ? bgp - > nodes - > head : NULL ;
while ( node_entry ) {
while ( node_entry ) {
struct ll_entry * next = node_entry - > next ;
struct ll_entry * next = node_entry - > next ;
struct NODEINFO_Q * nq = ( struct NODEINFO_Q * ) node_entry ;
struct NODEINFO_Q * nq = ( struct NODEINFO_Q * ) node_entry ;
if ( route_bgp_remove_path ( nq , conn ) = = 1 ) {
if ( route_bgp_remove_path ( nq , conn ) = = 1 ) {
need_withdraw = true ;
if ( rt ) route_delete ( rt , nq ) ;
if ( rt ) route_delete ( rt , nq ) ;
if ( conn - > instance & & conn - > instance - > control_srv )
if ( conn - > instance & & conn - > instance - > control_srv )
control_server_notify_node_removed ( conn - > instance - > control_srv , nq - > node . node_id ) ;
control_server_notify_node_removed ( conn - > instance - > control_srv , nq - > node . node_id ) ;
@ -460,6 +458,8 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
if ( entry ) { queue_remove_data ( bgp - > nodes , entry ) ; queue_entry_free ( entry ) ; }
if ( entry ) { queue_remove_data ( bgp - > nodes , entry ) ; queue_entry_free ( entry ) ; }
nodes_removed + + ;
nodes_removed + + ;
etcp_router_conn_close_all_for_node ( bgp - > instance , key ) ;
etcp_router_conn_close_all_for_node ( bgp - > instance , key ) ;
uint64_t wd_src = ( key = = conn - > peer_node_id ) ? conn - > instance - > node_id : conn - > peer_node_id ;
route_bgp_broadcast_withdraw ( bgp , key , wd_src , NULL ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_BGP , " Removed node %016llx after link down " , ( unsigned long long ) key ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_BGP , " Removed node %016llx after link down " , ( unsigned long long ) key ) ;
}
}
node_entry = next ;
node_entry = next ;
@ -477,12 +477,8 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
e = e - > next ;
e = e - > next ;
}
}
if ( need_withdraw ) {
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " BGP peer removed: %s nodes=%d " ,
route_bgp_broadcast_withdraw ( bgp , conn - > peer_node_id , conn - > instance - > node_id , NULL ) ;
conn - > log_name , nodes_removed ) ;
}
DEBUG_INFO ( DEBUG_CATEGORY_BGP , " BGP peer removed: %s nodes=%d withdraw=%d " ,
conn - > log_name , nodes_removed , need_withdraw ) ;
}
}
@ -755,7 +751,16 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co
uint8_t new_ver = ni - > ver ;
uint8_t new_ver = ni - > ver ;
if ( nodeinfo1 & & ( int8_t ) ( nodeinfo1 - > last_ver - new_ver ) > = 0 ) {
if ( nodeinfo1 & & ( int8_t ) ( nodeinfo1 - > last_ver - new_ver ) > = 0 ) {
DEBUG_TRACE ( DEBUG_CATEGORY_BGP , " NODEINFO ignored old ver: node=%016llx ver=%d<=%d from=%s " ,
int new_hops = ni - > hop_count + 1 ;
if ( new_hops < = MAX_HOPS ) {
uint64_t hop_list [ MAX_HOPS ] ;
uint64_t * pkt_hops = ( uint64_t * ) ( ( uint8_t * ) ni + sizeof ( struct NODEINFO ) + dyn_size ) ;
memcpy ( hop_list , pkt_hops , ni - > hop_count * 8 ) ;
hop_list [ ni - > hop_count ] = from - > peer_node_id ;
route_bgp_remove_path_by_hop ( nodeinfo1 , from - > peer_node_id ) ;
route_bgp_add_path ( nodeinfo1 , from , hop_list , new_hops ) ;
}
DEBUG_TRACE ( DEBUG_CATEGORY_BGP , " NODEINFO old ver: node=%016llx ver=%d<=%d from=%s (paths updated) " ,
( unsigned long long ) node_id , new_ver , nodeinfo1 - > last_ver , from - > log_name ) ;
( unsigned long long ) node_id , new_ver , nodeinfo1 - > last_ver , from - > log_name ) ;
return 0 ;
return 0 ;
}
}
@ -887,7 +892,7 @@ int route_bgp_process_withdraw(struct ROUTE_BGP* bgp, struct ETCP_CONN* sender,
return 0 ;
return 0 ;
}
}
int ret = route_bgp_remove_path_by_hop ( nq , wd_source ) ;
int ret = route_bgp_remove_path_by_hop ( nq , wd_source ) ;
if ( ret > 0 | | ! nq - > paths | | ( nq - > paths & & queue_entry_count ( nq - > paths ) = = 0 ) ) {
if ( ret = = 1 ) {
if ( bgp - > instance & & bgp - > instance - > rt ) route_delete ( bgp - > instance - > rt , nq ) ;
if ( bgp - > instance & & bgp - > instance - > rt ) route_delete ( bgp - > instance - > rt , nq ) ;
if ( bgp - > instance - > control_srv ) control_server_notify_node_removed ( bgp - > instance - > control_srv , node_id ) ;
if ( bgp - > instance - > control_srv ) control_server_notify_node_removed ( bgp - > instance - > control_srv , node_id ) ;
nq - > dirty = 1 ;
nq - > dirty = 1 ;