From: pcarana Date: Mon, 22 Jul 2019 23:07:49 +0000 (-0500) Subject: Fix some issues related to BGPsec. X-Git-Tag: v1.1.0~1^2~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c20ffb2add30d29eb12628b0e6c18b1af9a0f4c6;p=thirdparty%2FFORT-validator.git Fix some issues related to BGPsec. -Add functions to apply SLURM BGPsec filters and assertions. -Remove length variables of SKI and SPKI on SLURM BGPsec structs. -Send Router Key PDUs of base data (only PDUs from deltas were sent). -Update outdated unit tests (bad calls, missing calls, impersonate functions). -Complete filtering functions for BGPsec data. --- diff --git a/src/rtr/db/db_table.c b/src/rtr/db/db_table.c index f2cca92f..4d688222 100644 --- a/src/rtr/db/db_table.c +++ b/src/rtr/db/db_table.c @@ -220,22 +220,19 @@ db_table_remove_roa(struct db_table *table, struct vrp const *del) } } -/* - * FIXME and TODO: add more funcs for router keys - * void - * db_table_remove_router_key(struct db_table *table, - * struct router_key const *del) - * { - * struct hashable_key *ptr; - * - * HASH_FIND(hh, table->router_keys, del, sizeof(*del), ptr); - * if (ptr != NULL) { - * HASH_DELETE(hh, table->router_keys, ptr); - * router_key_cleanup(&ptr->data); - * free(ptr); - * } - * } - */ +void +db_table_remove_router_key(struct db_table *table, + struct router_key const *del) +{ + struct hashable_key *ptr; + + HASH_FIND(hh, table->router_keys, del, sizeof(*del), ptr); + if (ptr != NULL) { + HASH_DELETE(hh, table->router_keys, ptr); + router_key_cleanup(&ptr->data); + free(ptr); + } +} int rtrhandler_handle_roa_v4(struct db_table *table, uint32_t asn, diff --git a/src/rtr/db/db_table.h b/src/rtr/db/db_table.h index 0a475aa5..685393aa 100644 --- a/src/rtr/db/db_table.h +++ b/src/rtr/db/db_table.h @@ -14,8 +14,9 @@ int db_table_clone(struct db_table **, struct db_table *); int db_table_foreach_roa(struct db_table *, vrp_foreach_cb, void *); void db_table_remove_roa(struct db_table *, struct vrp const *); -int db_table_foreach_router_key(struct db_table *, router_key_foreach_cb cb, +int db_table_foreach_router_key(struct db_table *, router_key_foreach_cb, void *); +void db_table_remove_router_key(struct db_table *, struct router_key const *); int rtrhandler_handle_roa_v4(struct db_table *, uint32_t, struct ipv4_prefix const *, uint8_t); diff --git a/src/rtr/db/delta.c b/src/rtr/db/delta.c index 9461099f..2cb318b8 100644 --- a/src/rtr/db/delta.c +++ b/src/rtr/db/delta.c @@ -268,10 +268,6 @@ deltas_foreach(serial_t serial, struct deltas *deltas, if (error) return error; - /* FIXME Temporary, this must not be null */ - if (cb_bgpsec == NULL) - return 0; - error = __foreach_bgpsec(&deltas->bgpsec.adds, cb_bgpsec, arg, serial, FLAG_ANNOUNCEMENT); if (error) diff --git a/src/rtr/db/vrps.c b/src/rtr/db/vrps.c index 3161e459..14c62de2 100644 --- a/src/rtr/db/vrps.c +++ b/src/rtr/db/vrps.c @@ -28,8 +28,19 @@ struct vrp_node { SLIST_ENTRY(vrp_node) next; }; +struct bgpsec_node { + struct delta_bgpsec delta; + SLIST_ENTRY(bgpsec_node) next; +}; + /** Sorted list to filter deltas */ SLIST_HEAD(vrp_slist, vrp_node); +SLIST_HEAD(bgpsec_slist, bgpsec_node); + +struct sorted_lists { + struct vrp_slist prefixes; + struct bgpsec_slist bgpsec; +}; struct state { /** @@ -330,7 +341,7 @@ revert_base: * 2. -EAGAIN: No data available; database still under construction. */ int -vrps_foreach_base_roa(vrp_foreach_cb cb, void *arg) +vrps_foreach_base(vrp_foreach_cb cb_roa, router_key_foreach_cb cb_rk, void *arg) { int error; @@ -338,11 +349,15 @@ vrps_foreach_base_roa(vrp_foreach_cb cb, void *arg) if (error) return error; - if (state.base != NULL) - error = db_table_foreach_roa(state.base, cb, arg); - else + if (state.base != NULL) { + error = db_table_foreach_roa(state.base, cb_roa, arg); + if (error) + goto unlock; + error = db_table_foreach_router_key(state.base, cb_rk, arg); + } else error = -EAGAIN; +unlock: rwlock_unlock(&lock); return error; @@ -357,9 +372,11 @@ vrps_foreach_base_roa(vrp_foreach_cb cb, void *arg) static int vrp_ovrd_remove(struct delta_vrp const *delta, void *arg) { + struct sorted_lists *lists = arg; struct vrp_node *ptr; - struct vrp_slist *filtered_vrps = arg; + struct vrp_slist *filtered_vrps; + filtered_vrps = &lists->prefixes; SLIST_FOREACH(ptr, filtered_vrps, next) if (VRP_EQ(&delta->vrp, &ptr->delta.vrp) && delta->flags != ptr->delta.flags) { @@ -377,17 +394,51 @@ vrp_ovrd_remove(struct delta_vrp const *delta, void *arg) return 0; } +static int +bgpsec_ovrd_remove(struct delta_bgpsec const *delta, void *arg) +{ + struct sorted_lists *lists = arg; + struct bgpsec_node *ptr; + struct bgpsec_slist *filtered_bgpsec; + struct router_key const *key; + + filtered_bgpsec = &lists->bgpsec; + SLIST_FOREACH(ptr, filtered_bgpsec, next) { + key = &delta->router_key; + if (key->as == ptr->delta.router_key.as && + memcmp(sk_info_get_ski(key->sk), + sk_info_get_ski(ptr->delta.router_key.sk), RK_SKI_LEN) && + memcmp(sk_info_get_spk(key->sk), + sk_info_get_spk(ptr->delta.router_key.sk), RK_SPKI_LEN) && + delta->flags != ptr->delta.flags) { + SLIST_REMOVE(filtered_bgpsec, ptr, bgpsec_node, next); + free(ptr); + return 0; + } + } + + ptr = malloc(sizeof(struct bgpsec_node)); + if (ptr == NULL) + return pr_enomem(); + + ptr->delta = *delta; + SLIST_INSERT_HEAD(filtered_bgpsec, ptr, next); + return 0; +} + /* * Remove all operations on @deltas that override each other, and do @cb (with * @arg) on each element of the resultant delta. */ int -vrps_foreach_filtered_delta(struct deltas_db *deltas, delta_vrp_foreach_cb cb, +vrps_foreach_filtered_delta(struct deltas_db *deltas, + delta_vrp_foreach_cb cb_prefix, delta_bgpsec_foreach_cb cb_bgpsec, void *arg) { - struct vrp_slist filtered_vrps; + struct sorted_lists filtered_lists; struct delta_group *group; - struct vrp_node *ptr; + struct vrp_node *vnode; + struct bgpsec_node *bnode; array_index i; int error = 0; @@ -396,27 +447,37 @@ vrps_foreach_filtered_delta(struct deltas_db *deltas, delta_vrp_foreach_cb cb, * (We'll have to build a separate list because the database nodes * are immutable.) */ - SLIST_INIT(&filtered_vrps); + SLIST_INIT(&filtered_lists.prefixes); + SLIST_INIT(&filtered_lists.bgpsec); ARRAYLIST_FOREACH(deltas, group, i) { - /* FIXME Add cb function for router keys */ error = deltas_foreach(group->serial, group->deltas, - vrp_ovrd_remove, NULL, &filtered_vrps); + vrp_ovrd_remove, bgpsec_ovrd_remove, &filtered_lists); if (error) goto release_list; } - /* Now do the callback on the filtered deltas */ - SLIST_FOREACH(ptr, &filtered_vrps, next) { - error = cb(&ptr->delta, arg); + /* Now do the corresponding callback on the filtered deltas */ + SLIST_FOREACH(vnode, &filtered_lists.prefixes, next) { + error = cb_prefix(&vnode->delta, arg); + if (error) + break; + } + SLIST_FOREACH(bnode, &filtered_lists.bgpsec, next) { + error = cb_bgpsec(&bnode->delta, arg); if (error) break; } release_list: - while (!SLIST_EMPTY(&filtered_vrps)) { - ptr = filtered_vrps.slh_first; - SLIST_REMOVE_HEAD(&filtered_vrps, next); - free(ptr); + while (!SLIST_EMPTY(&filtered_lists.prefixes)) { + vnode = filtered_lists.prefixes.slh_first; + SLIST_REMOVE_HEAD(&filtered_lists.prefixes, next); + free(vnode); + } + while (!SLIST_EMPTY(&filtered_lists.bgpsec)) { + bnode = filtered_lists.bgpsec.slh_first; + SLIST_REMOVE_HEAD(&filtered_lists.bgpsec, next); + free(bnode); } return error; diff --git a/src/rtr/db/vrps.h b/src/rtr/db/vrps.h index 347a5fba..48a3abaa 100644 --- a/src/rtr/db/vrps.h +++ b/src/rtr/db/vrps.h @@ -29,14 +29,12 @@ int vrps_update(bool *); * Handle gracefully. */ -/* FIXME Also add BGPSEC */ -int vrps_foreach_base_roa(vrp_foreach_cb, void *); +int vrps_foreach_base(vrp_foreach_cb, router_key_foreach_cb, void *); int vrps_get_deltas_from(serial_t, serial_t *, struct deltas_db *); int get_last_serial_number(serial_t *); -/* FIXME Also filter BGPSEC */ int vrps_foreach_filtered_delta(struct deltas_db *, delta_vrp_foreach_cb, - void *); + delta_bgpsec_foreach_cb, void *); uint16_t get_current_session_id(uint8_t); diff --git a/src/rtr/pdu_handler.c b/src/rtr/pdu_handler.c index 5f10b2a3..5e3d4b6c 100644 --- a/src/rtr/pdu_handler.c +++ b/src/rtr/pdu_handler.c @@ -120,6 +120,25 @@ send_base_roa(struct vrp const *vrp, void *arg) return send_prefix_pdu(args->fd, args->version, vrp, FLAG_ANNOUNCEMENT); } + + +static int +send_base_router_key(struct router_key const *key, void *arg) +{ + struct base_roa_args *args = arg; + int error; + + if (!args->started) { + error = send_cache_response_pdu(args->fd, args->version); + if (error) + return error; + args->started = true; + } + + return send_router_key_pdu(args->fd, args->version, key, + FLAG_ANNOUNCEMENT); +} + int handle_reset_query_pdu(int fd, struct rtr_request const *request) { @@ -150,8 +169,7 @@ handle_reset_query_pdu(int fd, struct rtr_request const *request) * queries than reset queries. */ - /* FIXME Apply to router keys as well */ - error = vrps_foreach_base_roa(send_base_roa, &args); + error = vrps_foreach_base(send_base_roa, send_base_router_key, &args); /* See handle_serial_query_pdu() for some comments. */ switch (error) { diff --git a/src/rtr/pdu_sender.c b/src/rtr/pdu_sender.c index 9bda1c6e..977dfe8c 100644 --- a/src/rtr/pdu_sender.c +++ b/src/rtr/pdu_sender.c @@ -250,8 +250,8 @@ send_delta_pdus(int fd, uint8_t version, struct deltas_db *deltas) vrp_simply_send, router_key_simply_send, ¶m); } - /* FIXME Apply to router keys as well */ - return vrps_foreach_filtered_delta(deltas, vrp_simply_send, ¶m); + return vrps_foreach_filtered_delta(deltas, vrp_simply_send, + router_key_simply_send, ¶m); } #define GET_END_OF_DATA_LENGTH(version) \ diff --git a/src/slurm/slurm_db.c b/src/slurm/slurm_db.c index 7109705d..90bb2195 100644 --- a/src/slurm/slurm_db.c +++ b/src/slurm/slurm_db.c @@ -5,6 +5,7 @@ #include /* AF_INET, AF_INET6 (needed in OpenBSD) */ #include "data_structure/array_list.h" +#include "object/router_key.h" ARRAY_LIST(al_filter_prefix, struct slurm_prefix) ARRAY_LIST(al_assertion_prefix, struct slurm_prefix) @@ -89,9 +90,8 @@ bgpsec_filtered_by(struct slurm_bgpsec *bgpsec, struct slurm_bgpsec *filter) /* Both have a SKI */ if ((bgpsec->data_flag & SLURM_BGPS_FLAG_SKI) > 0 && - (filter->data_flag & SLURM_BGPS_FLAG_SKI) > 0 && - bgpsec->ski_len == filter->ski_len) - return memcmp(bgpsec->ski, filter->ski, bgpsec->ski_len) == 0; + (filter->data_flag & SLURM_BGPS_FLAG_SKI) > 0) + return memcmp(bgpsec->ski, filter->ski, RK_SKI_LEN) == 0; return false; } @@ -113,15 +113,13 @@ bgpsec_equal(struct slurm_bgpsec *left, struct slurm_bgpsec *right, equal = equal && left->asn == right->asn; if ((left->data_flag & SLURM_BGPS_FLAG_SKI) > 0) - equal = equal && left->ski_len == right->ski_len && - memcmp(left->ski, right->ski, left->ski_len) == 0; + equal = equal && + memcmp(left->ski, right->ski, RK_SKI_LEN) == 0; if ((left->data_flag & SLURM_BGPS_FLAG_ROUTER_KEY) > 0) equal = equal && - left->router_public_key_len == - right->router_public_key_len && memcmp(left->router_public_key, right->router_public_key, - left->router_public_key_len) == 0; + RK_SPKI_LEN) == 0; return equal; } @@ -191,6 +189,38 @@ slurm_db_foreach_assertion_prefix(assertion_pfx_foreach_cb cb, void *arg) return 0; } +bool +slurm_db_bgpsec_is_filtered(struct router_key const *key) +{ + struct slurm_bgpsec slurm_bgpsec; + + sk_info_refget(key->sk); + slurm_bgpsec.data_flag = SLURM_COM_FLAG_ASN | SLURM_BGPS_FLAG_SKI + | SLURM_BGPS_FLAG_ROUTER_KEY; + slurm_bgpsec.ski = sk_info_get_ski(key->sk); + slurm_bgpsec.router_public_key = sk_info_get_spk(key->sk); + slurm_bgpsec.comment = NULL; + sk_info_refput(key->sk); + + return bgpsec_filter_exists(&slurm_bgpsec); +} + +int +slurm_db_foreach_assertion_bgpsec(assertion_bgpsec_foreach_cb cb, void *arg) +{ + struct slurm_bgpsec *cursor; + array_index i; + int error; + + ARRAYLIST_FOREACH(&array_lists_db.assertion_bgps_al, cursor, i) { + error = cb(cursor, arg); + if (error) + return error; + } + + return 0; +} + static void clean_slurm_prefix(struct slurm_prefix *prefix) { diff --git a/src/slurm/slurm_db.h b/src/slurm/slurm_db.h index 52d19747..971f6f3e 100644 --- a/src/slurm/slurm_db.h +++ b/src/slurm/slurm_db.h @@ -22,6 +22,7 @@ struct slurm_db { }; typedef int (*assertion_pfx_foreach_cb)(struct slurm_prefix *, void *); +typedef int (*assertion_bgpsec_foreach_cb)(struct slurm_bgpsec *, void *); void slurm_db_init(void); @@ -30,9 +31,12 @@ int slurm_db_add_prefix_assertion(struct slurm_prefix *); int slurm_db_add_bgpsec_filter(struct slurm_bgpsec *); int slurm_db_add_bgpsec_assertion(struct slurm_bgpsec *); -bool slurm_db_vrp_is_filtered(struct vrp const *vrp); +bool slurm_db_vrp_is_filtered(struct vrp const *); int slurm_db_foreach_assertion_prefix(assertion_pfx_foreach_cb, void *); +bool slurm_db_bgpsec_is_filtered(struct router_key const *); +int slurm_db_foreach_assertion_bgpsec(assertion_bgpsec_foreach_cb, void *); + void slurm_db_cleanup(void); #endif /* SRC_SLURM_SLURM_DB_H_ */ diff --git a/src/slurm/slurm_loader.c b/src/slurm/slurm_loader.c index 482097a1..f904cae9 100644 --- a/src/slurm/slurm_loader.c +++ b/src/slurm/slurm_loader.c @@ -82,6 +82,33 @@ slurm_pfx_assertions_apply(struct db_table *base) base); } +static int +slurm_bgpsec_filters_apply(struct router_key const *key, void *arg) +{ + struct db_table *table = arg; + + if (slurm_db_bgpsec_is_filtered(key)) + db_table_remove_router_key(table, key); + + return 0; +} + +static int +slurm_bgpsec_assertions_add(struct slurm_bgpsec *bgpsec, void *arg) +{ + struct db_table *table = arg; + + return rtrhandler_handle_router_key(table, bgpsec->ski, + bgpsec->asn, bgpsec->router_public_key); +} + +static int +slurm_bgpsec_assertions_apply(struct db_table *base) +{ + return slurm_db_foreach_assertion_bgpsec(slurm_bgpsec_assertions_add, + base); +} + /* * Load the SLURM file/dir and try to apply it on @base. * @@ -112,14 +139,23 @@ slurm_apply(struct db_table **base) if (error) goto release_new; + error = db_table_foreach_router_key(new_base, + slurm_bgpsec_filters_apply, new_base); + if (error) + goto release_new; + error = slurm_pfx_assertions_apply(new_base); + if (error) { + goto release_new; + } + + error = slurm_bgpsec_assertions_apply(new_base); if (!error) { db_table_destroy(*base); *base = new_base; goto cleanup; } - /** TODO (next iteration) Apply BGPsec filters and assertions */ release_new: db_table_destroy(new_base); cleanup: diff --git a/src/slurm/slurm_parser.c b/src/slurm/slurm_parser.c index 74285ca3..ff21753a 100644 --- a/src/slurm/slurm_parser.c +++ b/src/slurm/slurm_parser.c @@ -11,6 +11,7 @@ #include "log.h" #include "address.h" #include "json_parser.h" +#include "object/router_key.h" #include "slurm/slurm_db.h" /* JSON members */ @@ -232,6 +233,7 @@ set_ski(json_t *object, bool is_assertion, struct slurm_bgpsec *result, size_t *members_loaded) { char const *str_encoded; + size_t ski_len; int error; error = json_get_string(object, SKI, &str_encoded); @@ -247,12 +249,12 @@ set_ski(json_t *object, bool is_assertion, struct slurm_bgpsec *result, if (error) return error; - error = base64url_decode(str_encoded, &result->ski, &result->ski_len); + error = base64url_decode(str_encoded, &result->ski, &ski_len); if (error) return error; /* Validate that's at least 20 octects long */ - if (result->ski_len != 20) { + if (ski_len != RK_SKI_LEN) { free(result->ski); return pr_err("The decoded SKI must be 20 octets long"); } @@ -267,6 +269,7 @@ set_router_pub_key(json_t *object, bool is_assertion, struct slurm_bgpsec *result, size_t *members_loaded) { char const *str_encoded; + size_t spk_len; int error; error = json_get_string(object, ROUTER_PUBLIC_KEY, &str_encoded); @@ -289,7 +292,7 @@ set_router_pub_key(json_t *object, bool is_assertion, return error; error = base64url_decode(str_encoded, &result->router_public_key, - &result->router_public_key_len); + &spk_len); if (error) return pr_err("'%s' couldn't be decoded", str_encoded); @@ -454,9 +457,7 @@ init_slurm_bgpsec(struct slurm_bgpsec *slurm_bgpsec) slurm_bgpsec->data_flag = SLURM_COM_FLAG_NONE; slurm_bgpsec->asn = 0; slurm_bgpsec->ski = NULL; - slurm_bgpsec->ski_len = 0; slurm_bgpsec->router_public_key = NULL; - slurm_bgpsec->router_public_key_len = 0; slurm_bgpsec->comment = NULL; } diff --git a/src/slurm/slurm_parser.h b/src/slurm/slurm_parser.h index 6be52e2c..3e5338a8 100644 --- a/src/slurm/slurm_parser.h +++ b/src/slurm/slurm_parser.h @@ -24,9 +24,7 @@ struct slurm_bgpsec { uint8_t data_flag; uint32_t asn; unsigned char *ski; - size_t ski_len; unsigned char *router_public_key; - size_t router_public_key_len; char *comment; }; diff --git a/test/rtr/db/vrps_test.c b/test/rtr/db/vrps_test.c index 8935cbb0..b21c820c 100644 --- a/test/rtr/db/vrps_test.c +++ b/test/rtr/db/vrps_test.c @@ -95,6 +95,13 @@ vrp_fail(struct vrp const *vrp, void *arg) return -EINVAL; } +static int +rk_fail(struct router_key const *key, void *arg) +{ + ck_abort_msg("Expected no callbacks, got from RK ASN %u.", key->as); + return -EINVAL; +} + static array_index get_vrp_index(struct vrp const *vrp) { @@ -150,6 +157,13 @@ vrp_check(struct vrp const *vrp, void *arg) return 0; } +static int +rk_check(struct router_key const *rk, void *arg) +{ + /* FIXME (now) add index with Router key examples */ + return 0; +} + static int delta_check(struct delta_vrp const *delta, void *arg) { @@ -163,6 +177,13 @@ delta_check(struct delta_vrp const *delta, void *arg) return 0; } +static int +delta_rk_check(struct delta_bgpsec const *delta, void *arg) +{ + /* FIXME (now) add index with Router key examples */ + return 0; +} + static void check_serial(serial_t expected_serial) { @@ -180,7 +201,8 @@ check_base(serial_t expected_serial, bool const *expected_base) memset(actual_base, 0, sizeof(actual_base)); ck_assert_int_eq(0, get_last_serial_number(&actual_serial)); - ck_assert_int_eq(0, vrps_foreach_base_roa(vrp_check, actual_base)); + ck_assert_int_eq(0, vrps_foreach_base(vrp_check, rk_check, + actual_base)); ck_assert_uint_eq(expected_serial, actual_serial); for (i = 0; i < ARRAY_LEN(actual_base); i++) ck_assert_uint_eq(expected_base[i], actual_base[i]); @@ -214,6 +236,17 @@ vrp_add(struct delta_vrp const *delta, void *arg) return 0; } +static int +rk_add(struct delta_bgpsec const *delta, void *arg) +{ + struct deltas *deltas = arg; + struct router_key key; + + key = delta->router_key; + deltas_add_bgpsec(deltas, &key, delta->flags); + return 0; +} + static void filter_deltas(struct deltas_db *db) { @@ -225,7 +258,7 @@ filter_deltas(struct deltas_db *db) ck_assert_int_eq(0, deltas_create(&deltas)); group.deltas = deltas; ck_assert_int_eq(0, vrps_foreach_filtered_delta(db, vrp_add, - group.deltas)); + rk_add, group.deltas)); deltas_db_init(&tmp); ck_assert_int_eq(0, deltas_db_add(&tmp, &group)); @@ -251,10 +284,9 @@ check_deltas(serial_t from, serial_t to, bool const *expected_deltas, filter_deltas(&deltas); memset(actual_deltas, 0, sizeof(actual_deltas)); - /* FIXME Add cb function for router keys */ ARRAYLIST_FOREACH(&deltas, group, i) ck_assert_int_eq(0, deltas_foreach(group->serial, group->deltas, - delta_check, NULL, actual_deltas)); + delta_check, delta_rk_check, actual_deltas)); for (i = 0; i < ARRAY_LEN(actual_deltas); i++) ck_assert_uint_eq(expected_deltas[i], actual_deltas[i]); } @@ -282,7 +314,7 @@ create_deltas_0to1(struct deltas_db *deltas, serial_t *serial, bool *changed, /* First validation not yet performed: Tell routers to wait */ ck_assert_int_eq(-EAGAIN, get_last_serial_number(serial)); - ck_assert_int_eq(-EAGAIN, vrps_foreach_base_roa(vrp_fail, + ck_assert_int_eq(-EAGAIN, vrps_foreach_base(vrp_fail, rk_fail, iterated_entries)); ck_assert_int_eq(-EAGAIN, vrps_get_deltas_from(0, serial, deltas)); diff --git a/test/rtr/pdu_handler_test.c b/test/rtr/pdu_handler_test.c index 64adca77..7e67c816 100644 --- a/test/rtr/pdu_handler_test.c +++ b/test/rtr/pdu_handler_test.c @@ -114,7 +114,21 @@ clients_get_min_serial(serial_t *result) } int -send_cache_reset_pdu(int fd) +clients_set_rtr_version(int fd, uint8_t rtr_version) +{ + return 0; +} + +int +clients_get_rtr_version_set(int fd, bool *is_set, uint8_t *rtr_version) +{ + (*is_set) = true; + (*rtr_version) = RTR_V0; + return 0; +} + +int +send_cache_reset_pdu(int fd, uint8_t version) { pr_info(" Server sent Cache Reset."); ck_assert_int_eq(pop_expected_pdu(), PDU_TYPE_CACHE_RESET); @@ -122,7 +136,7 @@ send_cache_reset_pdu(int fd) } int -send_cache_response_pdu(int fd) +send_cache_response_pdu(int fd, uint8_t version) { pr_info(" Server sent Cache Response."); ck_assert_int_eq(pop_expected_pdu(), PDU_TYPE_CACHE_RESPONSE); @@ -130,7 +144,7 @@ send_cache_response_pdu(int fd) } int -send_prefix_pdu(int fd, struct vrp const *vrp, uint8_t flags) +send_prefix_pdu(int fd, uint8_t version, struct vrp const *vrp, uint8_t flags) { /* * We don't care about order. @@ -145,30 +159,55 @@ send_prefix_pdu(int fd, struct vrp const *vrp, uint8_t flags) return 0; } +int +send_router_key_pdu(int fd, uint8_t version, + struct router_key const *router_key, uint8_t flags) +{ + /* + * We don't care about order. + * If the server is expected to return `M` IPv4 PDUs and `N` IPv6 PDUs, + * we'll just check `M + N` contiguous Prefix PDUs. + */ + uint8_t pdu_type = pop_expected_pdu(); + pr_info(" Server sent Router Key PDU."); + ck_assert_msg(pdu_type == PDU_TYPE_ROUTER_KEY, + "Server's PDU type is %d, not Router Key type.", pdu_type); + return 0; +} + static int handle_delta(struct delta_vrp const *delta, void *arg) { int *fd = arg; - ck_assert_int_eq(0, send_prefix_pdu(*fd, &delta->vrp, delta->flags)); + ck_assert_int_eq(0, send_prefix_pdu(*fd, RTR_V0, &delta->vrp, + delta->flags)); + return 0; +} + +static int +handle_delta_bgpsec(struct delta_bgpsec const *delta, void *arg) +{ + int *fd = arg; + ck_assert_int_eq(0, send_router_key_pdu(*fd, RTR_V0, &delta->router_key, + delta->flags)); return 0; } int -send_delta_pdus(int fd, struct deltas_db *deltas) +send_delta_pdus(int fd, uint8_t version, struct deltas_db *deltas) { struct delta_group *group; array_index i; - /* FIXME Add cb function for router keys */ ARRAYLIST_FOREACH(deltas, group, i) ck_assert_int_eq(0, deltas_foreach(group->serial, group->deltas, - handle_delta, NULL, &fd)); + handle_delta, handle_delta_bgpsec, &fd)); return 0; } int -send_end_of_data_pdu(int fd, serial_t end_serial) +send_end_of_data_pdu(int fd, uint8_t version, serial_t end_serial) { pr_info(" Server sent End of Data."); ck_assert_int_eq(pop_expected_pdu(), PDU_TYPE_END_OF_DATA); @@ -176,8 +215,8 @@ send_end_of_data_pdu(int fd, serial_t end_serial) } int -send_error_report_pdu(int fd, uint16_t code, struct rtr_request const *request, - char *message) +send_error_report_pdu(int fd, uint8_t version, uint16_t code, + struct rtr_request const *request, char *message) { pr_info(" Server sent Error Report %u: '%s'", code, message); ck_assert_int_eq(pop_expected_pdu(), PDU_TYPE_ERROR_REPORT); diff --git a/test/rtr/pdu_test.c b/test/rtr/pdu_test.c index 849fcfbc..3c8883e1 100644 --- a/test/rtr/pdu_test.c +++ b/test/rtr/pdu_test.c @@ -44,6 +44,20 @@ get_current_session_id(uint8_t rtr_version) return 12345; } +int +clients_set_rtr_version(int fd, uint8_t rtr_version) +{ + return 0; +} + +int +clients_get_rtr_version_set(int fd, bool *is_set, uint8_t *rtr_version) +{ + (*is_set) = true; + (*rtr_version) = RTR_V0; + return 0; +} + IMPERSONATE_HANDLER(serial_notify) IMPERSONATE_HANDLER(serial_query) IMPERSONATE_HANDLER(reset_query) @@ -56,8 +70,8 @@ IMPERSONATE_HANDLER(router_key) IMPERSONATE_HANDLER(error_report) int -send_error_report_pdu(int fd, uint16_t code, struct rtr_request const *request, - char *message) +send_error_report_pdu(int fd, uint8_t version, uint16_t code, + struct rtr_request const *request, char *message) { pr_info(" Server sent Error Report %u: '%s'", code, message); return 0;