|
|
|
|
@ -31,6 +31,22 @@ static void route_bgp_on_route_change(struct ROUTE_TABLE* table,
|
|
|
|
|
struct ROUTE_ENTRY* entry, |
|
|
|
|
int action, void* arg); |
|
|
|
|
|
|
|
|
|
static const char* route_type_to_str(route_type_t type) { |
|
|
|
|
switch (type) { |
|
|
|
|
case ROUTE_TYPE_STATIC: return "STATIC"; |
|
|
|
|
case ROUTE_TYPE_DYNAMIC: return "DYNAMIC"; |
|
|
|
|
case ROUTE_TYPE_LOCAL: return "LOCAL"; |
|
|
|
|
case ROUTE_TYPE_LEARNED: return "LEARNED"; |
|
|
|
|
default: return "UNKNOWN"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void format_ip(uint32_t ip, char* buffer) { |
|
|
|
|
if (!buffer) return; |
|
|
|
|
uint8_t* b = (uint8_t*)&ip; |
|
|
|
|
snprintf(buffer, 16, "%u.%u.%u.%u", b[3], b[2], b[1], b[0]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Колбэк для приема роутинг-пакетов от ETCP |
|
|
|
|
*
|
|
|
|
|
@ -66,8 +82,11 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received BGP packet: subcmd=%d, network=%08x/%d, node_id=%016llx", |
|
|
|
|
pkt->subcmd, ntohl(pkt->network), pkt->prefix_length & 0x3F, (unsigned long long)pkt->node_id); |
|
|
|
|
char ip_buf[16]; |
|
|
|
|
uint32_t network = ntohl(pkt->network); |
|
|
|
|
format_ip(network, ip_buf); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received BGP packet: subcmd=%d, network=%s/%d, node_id=%016llx", |
|
|
|
|
pkt->subcmd, ip_buf, pkt->prefix_length & 0x3F, (unsigned long long)pkt->node_id); |
|
|
|
|
|
|
|
|
|
switch (pkt->subcmd) { |
|
|
|
|
case ROUTE_SUBCMD_ENTRY: { |
|
|
|
|
@ -99,14 +118,16 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Вставляем в таблицу
|
|
|
|
|
char net_buf[16]; |
|
|
|
|
format_ip(route.network, net_buf); |
|
|
|
|
if (route_table_insert(instance->rt, &route)) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Added learned route: %08x/%d via node %016llx (hops=%d)", |
|
|
|
|
route.network, route.prefix_length,
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Added learned route: %s/%d via node %016llx (hops=%d)", |
|
|
|
|
net_buf, route.prefix_length, |
|
|
|
|
(unsigned long long)route.destination_node_id, |
|
|
|
|
route.metrics.hop_count); |
|
|
|
|
} else { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "Failed to insert route: %08x/%d", |
|
|
|
|
route.network, route.prefix_length); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "Failed to insert route: %s/%d", |
|
|
|
|
net_buf, route.prefix_length); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
@ -115,16 +136,18 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
// Удаление маршрута (withdrawal)
|
|
|
|
|
uint32_t network = ntohl(pkt->network); |
|
|
|
|
uint8_t prefix_length = pkt->prefix_length & 0x3F; |
|
|
|
|
char w_net_buf[16]; |
|
|
|
|
format_ip(network, w_net_buf); |
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Processing route withdrawal: %08x/%d from conn %p", |
|
|
|
|
network, prefix_length, (void*)from_conn); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Processing route withdrawal: %s/%d from conn %p", |
|
|
|
|
w_net_buf, prefix_length, (void*)from_conn); |
|
|
|
|
|
|
|
|
|
if (route_table_delete_entry(instance->rt, network, prefix_length, from_conn)) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Route withdrawn successfully: %08x/%d",
|
|
|
|
|
network, prefix_length); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Route withdrawn successfully: %s/%d",
|
|
|
|
|
w_net_buf, prefix_length); |
|
|
|
|
} else { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "Route to withdraw not found: %08x/%d", |
|
|
|
|
network, prefix_length); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "Route to withdraw not found: %s/%d", |
|
|
|
|
w_net_buf, prefix_length); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
@ -177,8 +200,10 @@ static void route_bgp_send_withdraw(struct ROUTE_BGP* bgp, struct ETCP_CONN* con
|
|
|
|
|
|
|
|
|
|
entry->len = sizeof(struct ROUTE_BGP_PACKET); |
|
|
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Sending withdraw: %08x/%d to conn %p", |
|
|
|
|
route->network, route->prefix_length, (void*)conn); |
|
|
|
|
char wd_net_buf[16]; |
|
|
|
|
format_ip(route->network, wd_net_buf); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Sending withdraw: %s/%d to conn %p", |
|
|
|
|
wd_net_buf, route->prefix_length, (void*)conn); |
|
|
|
|
|
|
|
|
|
// Отправляем через ETCP
|
|
|
|
|
if (etcp_send(conn, entry) != 0) { |
|
|
|
|
@ -240,8 +265,10 @@ static void route_bgp_on_route_change(struct ROUTE_TABLE* table,
|
|
|
|
|
// Не рассылаем маршруты через которые мы их получили (чтобы избежать петель)
|
|
|
|
|
// Это делается в цикле ниже
|
|
|
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Route change: action=%d, network=%08x/%d, type=%d", |
|
|
|
|
action, entry->network, entry->prefix_length, entry->type); |
|
|
|
|
char ch_net_buf[16]; |
|
|
|
|
format_ip(entry->network, ch_net_buf); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Route change: action=%d, network=%s/%d, type=%d", |
|
|
|
|
action, ch_net_buf, entry->prefix_length, entry->type); |
|
|
|
|
|
|
|
|
|
// Перебираем все соединения в senders_list
|
|
|
|
|
struct ll_entry* item_entry = bgp->senders_list->head; |
|
|
|
|
@ -302,11 +329,13 @@ static int route_bgp_send_route_single(struct ROUTE_BGP* bgp, struct ETCP_CONN*
|
|
|
|
|
|
|
|
|
|
entry->len = sizeof(struct ROUTE_BGP_PACKET); |
|
|
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Sending route: %08x/%d to conn %p, endpoint=%u.%u.%u.%u:%d", |
|
|
|
|
route->network, route->prefix_length & 0x3F, (void*)conn, |
|
|
|
|
(endpoint_ip >> 24) & 0xFF, (endpoint_ip >> 16) & 0xFF, |
|
|
|
|
(endpoint_ip >> 8) & 0xFF, endpoint_ip & 0xFF, |
|
|
|
|
ntohs(endpoint_port)); |
|
|
|
|
char sr_net_buf[16]; |
|
|
|
|
char sr_ep_buf[16]; |
|
|
|
|
format_ip(route->network, sr_net_buf); |
|
|
|
|
format_ip(ntohl(endpoint_ip), sr_ep_buf); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Sending route: %s/%d to conn %p, endpoint=%s:%d", |
|
|
|
|
sr_net_buf, route->prefix_length & 0x3F, (void*)conn, |
|
|
|
|
sr_ep_buf, ntohs(endpoint_port)); |
|
|
|
|
|
|
|
|
|
// Отправляем через ETCP
|
|
|
|
|
if (etcp_send(conn, entry) != 0) { |
|
|
|
|
@ -339,6 +368,20 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
char dbg_net[16], dbg_ep[16]; |
|
|
|
|
format_ip(route->network, dbg_net); |
|
|
|
|
format_ip(route->endpoint_ip, dbg_ep); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending route: %s/%d type=%s flags=0x%x " |
|
|
|
|
"metrics{hops=%u lat=%u kbps=%u loss=%u metric=%u} " |
|
|
|
|
"endpoint=%s:%u node_id=%016llx", |
|
|
|
|
dbg_net, route->prefix_length, |
|
|
|
|
route_type_to_str(route->type), route->flags, |
|
|
|
|
route->metrics.hop_count, route->metrics.latency_ms, |
|
|
|
|
route->metrics.bandwidth_kbps, route->metrics.packet_loss_rate, |
|
|
|
|
route->metrics.metric, |
|
|
|
|
dbg_ep, route->endpoint_port, |
|
|
|
|
(unsigned long long)route->destination_node_id); |
|
|
|
|
|
|
|
|
|
// Для LOCAL маршрутов - отправляем с нескольких endpoints если есть PUBLIC или NAT серверы
|
|
|
|
|
if (route->type == ROUTE_TYPE_LOCAL && conn->links) { |
|
|
|
|
// Сначала отправляем PUBLIC (приоритет), затем NAT
|
|
|
|
|
|