From 1f84fda9d7e4aef8bfc9ff9d4cb0e6861500434d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Br=C3=A4uer?= Date: Sat, 9 Aug 2025 20:25:02 +0200 Subject: [PATCH] aspa: Remove in-place update algorithm - The in-place update algorithm didn't work anymore after upgrading the swap-in algorithm to draft version 21 of [sidrops-8210bis]. Since swap-in was the default algorithm, all code related to the in-place algorithm has been removed (at least for now). [sidrops-8210bis]: https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-8210bis-21 --- rtrlib/aspa/aspa.c | 333 ------------------------------------- rtrlib/aspa/aspa.h | 2 +- rtrlib/aspa/aspa_private.h | 85 ++-------- rtrlib/rtr/packets.c | 141 ---------------- tests/test_aspa.c | 12 +- 5 files changed, 14 insertions(+), 559 deletions(-) diff --git a/rtrlib/aspa/aspa.c b/rtrlib/aspa/aspa.c index ce5134fe..4585e793 100644 --- a/rtrlib/aspa/aspa.c +++ b/rtrlib/aspa/aspa.c @@ -640,336 +640,3 @@ void aspa_table_update_swap_in_discard(struct aspa_update **update_pointer) { aspa_table_update_swap_in_consume(update_pointer, false); } - -// MARK: - In-Place Update Mechanism - -enum aspa_status aspa_table_update_in_place(struct aspa_table *aspa_table, struct rtr_socket *rtr_socket, - struct aspa_update_operation *operations, size_t count, - struct aspa_update_operation **failed_operation) -{ - // Fail hard in debug builds. - assert(aspa_table); - assert(rtr_socket); - assert(failed_operation); - - if (!aspa_table || !rtr_socket || !failed_operation || ((count > 0) && !operations)) - return ASPA_ERROR; - - if (count == 0) - return ASPA_SUCCESS; - - // stable sort operations, so operations dealing with the same customer ASN - // are located right next to each other - qsort(operations, count, sizeof(struct aspa_update_operation), compare_update_operations); - - pthread_rwlock_wrlock(&aspa_table->lock); - struct aspa_store_node **node = aspa_store_get_node(&aspa_table->store, rtr_socket); - - if (!node || !*node) { - // The given table doesn't have a node for that socket, so create one - struct aspa_array *a = NULL; - - if (aspa_array_create(&a) != ASPA_SUCCESS) - return ASPA_ERROR; - - // Insert into table - if (aspa_store_create_node(&aspa_table->store, rtr_socket, a, &node) != ASPA_SUCCESS || !node || - !*node) { - aspa_array_free(a, false); - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_ERROR; - } - } - - assert(node); - assert(*node); - assert((*node)->aspa_array); - - struct aspa_array *array = (*node)->aspa_array; - size_t existing_i = 0; - - // preemptively allocating enough space - aspa_array_reserve(array, count + array->size); - - for (size_t i = 0; i < count; i++) { - struct aspa_update_operation *current = &operations[i]; - struct aspa_update_operation *next = (i < count - 1) ? &(operations[i + 1]) : NULL; - -#ifndef NDEBUG - // Sanity check record - if (current->type == ASPA_REMOVE) { - assert(current->record.provider_count == 0); - assert(!current->record.provider_asns); - } -#endif - - // Sort providers. - // We consider this an implementation detail, callers must not make any assumptions on the - // ordering of provider ASNs. - if (current->record.provider_count > 0 && current->record.provider_asns) - qsort(current->record.provider_asns, current->record.provider_count, sizeof(uint32_t), - compare_asns); - - while (existing_i < array->size && - aspa_array_get_record(array, existing_i)->customer_asn < current->record.customer_asn) { - existing_i += 1; - } - - struct aspa_record *existing_record = aspa_array_get_record(array, existing_i); - - // existing record and current op have matching CAS - bool existing_matches_current = existing_record && - existing_record->customer_asn == current->record.customer_asn; - - // next record and current op have matching CAS - bool next_matches_current = next && next->record.customer_asn == current->record.customer_asn; - - // MARK: Handling 'add' operations - if (current->type == ASPA_ADD) { - // Attempt to add record with $CAS, but record with $CAS already exists - // Error: Duplicate Add. - if (existing_matches_current) { - *failed_operation = current; - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_DUPLICATE_RECORD; - } - - // This operation adds a record with $CAS, the next op however removes this $CAS record again. - if (next_matches_current && next->type == ASPA_REMOVE) { -#if ASPA_NOTIFY_NO_OPS - // Complete record's providers for clients - next->record = current->record; - aspa_table_notify_clients(aspa_table, ¤t->record, rtr_socket, current->type); - aspa_table_notify_clients(aspa_table, &next->record, rtr_socket, next->type); -#endif - - // Mark as no-op. - current->is_no_op = true; - next->is_no_op = true; - - // Skip next - i += 1; - continue; - } - - // Add record by appending it to new array (copy providers) - if (aspa_array_insert(array, existing_i, ¤t->record, true) != ASPA_SUCCESS) { - *failed_operation = current; - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_ERROR; - } - } - - // MARK: Handling 'remove' operations - else if (current->type == ASPA_REMOVE) { - // Attempt to remove record with $CAS, but record with $CAS does not exist - // Error: Removal of unknown record. - if (!existing_matches_current) { - *failed_operation = current; - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_RECORD_NOT_FOUND; - } - - // If it's a remove operation, we insert a reference to the removed record's providers. - current->record.provider_count = existing_record->provider_count; - current->record.provider_asns = existing_record->provider_asns; - - // Remove record (don't release providers) - if (aspa_array_remove(array, existing_i, false) != ASPA_SUCCESS) { - *failed_operation = current; - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_RECORD_NOT_FOUND; - } - } - - // Notify clients - aspa_table_notify_clients(aspa_table, ¤t->record, rtr_socket, current->type); - } - - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_SUCCESS; -} - -static enum aspa_status aspa_table_update_in_place_undo_internal(struct aspa_table *aspa_table, - struct rtr_socket *rtr_socket, - struct aspa_update_operation *operations, size_t count, - struct aspa_update_operation *failed_operation) -{ - // Fail hard in debug builds. - assert(aspa_table); - assert(rtr_socket); - assert(operations); - assert(count > 0); - - pthread_rwlock_wrlock(&aspa_table->lock); - struct aspa_store_node **node = aspa_store_get_node(&aspa_table->store, rtr_socket); - - if (!node || !*node || !(*node)->aspa_array) { - // Node/array is gone -- nothing we can undo - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_ERROR; - } - - assert(node); - assert(*node); - assert((*node)->aspa_array); - - struct aspa_array *array = (*node)->aspa_array; - size_t existing_i = 0; - - for (size_t i = 0; i < array->size; i++) { - struct aspa_update_operation *current = &operations[i]; - struct aspa_update_operation *next = (i < count - 1) ? &(operations[i + 1]) : NULL; - - // Check if this operation and the following were executed in the first place - if (failed_operation && current == failed_operation) - break; - - while (existing_i < array->size && - aspa_array_get_record(array, existing_i)->customer_asn < current->record.customer_asn) { - existing_i += 1; - } - - struct aspa_record *existing_record = aspa_array_get_record(array, existing_i); - - // existing record and current op have matching CAS - bool existing_matches_current = existing_record && - existing_record->customer_asn == current->record.customer_asn; - - // next record and current op have matching CAS - bool next_matches_current = next && next->record.customer_asn == current->record.customer_asn; - - // MARK: Undo 'add' operation - if (current->type == ASPA_ADD) { - // Attempt to remove record with $CAS, but record with $CAS does not exist - // Error: Removal of unknown record. - if (!existing_matches_current) { - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_RECORD_NOT_FOUND; - } - - // This operation adds a record with $CAS, the next op however removes this $CAS record again. - if (next_matches_current && next->type == ASPA_REMOVE) { -#if ASPA_NOTIFY_NO_OPS - // If it's a remove operation, we insert a reference to the removed record's providers. - next->record = current->record; - aspa_table_notify_clients(aspa_table, &next->record, rtr_socket, ASPA_ADD); - aspa_table_notify_clients(aspa_table, ¤t->record, rtr_socket, ASPA_REMOVE); -#endif - - // Mark as no-op. - current->is_no_op = true; - next->is_no_op = true; - - // Skip next - i += 1; - continue; - } - - // Remove record (release providers) - if (aspa_array_remove(array, existing_i, true) != ASPA_SUCCESS) { - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_RECORD_NOT_FOUND; - } - - aspa_table_notify_clients(aspa_table, ¤t->record, rtr_socket, ASPA_REMOVE); - } - - // MARK: Undo 'remove' operation - else if (current->type == ASPA_REMOVE) { - // Next adds record with $CAS again. - // Treat these two as a 'replace' op - if (existing_matches_current & next_matches_current && next->type == ASPA_ADD) { - if (existing_record->provider_asns) - lrtr_free(existing_record->provider_asns); - - // If it's a remove operation, we inserted a reference to the existing - // provider array. Put back reference. - existing_record->provider_asns = current->record.provider_asns; - existing_record->provider_count = current->record.provider_count; - i += 1; - - aspa_table_notify_clients(aspa_table, &next->record, rtr_socket, ASPA_REMOVE); - } else { - // Attempt to add record with $CAS, but record with $CAS already exists - // Error: Duplicate Add. - if (existing_matches_current) { - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_DUPLICATE_RECORD; - } - - // Insert record (don't copy providers) - if (aspa_array_insert(array, existing_i, ¤t->record, false) != ASPA_SUCCESS) { - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_ERROR; - } - } - - aspa_table_notify_clients(aspa_table, ¤t->record, rtr_socket, ASPA_ADD); - - // If it's a remove operation, we inserted a reference to the existing - // provider array. Restore that 'remove' operation back to its original state. - current->record.provider_count = 0; - current->record.provider_asns = NULL; - } - } - - pthread_rwlock_unlock(&aspa_table->lock); - return ASPA_SUCCESS; -} - -enum aspa_status aspa_table_update_in_place_undo(struct aspa_table *aspa_table, struct rtr_socket *rtr_socket, - struct aspa_update_operation *operations, size_t count, - struct aspa_update_operation *failed_operation) -{ - // Fail hard in debug builds. - assert(aspa_table); - assert(rtr_socket); - - if (!aspa_table || !rtr_socket || ((count > 0) && !operations)) - return ASPA_ERROR; - - if (count == 0) - return ASPA_SUCCESS; - - enum aspa_status res = - aspa_table_update_in_place_undo_internal(aspa_table, rtr_socket, operations, count, failed_operation); - - for (size_t i = 0; i < count; i++) { - struct aspa_update_operation *op = &operations[i]; - - // If it's a remove operation, we inserted a reference to the removed record's providers. - // Restore that 'remove' operation back to its original state. - if (op->type == ASPA_REMOVE) { - op->record.provider_asns = NULL; - op->record.provider_count = 0; - } - } - - return res; -} - -void aspa_table_update_in_place_cleanup(struct aspa_update_operation **operations, size_t count) -{ - if (!operations || !*operations) - return; - - // If count == 0, this won't be executed - for (size_t i = 0; i < count; i++) { - struct aspa_update_operation *op = &(*operations)[i]; - - // If it's a remove operation, we inserted a reference to the removed record's providers. - // Release that provider array now and restore that 'remove' - // operation back to its original state. - if (!op->is_no_op && op->type == ASPA_REMOVE) { - if (op->record.provider_asns) - lrtr_free(op->record.provider_asns); - - op->record.provider_asns = NULL; - op->record.provider_count = 0; - } - } - - lrtr_free(*operations); - *operations = NULL; -} diff --git a/rtrlib/aspa/aspa.h b/rtrlib/aspa/aspa.h index 5930b0e5..04b03ade 100644 --- a/rtrlib/aspa/aspa.h +++ b/rtrlib/aspa/aspa.h @@ -169,7 +169,7 @@ enum aspa_verification_result aspa_verify_as_path(struct aspa_table *aspa_table, enum aspa_direction direction); /** - * @brief Collapses an `AS_PATH` in-place, replacing in-series repetitions with single occurences + * @brief Collapses an `AS_PATH` in-place, replacing in-series repetitions with single occurrences * * @return Length of the given array. */ diff --git a/rtrlib/aspa/aspa_private.h b/rtrlib/aspa/aspa_private.h index ce1d2e06..10e51dc9 100644 --- a/rtrlib/aspa/aspa_private.h +++ b/rtrlib/aspa/aspa_private.h @@ -15,47 +15,32 @@ * * # Updating an ASPA table * ASPA tables implement aggregated updating using an array of 'add record' and 'remove record' operations -- - * reducing iterations and memory allocations. E.g., these operations can be derived from a RTR cache response. - * Currently, two distinct update mechanisms are supported: **Swap-In** and **In-Place** updates. Use the macro - * `ASPA_UPDATE_MECHANISM` in rtr/packets.c to configure which implementation is used during syncing. - * The array of operations is effectively a diff to the table's previous state. This diff can be conveniently used to - * notify callers about changes once the update is applied. + * reducing iterations and memory allocations. E.g., these operations can be derived from an RTR cache response. + * Currently, one update mechanism is supported: **Swap-In**. + * + * The array of operations is effectively a diff to the table's previous state. This diff can be conveniently + * used to notify callers about changes once the update is applied. * * ## Swap-In Update Mechanism - * The ASPA table's **Swap-In** update mechanism avoids blocking callers who want to - * verify an `AS_PATH` (and therefore need read access to the table) while an update is in progress and removes the - * need for an *undo mechanism* in case the update to the ASPA table itself or some other action performed + * The ASPA table's **Swap-In** update mechanism avoids blocking callers who want to verify an `AS_PATH` + * (and therefore need read access to the table) while an update is in progress and removes the need for + * an *undo mechanism* in case the update to the ASPA table itself or some other action performed * inbetween fails. * * Performing an update using this mechanism involves these steps: * - **Compute Update**: * Every time you want to update a given ASPA table, call `aspa_table_update_swap_in_compute`. - * This will create a new ASPA array, appending both existing records and new records. Everything needed to update - * the table is stored in an update structure. + * This will create a new ASPA array, appending both existing records and new records. Everything + * needed to update the table is stored in an update structure. * - **Apply Update** or **Discard Update**: * You either have to apply the update using `aspa_table_update_swap_in_apply` or discard it by calling * `aspa_table_update_swap_in_discard`. This will either swap in the newly created ASPA array and notify * clients about changes or discard and release data that's now unused. * - * The implementation guarantess no changes are made to the ASPA table between + * The implementation guarantees no changes are made to the ASPA table between * calling `aspa_table_update_swap_in_compute` and `aspa_table_update_swap_in_apply` * or `aspa_table_update_swap_in_discard`. * - * ## In-Place Update Mechanism - * The ASPA table's **In-Place** update mechanism involves in-place modifications to the array of records - * and an undo function that undoes changes made previously. - * - * Performing an update using this mechanism involves these steps: - * - **Update**: - * Every time you want to update a given ASPA table, call `aspa_table_update_in_place`. This will modify the ASPA - * array. If the update fails, `failed_operation` will be set to the operation where the error occurring. - * - **Undo Update**: - * You may, but do not need to, undo the update using `aspa_table_update_in_place_undo`. This will undo all - * operations up to `failed_operation` or all operations. - * - **Clean Up**: - * After computing the update you should go through a cleanup step using `aspa_table_update_in_place_cleanup`. - * This will deallocate provider arrays and other data created during the update that's now unused. - * * ## Special Cases * There're various cases that need to be handled appropriately by both implementations. * 1. **Add existing record**: @@ -218,53 +203,5 @@ void aspa_table_update_swap_in_apply(struct aspa_update **update); */ void aspa_table_update_swap_in_discard(struct aspa_update **update); -// MARK: - In-Place Update Mechanism - -/** - * @brief Updates the given ASPA table. - * - * @note Each record in an 'add' operation may have a provider array associated with it. Any record in a 'remove' - * operation must have its `provider_count` set to `0` and `provider_array` set to `NULL`. - * - * @param[in] aspa_table ASPA table to store new ASPA data in. - * @param[in] rtr_socket The socket the updates originate from. - * @param[in] operations Add and remove operations to perform. - * @param[in] count Number of operations. - * @param[out] failed_operation Failed operation, filled in if update fails. - * @return @c ASPA_SUCCESS On success. - * @return @c ASPA_RECORD_NOT_FOUND If a records is supposed to be removed but cannot be found. - * @return @c ASPA_DUPLICATE_RECORD If a records is supposed to be added but its corresponding customer ASN already - * exists. - * @return @c ASPA_ERROR On other failures. - */ -enum aspa_status aspa_table_update_in_place(struct aspa_table *aspa_table, struct rtr_socket *rtr_socket, - struct aspa_update_operation *operations, size_t count, - struct aspa_update_operation **failed_operation); - -/** - * @brief Tries to undo @c operations up to @p failed_operation and then releases all operations. - * - * @param[in] aspa_table ASPA table to store new ASPA data in. - * @param[in] rtr_socket The socket the updates originate from. - * @param[in] operations Add and remove operations to perform. - * @param[in] count Number of operations. - * @param[in] failed_operation Failed operation. - * @return @c ASPA_SUCCESS On success. - * @return @c ASPA_RECORD_NOT_FOUND If a records is supposed to be removed but cannot be found. - * @return @c ASPA_DUPLICATE_RECORD If a records is supposed to be added but its corresponding customer ASN already - * exists. - * @return @c ASPA_ERROR On other failures. - */ -enum aspa_status aspa_table_update_in_place_undo(struct aspa_table *aspa_table, struct rtr_socket *rtr_socket, - struct aspa_update_operation *operations, size_t count, - struct aspa_update_operation *failed_operation); - -/** - * @brief Releases operations and unused provider arrays. - * @param[in] operations Add and remove operations. - * @param[in] count Number of operations. - */ -void aspa_table_update_in_place_cleanup(struct aspa_update_operation **operations, size_t count); - #endif /* RTR_ASPA_PRIVATE_H */ /** @} */ diff --git a/rtrlib/rtr/packets.c b/rtrlib/rtr/packets.c index 940b8696..8d51fe66 100644 --- a/rtrlib/rtr/packets.c +++ b/rtrlib/rtr/packets.c @@ -35,14 +35,6 @@ #define TEMPORARY_PDU_STORE_INCREMENT_VALUE 100 #define MAX_SUPPORTED_PDU_TYPE 10 -/** - * @brief @c ASPA_UPDATE_MECHANISM macro sets the mechanism used in this file to update the ASPA table. - * @see aspa/aspa_private.h - */ -#define ASPA_IN_PLACE 'P' -#define ASPA_SWAP_IN 'S' -#define ASPA_UPDATE_MECHANISM ASPA_SWAP_IN - struct aspa_pdu_list_node { struct pdu_aspa *pdu; struct aspa_pdu_list_node *next; @@ -1062,7 +1054,6 @@ static int rtr_update_spki_table(struct rtr_socket *rtr_socket, struct spki_tabl return RTR_SUCCESS; } -#if ASPA_UPDATE_MECHANISM == ASPA_SWAP_IN static int rtr_compute_update_aspa_table(struct rtr_socket *rtr_socket, struct aspa_table *aspa_table, struct pdu_aspa **aspa_pdus, size_t pdu_count, struct aspa_update **update) { @@ -1137,98 +1128,6 @@ static int rtr_compute_update_aspa_table(struct rtr_socket *rtr_socket, struct a RTR_DBG1("ASPA update computed"); return RTR_SUCCESS; } -#endif - -#if ASPA_UPDATE_MECHANISM == ASPA_IN_PLACE -/** - * @brief Undoes changes made to the given @p aspa_table based on an array of @c aspa_update_operation s. - */ -static int rtr_undo_update_aspa_table(struct rtr_socket *rtr_socket, struct aspa_table *aspa_table, - struct aspa_update_operation *operations, size_t count, - struct aspa_update_operation *failed_operation) -{ - enum aspa_status res = - aspa_table_update_in_place_undo(aspa_table, rtr_socket, operations, count, failed_operation); - - if (res == ASPA_SUCCESS) { - return RTR_SUCCESS; - } - // Undo failed, cannot recover, remove all records associated with the socket instead - RTR_DBG1("Couldn't undo all update operations from failed data synchronisation: Purging all ASPA records"); - aspa_table_src_remove(aspa_table, rtr_socket, true); - return RTR_ERROR; -} - -static int rtr_update_aspa_table(struct rtr_socket *rtr_socket, struct aspa_table *aspa_table, - struct pdu_aspa **aspa_pdus, size_t pdu_count, struct aspa_update_operation **ops, - struct aspa_update_operation **failed_operation) -{ - // Fail hard in debug builds. - assert(rtr_socket); - assert(failed_operation); - assert(ops); - - // no aspa table was configured hence we ignore incoming aspa objects - if (aspa_table == NULL) { - const char txt[] = "IGNORING INCOMING ASPA OBJECTS"; - RTR_DBG("%s", txt); - retrun RTR_SUCESS; - } - - if (!ops || !failed_operation || (pdu_count > 0 && !aspa_pdus)) - return RTR_ERROR; - - if (!aspa_pdus && pdu_count == 0) - return RTR_SUCCESS; - - struct aspa_update_operation *operations = lrtr_malloc(sizeof(struct aspa_update_operation) * pdu_count); - - if (!operations) { - const char txt[] = "Malloc failed"; - - RTR_DBG("%s", txt); - rtr_send_error_pdu_from_host(rtr_socket, NULL, 0, INTERNAL_ERROR, txt, sizeof(txt)); - rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); - return RTR_ERROR; - } - - *ops = operations; - - for (size_t i = 0; i < pdu_count; i++) { - rtr_aspa_pdu_2_aspa_operation(aspa_pdus[i], &operations[i]); - operations[i].index = i; - } - - enum aspa_status res = - aspa_table_update_in_place(aspa_table, rtr_socket, operations, pdu_count, failed_operation); - - if (*failed_operation) { - struct pdu_aspa *pdu = aspa_pdus[(*failed_operation)->index]; - size_t pdu_size = pdu->len; - - if (res == ASPA_DUPLICATE_RECORD) { - RTR_DBG("Duplicate Announcement for ASPA customer ASN: %u received", pdu->customer_asn); - rtr_send_error_pdu_from_host(rtr_socket, pdu, pdu_size, DUPLICATE_ANNOUNCEMENT, NULL, 0); - rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); - return RTR_ERROR; - } else if (res == ASPA_RECORD_NOT_FOUND) { - RTR_DBG("Withdrawal of unknown ASPA customer ASN: %u", pdu->customer_asn); - rtr_send_error_pdu_from_host(rtr_socket, pdu, pdu_size, WITHDRAWAL_OF_UNKNOWN_RECORD, NULL, 0); - rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); - return RTR_ERROR; - } - } else if (res != ASPA_SUCCESS) { - const char txt[] = "aspa_table Error"; - - RTR_DBG("%s", txt); - rtr_send_error_pdu_from_host(rtr_socket, NULL, 0, INTERNAL_ERROR, txt, sizeof(txt)); - rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); - return RTR_ERROR; - } - - return RTR_SUCCESS; -} -#endif static int rtr_sync_update_tables(struct rtr_socket *rtr_socket, struct pfx_table *pfx_table, struct spki_table *spki_table, struct aspa_table *aspa_table, @@ -1240,14 +1139,7 @@ static int rtr_sync_update_tables(struct rtr_socket *rtr_socket, struct pfx_tabl { bool proceed = true; bool undo_failed = false; -#if ASPA_UPDATE_MECHANISM == ASPA_SWAP_IN struct aspa_update *aspa_update = NULL; -#elif ASPA_UPDATE_MECHANISM == ASPA_IN_PLACE - struct aspa_update_operation *aspa_failed_operation = NULL; - struct aspa_update_operation *aspa_operations = NULL; -#else -#error "Invalid ASPA_UPDATE_MECHANISM value." -#endif /* ASPA_UPDATE_MECHANISM */ // add all IPv4 prefix pdu to the pfx_table for (size_t i = 0; i < ipv4_pdu_count; i++) { @@ -1303,7 +1195,6 @@ static int rtr_sync_update_tables(struct rtr_socket *rtr_socket, struct pfx_tabl } } -#if ASPA_UPDATE_MECHANISM == ASPA_SWAP_IN if (proceed) { RTR_DBG1("spki data added"); @@ -1329,38 +1220,6 @@ static int rtr_sync_update_tables(struct rtr_socket *rtr_socket, struct pfx_tabl aspa_table_update_swap_in_discard(&aspa_update); } -#elif ASPA_UPDATE_MECHANISM == ASPA_IN_PLACE - if (proceed) { - RTR_DBG1("spki data added"); - - if (rtr_update_aspa_table(rtr_socket, aspa_table, aspa_pdus, aspa_pdu_count, &aspa_operations, - &aspa_failed_operation) == RTR_ERROR) { - RTR_DBG1("error while updating ASPA data"); - proceed = false; - - if (rtr_undo_update_aspa_table(rtr_socket, aspa_table, aspa_operations, aspa_pdu_count, - aspa_failed_operation) == RTR_ERROR) - undo_failed = true; - - if (rtr_undo_update_spki_table_batch(rtr_socket, spki_table, router_key_pdus, - router_key_pdu_count) == RTR_ERROR) - undo_failed = true; - - if (rtr_undo_update_pfx_table_batch(rtr_socket, pfx_table, ipv4_pdus, ipv4_pdu_count, ipv6_pdus, - ipv6_pdu_count) == RTR_ERROR) - undo_failed = true; - } - } - - if (proceed) - RTR_DBG1("ASPA data added"); - - aspa_table_update_in_place_cleanup(&aspa_operations, aspa_pdu_count); - aspa_failed_operation = NULL; -#else -#error "Invalid ASPA_UPDATE_MECHANISM value." -#endif /* ASPA_UPDATE_MECHANISM */ - // An update attempted above failed if (!proceed) { if (undo_failed) diff --git a/tests/test_aspa.c b/tests/test_aspa.c index d134dda1..67730c77 100644 --- a/tests/test_aspa.c +++ b/tests/test_aspa.c @@ -848,14 +848,10 @@ static void test_withdraw_twice(struct rtr_socket *socket) end_cache_response(RTR_PROTOCOL_VERSION_2, 0, 444); EXPECT_ERROR_PDUS_SENT(ERROR_PDU(WITHDRAWAL_OF_UNKNOWN_RECORD)); + EXPECT_NO_UPDATE_CALLBACKS(); - // Callback behavior deviates for different update mechanisms - // Swap-In: No callback because update computation fails - // In-Place: Callbacks until failed operation, then callbacks from undo - assert_callbacks = false; assert(rtr_sync(socket) == RTR_ERROR); assert(expected_error_pdus_index == expected_error_pdus_count); - assert_callbacks = true; ASSERT_TABLE(socket, RECORD(1900, ASNS(1901, 1902, 1903, 1904)), @@ -895,14 +891,10 @@ static void test_announce_withdraw_announce_twice(struct rtr_socket *socket) end_cache_response(RTR_PROTOCOL_VERSION_2, 0, 444); EXPECT_ERROR_PDUS_SENT(ERROR_PDU(DUPLICATE_ANNOUNCEMENT)); + EXPECT_NO_UPDATE_CALLBACKS(); - // Callback behavior deviates for different update mechanisms - // Swap-In: No callback because update computation fails - // In-Place: Callbacks until failed operation, then callbacks from undo - assert_callbacks = false; assert(rtr_sync(socket) == RTR_ERROR); assert(expected_error_pdus_index == expected_error_pdus_count); - assert_callbacks = true; ASSERT_TABLE(socket, RECORD(1400, ASNS(1401, 1402, 1403, 1404)),