Check that late BGP allocation failure preserves accepted state

This commit is contained in:
evgeny committed 2026-10-24 15:51:43 +02:00
1 parent 145dd1e5ab
commit d1562bdd0e
2 files changed
+27

No files matched your search

+3
View File
@@ -707,6 +707,9 @@ test_group_ownership_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
test_group_exchange_SOURCES = test_group_exchange.c
test_group_exchange_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
test_group_exchange_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS)
if OS_LINUX
test_group_exchange_LDFLAGS = -Wl,--wrap=queue_entry_new
endif
test_bgp_paths_SOURCES = test_bgp_paths.c
test_bgp_paths_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib
+24
View File
@@ -10,6 +10,18 @@
#include "../lib/debug_config.h"
#include "../lib/platform_compat.h"
#ifdef __linux__
static int fail_path;
struct ll_entry* __real_queue_entry_new(size_t);
struct ll_entry* __wrap_queue_entry_new(size_t size) {
if (fail_path && size == sizeof(struct TOPO_NODEPATH) - sizeof(struct ll_entry) + sizeof(uint64_t)) {
fail_path = 0;
DEBUG_WARN(DEBUG_CATEGORY_BGP, "[fault] reject incoming BGP path allocation"); return NULL;
}
return __real_queue_entry_new(size);
}
#endif
static struct TOPO_GROUP_CONN_ITEM* peer(struct TOPO_GROUP* group) {
assert(group->senders_list->head && !group->senders_list->head->next);
return (struct TOPO_GROUP_CONN_ITEM*)group->senders_list->head->data;
@@ -140,6 +152,18 @@ int main(void) {
assert(queue_entry_count(routed->paths) == 1 && topo_group_find_conn_for_node(a, node.node_id) == conn);
assert(topo_group_process_withdraw(a, &relay, (const uint8_t*)&alternate_wd, sizeof(alternate_wd)) == 0);
assert(topo_node_find_by_id(a, node.node_id) == routed && queue_entry_count(routed->paths) == 1);
#ifdef __linux__
/* Поздний OOM не меняет подписанную запись, per-group поля и предыдущий путь. */
struct ll_queue* previous_paths = routed->paths;
struct TOPO_NODE* previous_record = topo_node_registry_find(inst->topo_groups, node.node_id);
uint32_t previous_refs = previous_record->group_ref_count;
fail_path = 1;
nodeinfo(a, conn, &node, &keys, a_id, 2);
assert(!fail_path && peer(a)->tx_failed && !topo_group_peer_ready(a, node.node_id));
assert(topo_node_find_by_id(a, node.node_id) == routed && routed->paths == previous_paths);
assert(routed->last_timestamp == 1 && previous_record->timestamp == 1 && previous_record->group_ref_count == previous_refs);
assert(queue_entry_count(routed->paths) == 1 && topo_group_find_conn_for_node(a, node.node_id) == conn);
#endif
etcp_fire_conn_status(conn, ETCP_CONN_STATUS_REINIT);
assert(topo_group_find_conn_for_node(a, node.node_id) == conn); /* REINIT preserves known paths */
assert(peer(a)->local_epoch != a_id && peer(b)->local_epoch != b_id);