|
|
|
|
@ -55,18 +55,18 @@ static void format_ip(uint32_t ip, char* buffer) {
|
|
|
|
|
snprintf(buffer, 16, "%u.%u.%u.%u", b[3], b[2], b[1], b[0]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
struct BGP_WITHDRAW_PACKET { |
|
|
|
|
uint8_t cmd; |
|
|
|
|
uint8_t subcmd; |
|
|
|
|
uint64_t node_id; |
|
|
|
|
} BGP_WITHDRAW_PACKET __attribute__((packed)); |
|
|
|
|
} __attribute__((packed)); |
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
struct BGP_REROUTE_PACKET { |
|
|
|
|
uint8_t cmd; |
|
|
|
|
uint8_t subcmd; |
|
|
|
|
uint64_t old_node_id; |
|
|
|
|
struct ROUTE_PEER_INFO peer_info; |
|
|
|
|
} BGP_REROUTE_PACKET __attribute__((packed)); |
|
|
|
|
} __attribute__((packed)); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Рассылает маршрут всем соединениям (кроме exclude) |
|
|
|
|
@ -288,6 +288,8 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ROUTE_BGP* bgp = instance->bgp; |
|
|
|
|
|
|
|
|
|
struct BGP_ENTRY_PACKET* pkt = (struct BGP_ENTRY_PACKET*)entry->dgram; |
|
|
|
|
|
|
|
|
|
// Проверяем команду
|
|
|
|
|
@ -309,17 +311,17 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
uint64_t old_node_id = 0; |
|
|
|
|
struct ROUTE_PEER_INFO *peer_info; |
|
|
|
|
if (pkt->subcmd == ROUTE_SUBCMD_ENTRY_REROUTE) { |
|
|
|
|
if (entry->len < sizeof(BGP_REROUTE_PACKET)) { |
|
|
|
|
if (entry->len < sizeof(struct BGP_REROUTE_PACKET)) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Invalid REROUTE packet size"); |
|
|
|
|
queue_dgram_free(entry); |
|
|
|
|
queue_entry_free(entry); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
BGP_REROUTE_PACKET *reroute_pkt = (BGP_REROUTE_PACKET*)pkt; |
|
|
|
|
struct BGP_REROUTE_PACKET *reroute_pkt = (struct BGP_REROUTE_PACKET*)pkt; |
|
|
|
|
old_node_id = be64toh(reroute_pkt->old_node_id); |
|
|
|
|
peer_info = &reroute_pkt->peer_info; |
|
|
|
|
} else { |
|
|
|
|
if (entry->len < sizeof(BGP_ENTRY_PACKET)) { |
|
|
|
|
if (entry->len < sizeof(struct BGP_ENTRY_PACKET)) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Invalid ENTRY packet size"); |
|
|
|
|
queue_dgram_free(entry); |
|
|
|
|
queue_entry_free(entry); |
|
|
|
|
@ -351,7 +353,6 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
new_route.hop_count = hop_count + 1; |
|
|
|
|
new_route.latency = latency + (from_conn->rtt_last * 10); |
|
|
|
|
new_route.metrics.latency_ms = new_route.latency / 10; |
|
|
|
|
new_route.metrics.hop_count = new_route.hop_count; |
|
|
|
|
// Set defaults for other metrics
|
|
|
|
|
new_route.metrics.bandwidth_kbps = 100000; // example default
|
|
|
|
|
new_route.metrics.packet_loss_rate = 0; |
|
|
|
|
@ -397,13 +398,13 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case ROUTE_SUBCMD_WITHDRAW: { |
|
|
|
|
if (entry->len < sizeof(BGP_WITHDRAW_PACKET)) { |
|
|
|
|
if (entry->len < sizeof(struct BGP_WITHDRAW_PACKET)) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Invalid WITHDRAW packet size"); |
|
|
|
|
queue_dgram_free(entry); |
|
|
|
|
queue_entry_free(entry); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
BGP_WITHDRAW_PACKET *withdraw_pkt = (BGP_WITHDRAW_PACKET*)pkt; |
|
|
|
|
struct BGP_WITHDRAW_PACKET *withdraw_pkt = (struct BGP_WITHDRAW_PACKET*)pkt; |
|
|
|
|
uint64_t withdrawn_node_id = be64toh(withdraw_pkt->node_id); |
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received WITHDRAW for node %016llx", |
|
|
|
|
@ -449,24 +450,22 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
struct BGP_NODEINFO_PACKET *info_pkt = (struct BGP_NODEINFO_PACKET*)pkt; |
|
|
|
|
struct NODE_CONNS_INFO *node_info = &info_pkt->node_info; |
|
|
|
|
|
|
|
|
|
if (node_info->connlist_count == 0) break; |
|
|
|
|
|
|
|
|
|
uint64_t target_node_id = be64toh(node_info->NODE_CONN_INFO[0].node_id); // assume first
|
|
|
|
|
uint64_t target_node_id = be64toh(info_pkt->conn_info.node_id); |
|
|
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received NODEINFO for node %016llx, count=%d", |
|
|
|
|
(unsigned long long)target_node_id, node_info->connlist_count); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Received NODEINFO for node %016llx", |
|
|
|
|
(unsigned long long)target_node_id); |
|
|
|
|
|
|
|
|
|
struct ROUTE_TABLE* table = instance->rt; |
|
|
|
|
for (size_t i = 0; i < table->count; i++) { |
|
|
|
|
if (table->entries[i].node_id == target_node_id) { |
|
|
|
|
size_t size = sizeof(struct NODE_CONNS_INFO) +
|
|
|
|
|
node_info->connlist_count * sizeof(struct NODE_CONN_INFO); |
|
|
|
|
sizeof(struct NODE_CONN_INFO); |
|
|
|
|
struct NODE_CONNS_INFO *new_list = u_malloc(size); |
|
|
|
|
if (new_list) { |
|
|
|
|
memcpy(new_list, node_info, size); |
|
|
|
|
new_list->connlist_count = 1; |
|
|
|
|
new_list->ref_count = 1; |
|
|
|
|
memcpy(&new_list->conn_info[0], &info_pkt->conn_info, sizeof(struct NODE_CONN_INFO)); |
|
|
|
|
|
|
|
|
|
if (table->entries[i].conn_list) { |
|
|
|
|
if (--table->entries[i].conn_list->ref_count == 0) { |
|
|
|
|
|