|
|
|
|
@ -1065,7 +1065,7 @@ int topo_group_add_path(struct TOPO_GROUP_NODE* nq, struct ETCP_CONN* conn, uint
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Удаляет пути, содержащие wd_source в hop_list; 1 — если путей не осталось. */ |
|
|
|
|
/* Удаляет пути, содержащие wd_source в hop_list; возвращает число удалённых путей. */ |
|
|
|
|
static int topo_group_remove_path_by_hop(struct TOPO_GROUP_NODE* nq, uint64_t wd_source) { |
|
|
|
|
if (!nq || !nq->paths) return 0; |
|
|
|
|
int removed = 0; |
|
|
|
|
@ -1077,7 +1077,7 @@ static int topo_group_remove_path_by_hop(struct TOPO_GROUP_NODE* nq, uint64_t wd
|
|
|
|
|
if (has_wd) { struct ll_entry* next = e->next; queue_remove_data(nq->paths, e); queue_entry_free(e); removed++; e = next; continue; } |
|
|
|
|
e = e->next; |
|
|
|
|
} |
|
|
|
|
if (removed > 0 && nq->paths && queue_entry_count(nq->paths) == 0) { queue_free(nq->paths); nq->paths = NULL; return 1; } |
|
|
|
|
if (removed > 0 && queue_entry_count(nq->paths) == 0) { queue_free(nq->paths); nq->paths = NULL; } |
|
|
|
|
return removed; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1314,8 +1314,12 @@ int topo_group_process_withdraw(struct TOPO_GROUP* group, struct ETCP_CONN* send
|
|
|
|
|
|
|
|
|
|
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(group, node_id); |
|
|
|
|
if (!nq) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "node not found"); return 0; } |
|
|
|
|
int ret = topo_group_remove_path_by_hop(nq, wd_source); |
|
|
|
|
if (ret == 1) { |
|
|
|
|
int removed = topo_group_remove_path_by_hop(nq, wd_source); |
|
|
|
|
int remaining = nq->paths ? queue_entry_count(nq->paths) : 0; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "WITHDRAW group=%016llx node=%016llx source=%016llx removed=%d remaining=%d", |
|
|
|
|
(unsigned long long)group->group_id, (unsigned long long)node_id, |
|
|
|
|
(unsigned long long)wd_source, removed, remaining); |
|
|
|
|
if (removed > 0 && remaining == 0) { |
|
|
|
|
nq->conn_presence = 0; nq->conn_up = 0; |
|
|
|
|
topo_fire_nodeinfo_cbk(group->instance, group, nq); |
|
|
|
|
if (group->group_type != TOPO_GROUP_TYPE_CHAT && group->instance && group->instance->rt) route_delete(group->instance->rt, nq); |
|
|
|
|
|