|
|
|
|
@ -6,17 +6,17 @@
|
|
|
|
|
#include <string.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include "../lib/platform_compat.h" |
|
|
|
|
#include "route_node.h" |
|
|
|
|
#include "route_lib.h" |
|
|
|
|
#include "route_bgp.h" |
|
|
|
|
#include "../lib/debug_config.h" |
|
|
|
|
#include "../lib/mem.h" |
|
|
|
|
#include "utun_instance.h" |
|
|
|
|
#include "etcp_api.h" |
|
|
|
|
#include "etcp.h" |
|
|
|
|
#include "etcp_connections.h" |
|
|
|
|
#include "etcp_debug.h" |
|
|
|
|
#include "utun_instance.h" |
|
|
|
|
#include "config_parser.h" |
|
|
|
|
#include "../lib/debug_config.h" |
|
|
|
|
#include "../lib/mem.h" |
|
|
|
|
#include "route_node.h" |
|
|
|
|
#include "route_lib.h" |
|
|
|
|
#include "route_bgp.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
@ -40,6 +40,11 @@ static void route_bgp_send_table_request(struct ROUTE_BGP* bgp, struct ETCP_CONN
|
|
|
|
|
etcp_send(conn, e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void route_bgp_add_to_senders(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); |
|
|
|
|
static bool route_bgp_should_send_to(const struct NODEINFO_Q* nq, uint64_t target_id); |
|
|
|
|
static void route_bgp_send_full_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); |
|
|
|
|
static void route_bgp_handle_request_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); |
|
|
|
|
|
|
|
|
|
static char* nodeinfo_format(const uint8_t* data, size_t len) { |
|
|
|
|
if (!data || len < sizeof(struct BGP_NODEINFO_PACKET)) return NULL; |
|
|
|
|
struct BGP_NODEINFO_PACKET* pkt = (struct BGP_NODEINFO_PACKET*)data; |
|
|
|
|
@ -144,22 +149,7 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
} else if (subcmd == ROUTE_SUBCMD_WITHDRAW) { |
|
|
|
|
route_bgp_process_withdraw(bgp, from_conn, data, entry->len); |
|
|
|
|
} else if (subcmd == ROUTE_SUBCMD_REQUEST_TABLE) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received table request from %s", from_conn->log_name); |
|
|
|
|
route_bgp_send_nodeinfo(bgp->local_node, from_conn); |
|
|
|
|
bool already = false; |
|
|
|
|
struct ll_entry* e = bgp->senders_list ? bgp->senders_list->head : NULL; |
|
|
|
|
while (e) { |
|
|
|
|
if (((struct ROUTE_BGP_CONN_ITEM*)e->data)->conn == from_conn) { already = true; break; } |
|
|
|
|
e = e->next; |
|
|
|
|
} |
|
|
|
|
if (!already) { |
|
|
|
|
struct ll_entry* item_entry = queue_entry_new(sizeof(struct ROUTE_BGP_CONN_ITEM)); |
|
|
|
|
if (item_entry) { |
|
|
|
|
((struct ROUTE_BGP_CONN_ITEM*)item_entry->data)->conn = from_conn; |
|
|
|
|
queue_data_put(bgp->senders_list, item_entry); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Added table requester to senders_list"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
route_bgp_handle_request_table(bgp, from_conn); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
queue_dgram_free(entry); |
|
|
|
|
@ -321,30 +311,8 @@ void route_bgp_new_conn(struct ETCP_CONN* conn) {
|
|
|
|
|
|
|
|
|
|
struct ROUTE_BGP* bgp = conn->instance->bgp; |
|
|
|
|
|
|
|
|
|
// === 1. Проверяем, уже есть ли это соединение в списке ===
|
|
|
|
|
bool already_exists = false; |
|
|
|
|
struct ll_entry* e = bgp->senders_list->head; |
|
|
|
|
while (e) { |
|
|
|
|
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data; |
|
|
|
|
if (item->conn == conn) { |
|
|
|
|
already_exists = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
e = e->next; |
|
|
|
|
} |
|
|
|
|
route_bgp_add_to_senders(bgp, conn); |
|
|
|
|
|
|
|
|
|
// === 2. Если нет — добавляем (только один раз) ===
|
|
|
|
|
if (!already_exists) { |
|
|
|
|
struct ll_entry* item_entry = queue_entry_new(sizeof(struct ROUTE_BGP_CONN_ITEM)); |
|
|
|
|
if (!item_entry) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
((struct ROUTE_BGP_CONN_ITEM*)item_entry->data)->conn = conn; |
|
|
|
|
queue_data_put(bgp->senders_list, item_entry); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "New connection added to senders_list"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// === 3. Отправляем запрос на получение таблицы (обе стороны при on_up) ===
|
|
|
|
|
route_bgp_send_table_request(bgp, conn); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -704,3 +672,66 @@ void route_bgp_send_nodeinfo(struct NODEINFO_Q* node, struct ETCP_CONN* conn) {
|
|
|
|
|
|
|
|
|
|
etcp_send(conn, e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void route_bgp_add_to_senders(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { |
|
|
|
|
if (!bgp || !conn || !bgp->senders_list) return; |
|
|
|
|
bool already = false; |
|
|
|
|
struct ll_entry* e = bgp->senders_list->head; |
|
|
|
|
while (e) { |
|
|
|
|
if (((struct ROUTE_BGP_CONN_ITEM*)e->data)->conn == conn) { already = true; break; } |
|
|
|
|
e = e->next; |
|
|
|
|
} |
|
|
|
|
if (!already) { |
|
|
|
|
struct ll_entry* item_entry = queue_entry_new(sizeof(struct ROUTE_BGP_CONN_ITEM)); |
|
|
|
|
if (item_entry) { |
|
|
|
|
((struct ROUTE_BGP_CONN_ITEM*)item_entry->data)->conn = conn; |
|
|
|
|
queue_data_put(bgp->senders_list, item_entry); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Added to senders_list"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool route_bgp_should_send_to(const struct NODEINFO_Q* nq, uint64_t target_id) { |
|
|
|
|
if (!nq || !nq->paths) return false; |
|
|
|
|
struct ll_entry* e = nq->paths->head; |
|
|
|
|
while (e) { |
|
|
|
|
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)e; |
|
|
|
|
uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)); |
|
|
|
|
bool has_id = false; |
|
|
|
|
for (uint8_t i = 0; i < path->hop_count; i++) { |
|
|
|
|
if (hop[i] == target_id) { has_id = true; break; } |
|
|
|
|
} |
|
|
|
|
if (!has_id) return true; |
|
|
|
|
e = e->next; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void route_bgp_send_full_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { |
|
|
|
|
if (!bgp || !conn) return; |
|
|
|
|
uint64_t target = conn->peer_node_id; |
|
|
|
|
struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL; |
|
|
|
|
while (e) { |
|
|
|
|
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; |
|
|
|
|
if (nq->node.hop_count == 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "local node in learned list"); |
|
|
|
|
e = e->next; continue; |
|
|
|
|
} |
|
|
|
|
if (!nq->paths) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "node has no paths"); |
|
|
|
|
e = e->next; continue; |
|
|
|
|
} |
|
|
|
|
if (route_bgp_should_send_to(nq, target)) { |
|
|
|
|
route_bgp_send_nodeinfo(nq, conn); |
|
|
|
|
} |
|
|
|
|
e = e->next; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void route_bgp_handle_request_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { |
|
|
|
|
if (!bgp || !conn) return; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received table request from %s", conn->log_name); |
|
|
|
|
route_bgp_send_nodeinfo(bgp->local_node, conn); |
|
|
|
|
route_bgp_send_full_table(bgp, conn); |
|
|
|
|
route_bgp_add_to_senders(bgp, conn); |
|
|
|
|
} |
|
|
|
|
|