From: pcarana Date: Fri, 19 Jul 2019 17:04:26 +0000 (-0500) Subject: Store BGPsec certs info, print at configured output X-Git-Tag: v1.1.0~1^2~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9c2d087305da685af1ae67004bdcc6effd0d1c48;p=thirdparty%2FFORT-validator.git Store BGPsec certs info, print at configured output -Use struct 'router_key' to represent BGPsec certificates. -Use reference count of Subject Key data (ID and public key) with 'sk_info' struct. -Add router certificates info to local DB, as part of the refactor 'roa_table' was renamed to 'db_table'. -Add configuration parameter 'output.bgpsec', the information is printed in hexadecimal representation (there's a TODO here: maybe encode and print as base64). -Consider BGPsec keys in deltas. -Use a constant for SKI length, since always is the same (20 bytes/octets). --- diff --git a/src/Makefile.am b/src/Makefile.am index 7aea1e14..78b75eac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,7 +68,7 @@ fort_SOURCES += object/ghostbusters.h object/ghostbusters.c fort_SOURCES += object/manifest.h object/manifest.c fort_SOURCES += object/name.h object/name.c fort_SOURCES += object/roa.h object/roa.c -fort_SOURCES += object/router_key.h +fort_SOURCES += object/router_key.c object/router_key.h fort_SOURCES += object/signed_object.h object/signed_object.c fort_SOURCES += object/tal.h object/tal.c fort_SOURCES += object/vcard.h object/vcard.c @@ -88,8 +88,8 @@ fort_SOURCES += rtr/primitive_reader.c rtr/primitive_reader.h fort_SOURCES += rtr/primitive_writer.c rtr/primitive_writer.h fort_SOURCES += rtr/rtr.c rtr/rtr.h +fort_SOURCES += rtr/db/db_table.c rtr/db/db_table.h fort_SOURCES += rtr/db/delta.c rtr/db/delta.h -fort_SOURCES += rtr/db/roa_table.c rtr/db/roa_table.h fort_SOURCES += rtr/db/roa.c rtr/db/roa.h fort_SOURCES += rtr/db/vrp.h fort_SOURCES += rtr/db/vrps.c rtr/db/vrps.h diff --git a/src/config.c b/src/config.c index a7737683..971b7103 100644 --- a/src/config.c +++ b/src/config.c @@ -85,7 +85,8 @@ struct rpki_config { struct { /** File where the validated ROAs will be stored */ char *roa; - /** TODO (next iteration) Add BGPsec output */ + /** File where the validated BGPsec certs will be stored */ + char *bgpsec; } output; }; @@ -346,6 +347,14 @@ static const struct option_field options[] = { .doc = "File where ROAs will be stored in CSV format, use '-' to print at console", .arg_doc = "", }, + { + .id = 6001, + .name = "output.bgpsec", + .type = >_string, + .offset = offsetof(struct rpki_config, output.bgpsec), + .doc = "File where BGPsec certificates will be stored in CSV format, use '-' to print at console", + .arg_doc = "", + }, { 0 }, }; @@ -548,6 +557,7 @@ set_default_values(void) rpki_config.log.filename_format = FNF_GLOBAL; rpki_config.output.roa = NULL; + rpki_config.output.bgpsec = NULL; return 0; @@ -815,6 +825,12 @@ config_get_output_roa(void) return rpki_config.output.roa; } +char const * +config_get_output_bgpsec(void) +{ + return rpki_config.output.bgpsec; +} + void free_rpki_config(void) { diff --git a/src/config.h b/src/config.h index ad6a9c34..c3d86062 100644 --- a/src/config.h +++ b/src/config.h @@ -35,6 +35,7 @@ enum filename_format config_get_filename_format(void); char *config_get_rsync_program(void); struct string_array const *config_get_rsync_args(bool); char const *config_get_output_roa(void); +char const *config_get_output_bgpsec(void); /* Needed public by the JSON module */ void *get_rpki_config_field(struct option_field const *); diff --git a/src/object/bgpsec.c b/src/object/bgpsec.c index e5bc894c..d2ef8ad1 100644 --- a/src/object/bgpsec.c +++ b/src/object/bgpsec.c @@ -4,36 +4,29 @@ #include "validation_handler.h" struct resource_params { - struct router_key *router_key; - struct resources *resources; + unsigned char const *ski; + unsigned char const *spk; + size_t spk_len; + struct resources *resources; }; static int asn_cb(unsigned long asn, void *arg) { struct resource_params *params = arg; - struct router_key router_key; if (!resources_contains_asn(params->resources, asn)) return pr_err("BGPsec certificate is not allowed for ASN %lu.", asn); - memcpy(&router_key, params->router_key, sizeof(*params->router_key)); - router_key.asn = asn; - - return vhandler_handle_bgpsec(&router_key); + return vhandler_handle_bgpsec(params->ski, asn, params->spk, + params->spk_len); } int -handle_bgpsec(X509 *cert, unsigned char *ski, int ski_len, - struct resources *resources) +handle_bgpsec(X509 *cert, unsigned char const *ski, struct resources *resources) { - /* - * FIXME: Store the public key, SKI, and the resources - */ struct resource_params res_params; - struct router_key router_key; - ASN1_OBJECT *cert_alg; X509_PUBKEY *pub_key; unsigned char const *cert_spk; int cert_spk_len; @@ -43,22 +36,17 @@ handle_bgpsec(X509 *cert, unsigned char *ski, int ski_len, if (pub_key == NULL) return crypto_err("X509_get_X509_PUBKEY() returned NULL at BGPsec"); - ok = X509_PUBKEY_get0_param(&cert_alg, &cert_spk, &cert_spk_len, NULL, + ok = X509_PUBKEY_get0_param(NULL, &cert_spk, &cert_spk_len, NULL, pub_key); if (!ok) return crypto_err("X509_PUBKEY_get0_param() returned %d at BGPsec", ok); - router_key.spk = cert_spk; - router_key.spk_len = cert_spk_len; - router_key.ski = ski; - router_key.ski_len = ski_len; - - res_params.router_key = &router_key; + res_params.spk = cert_spk; + res_params.spk_len = cert_spk_len; + res_params.ski = ski; res_params.resources = resources; ok = resources_foreach_asn(resources, asn_cb, &res_params); - /* FIXME Maybe this should be released elsewhere.. */ - free(ski); return ok; } diff --git a/src/object/bgpsec.h b/src/object/bgpsec.h index c34eba40..e1df2126 100644 --- a/src/object/bgpsec.h +++ b/src/object/bgpsec.h @@ -4,6 +4,6 @@ #include #include "resource.h" -int handle_bgpsec(X509 *, unsigned char *, int, struct resources *); +int handle_bgpsec(X509 *, unsigned char const *, struct resources *); #endif /* SRC_OBJECT_BGPSEC_H_ */ diff --git a/src/object/certificate.c b/src/object/certificate.c index dc27a79f..735698ab 100644 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@ -42,7 +42,6 @@ struct sia_uris { struct bgpsec_ski { X509 *cert; - int *ski_len; unsigned char **ski_data; }; @@ -953,9 +952,9 @@ handle_ski_bgpsec(X509_EXTENSION *ext, void *arg) if (tmp == NULL) goto end; - (*params->ski_len) = ski->length; memcpy(tmp, ski->data, ski->length); - *params->ski_data = tmp; + tmp[ski->length] = '\0'; + *(params->ski_data) = tmp; end: ASN1_OCTET_STRING_free(ski); @@ -1457,7 +1456,7 @@ certificate_validate_extensions_ca(X509 *cert, struct rpki_uri **mft, static int certificate_validate_extensions_bgpsec(X509 *cert, unsigned char **ski, - int *ski_len, struct certificate_refs *refs, enum rpki_policy *policy) + struct certificate_refs *refs, enum rpki_policy *policy) { struct bgpsec_ski ski_param; struct extension_handler handlers[] = { @@ -1476,7 +1475,6 @@ certificate_validate_extensions_bgpsec(X509 *cert, unsigned char **ski, ski_param.cert = cert; ski_param.ski_data = ski; - ski_param.ski_len = ski_len; return handle_extensions(handlers, X509_get0_extensions(cert)); } @@ -1539,7 +1537,6 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri) enum cert_type type; struct rpp *pp; bool mft_retry; - int ski_len; int error; state = state_retrieve(); @@ -1598,7 +1595,7 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri) break; case BGPSEC: error = certificate_validate_extensions_bgpsec(cert, &ski, - &ski_len, &refs, &policy); + &refs, &policy); break; default: /* Validate as a CA */ @@ -1621,9 +1618,10 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri) if (type == BGPSEC) { /* This is an EE, so there's no manifest to process */ - error = handle_bgpsec(cert, ski, ski_len, + error = handle_bgpsec(cert, ski, x509stack_peek_resources(validation_certstack(state))); cert = NULL; /* Ownership stolen at x509stack_push */ + free(ski); /* No need to remember it */ x509stack_cancel(validation_certstack(state)); goto revert_refs; diff --git a/src/object/router_key.c b/src/object/router_key.c new file mode 100644 index 00000000..81ca8102 --- /dev/null +++ b/src/object/router_key.c @@ -0,0 +1,103 @@ +#include "object/router_key.h" + +#include +#include "log.h" + +struct sk_info { + unsigned char *ski; + /* SKI length its constant (see RK_SKI_LEN) */ + unsigned char *spk; + size_t spk_len; + unsigned int references; +}; + +static int +uchar_create(unsigned char **result, size_t size) +{ + unsigned char *tmp; + + tmp = malloc(size + 1); + if (tmp == NULL) + return pr_enomem(); + + *result = tmp; + return 0; +} + +int +router_key_init(struct router_key *key, unsigned char const *ski, + uint32_t as, unsigned char const *spk, size_t spk_len) +{ + struct sk_info *sk; + int error; + + sk = malloc(sizeof(struct sk_info)); + if (sk == NULL) + return pr_enomem(); + + error = uchar_create(&sk->ski, RK_SKI_LEN); + if (error) { + free(sk); + return pr_enomem(); + } + + error = uchar_create(&sk->spk, spk_len); + if (error) { + free(sk->ski); + free(sk); + return pr_enomem(); + } + + memcpy(sk->ski, ski, RK_SKI_LEN); + sk->ski[RK_SKI_LEN] = '\0'; + memcpy(sk->spk, spk, spk_len); + sk->spk[spk_len] = '\0'; + sk->spk_len = spk_len; + sk->references = 1; + + key->as = as; + key->sk = sk; + + return 0; +} + +void +router_key_cleanup(struct router_key *key) +{ + sk_info_refput(key->sk); +} + +void +sk_info_refget(struct sk_info *sk) +{ + sk->references++; +} + +void +sk_info_refput(struct sk_info *sk) +{ + sk->references--; + if (sk->references == 0) { + free(sk->ski); + free(sk->spk); + free(sk); + } +} + +unsigned char * +sk_info_get_ski(struct sk_info *sk) +{ + return sk->ski; +} + +unsigned char * +sk_info_get_spk(struct sk_info *sk) +{ + return sk->spk; +} + +size_t +sk_info_get_spk_len(struct sk_info *sk) +{ + return sk->spk_len; +} diff --git a/src/object/router_key.h b/src/object/router_key.h index 622be74f..a6b612da 100644 --- a/src/object/router_key.h +++ b/src/object/router_key.h @@ -1,15 +1,37 @@ #ifndef SRC_OBJECT_ROUTER_KEY_H_ #define SRC_OBJECT_ROUTER_KEY_H_ +#include +#include + +/* + * SKI is always 20 bytes long rfc6487#section-4.8.2: + * "The Key Identifier used for resource certificates is the 160-bit {...}" + */ +#define RK_SKI_LEN 20 + +/* + * Subject key info with ref counter, use getters to fetch its data + */ +struct sk_info; + /* - * Roouter Key representation + * Router Key representation */ struct router_key { - unsigned char *ski; - size_t ski_len; - uint32_t asn; - unsigned char *spk; - size_t spk_len; + uint32_t as; + struct sk_info *sk; }; +int router_key_init(struct router_key *, unsigned char const *, uint32_t, + unsigned char const *, size_t); +void router_key_cleanup(struct router_key *); + +void sk_info_refget(struct sk_info *); +void sk_info_refput(struct sk_info *); + +unsigned char *sk_info_get_ski(struct sk_info *); +unsigned char *sk_info_get_spk(struct sk_info *); +size_t sk_info_get_spk_len(struct sk_info *); + #endif /* SRC_OBJECT_ROUTER_KEY_H_ */ diff --git a/src/output_printer.c b/src/output_printer.c index 464ec920..dd327297 100644 --- a/src/output_printer.c +++ b/src/output_printer.c @@ -23,11 +23,10 @@ strv6addr(struct in6_addr const *addr) } static int -load_output_file(FILE **result, bool *fopen) +load_output_file(char const *output, FILE **result, bool *fopen) { FILE *tmp; struct stat stat; - char const *output = config_get_output_roa(); int error; if (output == NULL) { @@ -42,8 +41,10 @@ load_output_file(FILE **result, bool *fopen) } error = file_write(output, &tmp, &stat); - if (error) + if (error) { + *result = NULL; return error; + } *fopen = true; *result = tmp; @@ -73,29 +74,113 @@ print_roa(struct vrp const *vrp, void *arg) return 0; } -void -output_print_roas(struct roa_table *roas) +static int +print_to_hex(unsigned char *data, size_t len, char **out) { - FILE *out; - bool fopen; + char *tmp; + char *init; + int i; + + tmp = malloc(len * 3 + 1); + if (tmp == NULL) + return pr_enomem(); + + init = tmp; + for (i = 0; i < len * 3; i+=3) { + *tmp = ':'; + tmp++; + tmp += sprintf(tmp, "%02X", data[i/3]); + } + *tmp = '\0'; + + *out = init; + return 0; +} + +/* + * FIXME Improve this calls, maybe base64 encode and print? + */ +static int +print_router_key(struct router_key const *key, void *arg) +{ + FILE *out = arg; + char *buf1; + char *buf2; int error; - error = load_output_file(&out, &fopen); - if (error) { - pr_err("Error getting file '%s'", config_get_output_roa()); - return; - } + error = print_to_hex(sk_info_get_ski(key->sk), RK_SKI_LEN, &buf1); + if (error) + return error; + error = print_to_hex(sk_info_get_spk(key->sk), + sk_info_get_spk_len(key->sk), &buf2); + if (error) + return error; + fprintf(out, "AS%u,%s,%s\n", key->as, buf1, buf2); + free(buf1); + free(buf2); + + return 0; +} + +static int +open_file(char const *loc, FILE **out, bool *fopen) +{ + int error; + + error = load_output_file(loc, out, fopen); + if (error) + return pr_err("Error getting file '%s'", loc); /* No output configured */ - if (out == NULL) + if (*out == NULL) + return -ENOENT; + + return 0; +} + +static void +print_roas(struct db_table *db) +{ + FILE *out; + bool fopen; + int error; + + out = NULL; + error = open_file(config_get_output_roa(), &out, &fopen); + if (error) return; fprintf(out, "ASN,Prefix,Max prefix length\n"); - error = roa_table_foreach_roa(roas, print_roa, out); + error = db_table_foreach_roa(db, print_roa, out); if (fopen) file_close(out); - if (error) { + if (error) pr_err("Error printing ROAs"); +} + +static void +print_router_keys(struct db_table *db) +{ + FILE *out; + bool fopen; + int error; + + out = NULL; + error = open_file(config_get_output_bgpsec(), &out, &fopen); + if (error) return; - } + + fprintf(out, "ASN,SKI,SPK\n"); + error = db_table_foreach_router_key(db, print_router_key, out); + if (fopen) + file_close(out); + if (error) + pr_err("Error printing Router Keys"); +} + +void +output_print_data(struct db_table *db) +{ + print_roas(db); + print_router_keys(db); } diff --git a/src/output_printer.h b/src/output_printer.h index 47fcdb2d..4bb089e2 100644 --- a/src/output_printer.h +++ b/src/output_printer.h @@ -1,8 +1,8 @@ #ifndef SRC_OUTPUT_PRINTER_H_ #define SRC_OUTPUT_PRINTER_H_ -#include "rtr/db/roa_table.h" +#include "rtr/db/db_table.h" -void output_print_roas(struct roa_table *); +void output_print_data(struct db_table *); #endif /* SRC_OUTPUT_PRINTER_H_ */ diff --git a/src/rtr/db/db_table.c b/src/rtr/db/db_table.c new file mode 100644 index 00000000..7c8438f4 --- /dev/null +++ b/src/rtr/db/db_table.c @@ -0,0 +1,420 @@ +#include "rtr/db/db_table.h" + +#include /* AF_INET, AF_INET6 (needed in OpenBSD) */ +#include /* AF_INET, AF_INET6 (needed in OpenBSD) */ +#include "data_structure/uthash_nonfatal.h" + +struct hashable_roa { + struct vrp data; + UT_hash_handle hh; +}; + +struct hashable_key { + struct router_key data; + UT_hash_handle hh; +}; + +struct db_table { + struct hashable_roa *roas; + struct hashable_key *router_keys; +}; + +struct db_table * +db_table_create(void) +{ + struct db_table *table; + + table = malloc(sizeof(struct db_table)); + if (table == NULL) + return NULL; + + table->roas = NULL; + table->router_keys = NULL; + return table; +} + +void +db_table_destroy(struct db_table *table) +{ + struct hashable_roa *node; + struct hashable_roa *tmp; + struct hashable_key *node_key; + struct hashable_key *tmp_key; + + HASH_ITER(hh, table->roas, node, tmp) { + HASH_DEL(table->roas, node); + free(node); + } + + HASH_ITER(hh, table->router_keys, node_key, tmp_key) { + HASH_DEL(table->router_keys, node_key); + router_key_cleanup(&node_key->data); + free(node_key); + } + + free(table); +} + +int +db_table_foreach_roa(struct db_table *table, vrp_foreach_cb cb, void *arg) +{ + struct hashable_roa *node, *tmp; + int error; + + HASH_ITER(hh, table->roas, node, tmp) { + error = cb(&node->data, arg); + if (error) + return error; + } + + return 0; +} + +int +db_table_foreach_router_key(struct db_table *table, router_key_foreach_cb cb, + void *arg) +{ + struct hashable_key *node, *tmp; + int error; + + HASH_ITER(hh, table->router_keys, node, tmp) { + error = cb(&node->data, arg); + if (error) + return error; + } + + return 0; +} + +static struct hashable_roa * +create_roa(uint32_t asn, uint8_t max_length) +{ + struct hashable_roa *roa; + + roa = malloc(sizeof(struct hashable_roa)); + if (roa == NULL) + return NULL; + /* Needed by uthash */ + memset(roa, 0, sizeof(struct hashable_roa)); + + roa->data.asn = asn; + roa->data.max_prefix_length = max_length; + + return roa; +} + +static int +add_roa(struct db_table *table, struct hashable_roa *new) +{ + struct hashable_roa *old; + + errno = 0; + HASH_REPLACE(hh, table->roas, data, sizeof(new->data), new, old); + if (errno) + return -pr_errno(errno, "ROA couldn't be added to hash table"); + if (old != NULL) + free(old); + + return 0; +} + +static int +add_router_key(struct db_table *table, struct hashable_key *new) +{ + struct hashable_key *old; + + errno = 0; + HASH_REPLACE(hh, table->router_keys, data, sizeof(new->data), new, old); + if (errno) + return -pr_errno(errno, "Router Key couldn't be added to hash table"); + if (old != NULL) { + router_key_cleanup(&old->data); + free(old); + } + + return 0; +} + +static int +duplicate_roa(struct db_table *dst, struct hashable_roa *new) +{ + struct vrp vrp; + struct ipv4_prefix prefix4; + struct ipv6_prefix prefix6; + + vrp = new->data; + switch (vrp.addr_fam) { + case AF_INET: + prefix4.addr = vrp.prefix.v4; + prefix4.len = vrp.prefix_length; + return rtrhandler_handle_roa_v4(dst, vrp.asn, &prefix4, + vrp.max_prefix_length); + case AF_INET6: + prefix6.addr = vrp.prefix.v6; + prefix6.len = vrp.prefix_length; + return rtrhandler_handle_roa_v6(dst, vrp.asn, &prefix6, + vrp.max_prefix_length); + } + + pr_crit("Unknown address family: %d", vrp.addr_fam); +} + +static int +duplicate_key(struct db_table *dst, struct hashable_key *new) +{ + struct sk_info *sk = new->data.sk; + + return rtrhandler_handle_router_key(dst, sk_info_get_ski(sk), + new->data.as, sk_info_get_spk(sk), sk_info_get_spk_len(sk)); +} + +#define MERGE_ITER(table_prop, name, err_var) \ + struct hashable_##name *node_##name, *tmp_##name, *found_##name;\ + HASH_ITER(hh, src->table_prop, node_##name, tmp_##name) { \ + HASH_FIND(hh, dst->table_prop, &node_##name->data, \ + sizeof(node_##name->data), found_##name); \ + if (found_##name != NULL) \ + continue; \ + err_var = duplicate_##name(dst, node_##name); \ + if (err_var) \ + return err_var; \ + } + +static int +db_table_merge(struct db_table *dst, struct db_table *src) +{ + int error; + + /** Must look for elements due to the new mem allocation */ + MERGE_ITER(roas, roa, error) + MERGE_ITER(router_keys, key, error) + + return 0; +} + +int +db_table_clone(struct db_table **dst, struct db_table *src) +{ + int error; + + *dst = db_table_create(); + if (*dst == NULL) + return pr_enomem(); + + error = db_table_merge(*dst, src); + if (error) + free(*dst); + + return error; +} + +void +db_table_remove_roa(struct db_table *table, struct vrp const *del) +{ + struct hashable_roa *ptr; + + HASH_FIND(hh, table->roas, del, sizeof(*del), ptr); + if (ptr != NULL) { + HASH_DELETE(hh, table->roas, ptr); + free(ptr); + } +} + +/* + * 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); + * } + * } + */ + +int +rtrhandler_handle_roa_v4(struct db_table *table, uint32_t asn, + struct ipv4_prefix const *prefix4, uint8_t max_length) +{ + struct hashable_roa *roa; + int error; + + roa = create_roa(asn, max_length); + if (roa == NULL) + return pr_enomem(); + roa->data.prefix.v4 = prefix4->addr; + roa->data.prefix_length = prefix4->len; + roa->data.addr_fam = AF_INET; + + error = add_roa(table, roa); + if (error) + free(roa); + return error; +} + +int +rtrhandler_handle_roa_v6(struct db_table *table, uint32_t asn, + struct ipv6_prefix const *prefix6, uint8_t max_length) +{ + struct hashable_roa *roa; + int error; + + roa = create_roa(asn, max_length); + if (roa == NULL) + return pr_enomem(); + roa->data.prefix.v6 = prefix6->addr; + roa->data.prefix_length = prefix6->len; + roa->data.addr_fam = AF_INET6; + + error = add_roa(table, roa); + if (error) + free(roa); + return error; +} + +int +rtrhandler_handle_router_key(struct db_table *table, + unsigned char const *ski, uint32_t as, unsigned char const *spk, + size_t spk_len) +{ + struct hashable_key *key; + int error; + + key = malloc(sizeof(struct hashable_key)); + if (key == NULL) + return pr_enomem(); + /* Needed by uthash */ + memset(key, 0, sizeof(struct hashable_key)); + + error = router_key_init(&key->data, ski, as, spk, spk_len); + if (error) { + free(key); + return error; + } + + error = add_router_key(table, key); + if (error) { + router_key_cleanup(&key->data); + free(key); + } + return error; +} + +static int +add_roa_delta(struct deltas *deltas, struct hashable_roa *roa, int op) +{ + union { + struct v4_address v4; + struct v6_address v6; + } addr; + + switch (roa->data.addr_fam) { + case AF_INET: + addr.v4.prefix.addr = roa->data.prefix.v4; + addr.v4.prefix.len = roa->data.prefix_length; + addr.v4.max_length = roa->data.max_prefix_length; + return deltas_add_roa_v4(deltas, roa->data.asn, &addr.v4, op); + case AF_INET6: + addr.v6.prefix.addr = roa->data.prefix.v6; + addr.v6.prefix.len = roa->data.prefix_length; + addr.v6.max_length = roa->data.max_prefix_length; + return deltas_add_roa_v6(deltas, roa->data.asn, &addr.v6, op); + } + + pr_crit("Unknown address family: %d", roa->data.addr_fam); +} + +/* + * Copies `@roas1 - roas2` into @deltas. + * + * (Places the ROAs that exist in @roas1 but not in @roas2 in @deltas.) + */ +static int +add_roa_deltas(struct hashable_roa *roas1, struct hashable_roa *roas2, + struct deltas *deltas, int op) +{ + struct hashable_roa *n1; /* A node from @roas1 */ + struct hashable_roa *n2; /* A node from @roas2 */ + int error; + + for (n1 = roas1; n1 != NULL; n1 = n1->hh.next) { + HASH_FIND(hh, roas2, &n1->data, sizeof(n1->data), n2); + if (n2 == NULL) { + error = add_roa_delta(deltas, n1, op); + if (error) + return error; + } + } + + return 0; +} + +static int +add_router_key_delta(struct deltas *deltas, struct hashable_key *key, int op) +{ + return deltas_add_bgpsec(deltas, &key->data, op); +} + +/* + * Copies `@keys1 - keys2` into @deltas. + * + * (Places the Router Keys that exist in @keys1 but not in @key2 in @deltas.) + */ +static int +add_router_key_deltas(struct hashable_key *keys1, struct hashable_key *keys2, + struct deltas *deltas, int op) +{ + struct hashable_key *n1; /* A node from @keys1 */ + struct hashable_key *n2; /* A node from @keys2 */ + int error; + + for (n1 = keys1; n1 != NULL; n1 = n1->hh.next) { + HASH_FIND(hh, keys2, &n1->data, sizeof(n1->data), n2); + if (n2 == NULL) { + error = add_router_key_delta(deltas, n1, op); + if (error) + return error; + } + } + + return 0; +} + +int +compute_deltas(struct db_table *old, struct db_table *new, + struct deltas **result) +{ + struct deltas *deltas; + int error; + + error = deltas_create(&deltas); + if (error) + return error; + + error = add_roa_deltas(new->roas, old->roas, deltas, FLAG_ANNOUNCEMENT); + if (error) + goto fail; + error = add_roa_deltas(old->roas, new->roas, deltas, FLAG_WITHDRAWAL); + if (error) + goto fail; + error = add_router_key_deltas(new->router_keys, old->router_keys, + deltas, FLAG_ANNOUNCEMENT); + if (error) + goto fail; + error = add_router_key_deltas(old->router_keys, new->router_keys, + deltas, FLAG_WITHDRAWAL); + if (error) + goto fail; + + *result = deltas; + return 0; + +fail: + deltas_refput(deltas); + return error; +} diff --git a/src/rtr/db/db_table.h b/src/rtr/db/db_table.h new file mode 100644 index 00000000..178bc668 --- /dev/null +++ b/src/rtr/db/db_table.h @@ -0,0 +1,28 @@ +#ifndef SRC_RTR_DB_DB_TABLE_H_ +#define SRC_RTR_DB_DB_TABLE_H_ + +#include "rtr/db/delta.h" +#include "rtr/db/vrp.h" + +struct db_table; + +struct db_table *db_table_create(void); +void db_table_destroy(struct db_table *); + +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, + void *); + +int rtrhandler_handle_roa_v4(struct db_table *, uint32_t, + struct ipv4_prefix const *, uint8_t); +int rtrhandler_handle_roa_v6(struct db_table *, uint32_t, + struct ipv6_prefix const *, uint8_t); +int rtrhandler_handle_router_key(struct db_table *, unsigned char const *, + uint32_t, unsigned char const *, size_t); +int compute_deltas(struct db_table *, struct db_table *, struct deltas **); + +#endif /* SRC_RTR_DB_DB_TABLE_H_ */ diff --git a/src/rtr/db/delta.c b/src/rtr/db/delta.c index 0fd087cc..9461099f 100644 --- a/src/rtr/db/delta.c +++ b/src/rtr/db/delta.c @@ -18,11 +18,8 @@ struct delta_v6 { }; struct delta_bsec { - unsigned char *ski; - int *ski_len; uint32_t as; - unsigned char *spk; - int *spk_len; + struct sk_info *sk; }; ARRAY_LIST(deltas_v6, struct delta_v6) @@ -46,6 +43,12 @@ struct deltas { atomic_uint references; }; +static void +delta_bsec_cleanup(struct delta_bsec *bsec) +{ + sk_info_refput(bsec->sk); +} + int deltas_create(struct deltas **_result) { @@ -85,8 +88,9 @@ deltas_refput(struct deltas *deltas) deltas_v4_cleanup(&deltas->v4.removes, NULL); deltas_v6_cleanup(&deltas->v6.adds, NULL); deltas_v6_cleanup(&deltas->v6.removes, NULL); - deltas_bgpsec_cleanup(&deltas->bgpsec.adds, NULL); - deltas_bgpsec_cleanup(&deltas->bgpsec.removes, NULL); + deltas_bgpsec_cleanup(&deltas->bgpsec.adds, delta_bsec_cleanup); + deltas_bgpsec_cleanup(&deltas->bgpsec.removes, + delta_bsec_cleanup); free(deltas); } } @@ -132,16 +136,13 @@ deltas_add_roa_v6(struct deltas *deltas, uint32_t as, struct v6_address *addr, } int -deltas_add_bgpsec(struct deltas *deltas, unsigned char *ski, int ski_len, - uint32_t as, unsigned char *spk, int spk_len, int op) +deltas_add_bgpsec(struct deltas *deltas, struct router_key *key, int op) { struct delta_bsec delta = { - .ski = ski, - .ski_len = ski_len, - .as = as, - .spk = spk, - .spk_len = spk_len, + .as = key->as, + .sk = key->sk, }; + sk_info_refget(key->sk); switch (op) { case FLAG_ANNOUNCEMENT: @@ -229,12 +230,11 @@ __foreach_bgpsec(struct deltas_bgpsec *array, delta_bgpsec_foreach_cb cb, delta.flags = flags; ARRAYLIST_FOREACH(array, d, i) { - delta.router_key.ski = d->ski; - delta.router_key.ski_len = d->ski_len; - delta.router_key.asn = d->as; - delta.router_key.spk = d->spk; - delta.router_key.spk_len = d->spk_len; + delta.router_key.as = d->as; + delta.router_key.sk = d->sk; + sk_info_refget(d->sk); error = cb(&delta, arg); + sk_info_refput(d->sk); if (error) return error; } diff --git a/src/rtr/db/delta.h b/src/rtr/db/delta.h index 7512b317..7b70d6fd 100644 --- a/src/rtr/db/delta.h +++ b/src/rtr/db/delta.h @@ -1,6 +1,7 @@ #ifndef SRC_DELTA_H_ #define SRC_DELTA_H_ +#include "object/router_key.h" #include "rtr/db/roa.h" #include "rtr/db/vrp.h" @@ -12,8 +13,7 @@ void deltas_refput(struct deltas *); int deltas_add_roa_v4(struct deltas *, uint32_t, struct v4_address *, int); int deltas_add_roa_v6(struct deltas *, uint32_t, struct v6_address *, int); -int deltas_add_bgpsec(struct deltas *, unsigned char *, int, uint32_t, - unsigned char *, int, int); +int deltas_add_bgpsec(struct deltas *, struct router_key *, int); bool deltas_is_empty(struct deltas *); int deltas_foreach(serial_t, struct deltas *, delta_vrp_foreach_cb, diff --git a/src/rtr/db/roa_table.c b/src/rtr/db/roa_table.c deleted file mode 100644 index 3229069d..00000000 --- a/src/rtr/db/roa_table.c +++ /dev/null @@ -1,282 +0,0 @@ -#include "rtr/db/roa_table.h" - -#include /* AF_INET, AF_INET6 (needed in OpenBSD) */ -#include /* AF_INET, AF_INET6 (needed in OpenBSD) */ -#include "data_structure/uthash_nonfatal.h" - -struct hashable_roa { - struct vrp data; - UT_hash_handle hh; -}; - -/* FIXME Update whole roa_table logic */ -struct hashable_keys { - struct router_key data; - UT_hash_handle hh; -}; - -struct roa_table { - struct hashable_roa *roas; - struct hashable_keys *router_keys; -}; - -struct roa_table * -roa_table_create(void) -{ - struct roa_table *table; - - table = malloc(sizeof(struct roa_table)); - if (table == NULL) - return NULL; - - table->roas = NULL; - return table; -} - -void -roa_table_destroy(struct roa_table *table) -{ - struct hashable_roa *node; - struct hashable_roa *tmp; - - HASH_ITER(hh, table->roas, node, tmp) { - HASH_DEL(table->roas, node); - free(node); - } - - free(table); -} - -int -roa_table_foreach_roa(struct roa_table *table, vrp_foreach_cb cb, void *arg) -{ - struct hashable_roa *node, *tmp; - int error; - - HASH_ITER(hh, table->roas, node, tmp) { - error = cb(&node->data, arg); - if (error) - return error; - } - - return 0; -} - -static struct hashable_roa * -create_roa(uint32_t asn, uint8_t max_length) -{ - struct hashable_roa *roa; - - roa = malloc(sizeof(struct hashable_roa)); - if (roa == NULL) - return NULL; - /* Needed by uthash */ - memset(roa, 0, sizeof(struct hashable_roa)); - - roa->data.asn = asn; - roa->data.max_prefix_length = max_length; - - return roa; -} - -static int -add_roa(struct roa_table *table, struct hashable_roa *new) -{ - struct hashable_roa *old; - - errno = 0; - HASH_REPLACE(hh, table->roas, data, sizeof(new->data), new, old); - if (errno) - return -pr_errno(errno, "ROA couldn't be added to hash table"); - if (old != NULL) - free(old); - - return 0; -} - -static int -duplicate_roa(struct roa_table *dst, struct hashable_roa *new) -{ - struct vrp vrp; - struct ipv4_prefix prefix4; - struct ipv6_prefix prefix6; - - vrp = new->data; - switch (vrp.addr_fam) { - case AF_INET: - prefix4.addr = vrp.prefix.v4; - prefix4.len = vrp.prefix_length; - return rtrhandler_handle_roa_v4(dst, vrp.asn, &prefix4, - vrp.max_prefix_length); - case AF_INET6: - prefix6.addr = vrp.prefix.v6; - prefix6.len = vrp.prefix_length; - return rtrhandler_handle_roa_v6(dst, vrp.asn, &prefix6, - vrp.max_prefix_length); - } - - pr_crit("Unknown address family: %d", vrp.addr_fam); -} - -int -roa_table_merge(struct roa_table *dst, struct roa_table *src) -{ - struct hashable_roa *node, *tmp, *found; - int error; - - /** Must look for it due to the new mem allocation */ - HASH_ITER(hh, src->roas, node, tmp) { - HASH_FIND(hh, dst->roas, &node->data, sizeof(node->data), - found); - if (found != NULL) - continue; - error = duplicate_roa(dst, node); - if (error) - return error; - } - - return 0; -} - -int -roa_table_clone(struct roa_table **dst, struct roa_table *src) -{ - int error; - - *dst = roa_table_create(); - if (*dst == NULL) - return pr_enomem(); - - error = roa_table_merge(*dst, src); - if (error) - free(*dst); - - return error; -} - -void -roa_table_remove_roa(struct roa_table *table, struct vrp const *del) -{ - struct hashable_roa *ptr; - - HASH_FIND(hh, table->roas, del, sizeof(*del), ptr); - if (ptr != NULL) { - HASH_DELETE(hh, table->roas, ptr); - free(ptr); - } -} - -int -rtrhandler_handle_roa_v4(struct roa_table *table, uint32_t asn, - struct ipv4_prefix const *prefix4, uint8_t max_length) -{ - struct hashable_roa *roa; - int error; - - roa = create_roa(asn, max_length); - if (roa == NULL) - return pr_enomem(); - roa->data.prefix.v4 = prefix4->addr; - roa->data.prefix_length = prefix4->len; - roa->data.addr_fam = AF_INET; - - error = add_roa(table, roa); - if (error) - free(roa); - return error; -} - -int -rtrhandler_handle_roa_v6(struct roa_table *table, uint32_t asn, - struct ipv6_prefix const *prefix6, uint8_t max_length) -{ - struct hashable_roa *roa; - int error; - - roa = create_roa(asn, max_length); - if (roa == NULL) - return pr_enomem(); - roa->data.prefix.v6 = prefix6->addr; - roa->data.prefix_length = prefix6->len; - roa->data.addr_fam = AF_INET6; - - error = add_roa(table, roa); - if (error) - free(roa); - return error; -} - -static int -add_delta(struct deltas *deltas, struct hashable_roa *roa, int op) -{ - union { - struct v4_address v4; - struct v6_address v6; - } addr; - - switch (roa->data.addr_fam) { - case AF_INET: - addr.v4.prefix.addr = roa->data.prefix.v4; - addr.v4.prefix.len = roa->data.prefix_length; - addr.v4.max_length = roa->data.max_prefix_length; - return deltas_add_roa_v4(deltas, roa->data.asn, &addr.v4, op); - case AF_INET6: - addr.v6.prefix.addr = roa->data.prefix.v6; - addr.v6.prefix.len = roa->data.prefix_length; - addr.v6.max_length = roa->data.max_prefix_length; - return deltas_add_roa_v6(deltas, roa->data.asn, &addr.v6, op); - } - - pr_crit("Unknown address family: %d", roa->data.addr_fam); -} - -/* - * Copies `@roas1 - roas2` into @deltas. - * - * (Places the ROAs that exist in @roas1 but not in @roas2 in @deltas.) - */ -static int -add_deltas(struct hashable_roa *roas1, struct hashable_roa *roas2, - struct deltas *deltas, int op) -{ - struct hashable_roa *n1; /* A node from @roas1 */ - struct hashable_roa *n2; /* A node from @roas2 */ - int error; - - for (n1 = roas1; n1 != NULL; n1 = n1->hh.next) { - HASH_FIND(hh, roas2, &n1->data, sizeof(n1->data), n2); - if (n2 == NULL) { - error = add_delta(deltas, n1, op); - if (error) - return error; - } - } - - return 0; -} - -int -compute_deltas(struct roa_table *old, struct roa_table *new, - struct deltas **result) -{ - struct deltas *deltas; - int error; - - error = deltas_create(&deltas); - if (error) - return error; - - error = add_deltas(new->roas, old->roas, deltas, FLAG_ANNOUNCEMENT); - if (error) - goto fail; - error = add_deltas(old->roas, new->roas, deltas, FLAG_WITHDRAWAL); - if (error) - goto fail; - - *result = deltas; - return 0; - -fail: - deltas_refput(deltas); - return error; -} diff --git a/src/rtr/db/roa_table.h b/src/rtr/db/roa_table.h deleted file mode 100644 index f9776396..00000000 --- a/src/rtr/db/roa_table.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SRC_ROA_TABLE_H_ -#define SRC_ROA_TABLE_H_ - -#include "rtr/db/delta.h" -#include "rtr/db/vrp.h" - -struct roa_table; - -struct roa_table *roa_table_create(void); -void roa_table_destroy(struct roa_table *); - -int roa_table_merge(struct roa_table *, struct roa_table *); -int roa_table_clone(struct roa_table **, struct roa_table *); - -int roa_table_foreach_roa(struct roa_table *, vrp_foreach_cb, void *); -void roa_table_remove_roa(struct roa_table *, struct vrp const *); - -int rtrhandler_handle_roa_v4(struct roa_table *, uint32_t, - struct ipv4_prefix const *, uint8_t); -int rtrhandler_handle_roa_v6(struct roa_table *, uint32_t, - struct ipv6_prefix const *, uint8_t); - -int compute_deltas(struct roa_table *, struct roa_table *, struct deltas **); - -#endif /* SRC_ROA_TABLE_H_ */ diff --git a/src/rtr/db/vrps.c b/src/rtr/db/vrps.c index f1ffb0c1..b8a03bd5 100644 --- a/src/rtr/db/vrps.c +++ b/src/rtr/db/vrps.c @@ -11,7 +11,7 @@ #include "data_structure/array_list.h" #include "object/router_key.h" #include "object/tal.h" -#include "rtr/db/roa_table.h" +#include "rtr/db/db_table.h" #include "slurm/slurm_loader.h" /* @@ -39,7 +39,7 @@ struct state { * (We use this to know we're supposed to generate a @deltas entry * during the current iteration.) */ - struct roa_table *base; + struct db_table *base; /** ROA changes to @base over time. */ struct deltas_db deltas; @@ -94,7 +94,7 @@ void vrps_destroy(void) { if (state.base != NULL) - roa_table_destroy(state.base); + db_table_destroy(state.base); deltas_db_cleanup(&state.deltas, deltagroup_cleanup); pthread_rwlock_destroy(&lock); /* Nothing to do with error code */ } @@ -114,39 +114,35 @@ __handle_roa_v6(uint32_t as, struct ipv6_prefix const * prefix, } int -__handle_bgpsec(struct router_key const *router_key, void *arg) +__handle_bgpsec(unsigned char const *ski, uint32_t as, unsigned char const *spk, + size_t spk_len, void *arg) { - pr_debug("Handling BGPsec for ASN %u", router_key->asn); - /* - * FIXME Add RTR handler - * return rtrhandler_handle_router_key(arg, as, prefix, max_length); - */ - return 0; + return rtrhandler_handle_router_key(arg, ski, as, spk, spk_len); } static int -__perform_standalone_validation(struct roa_table **result) +__perform_standalone_validation(struct db_table **result) { - struct roa_table *roas; + struct db_table *db; struct validation_handler validation_handler; int error; - roas = roa_table_create(); - if (roas == NULL) + db = db_table_create(); + if (db == NULL) return pr_enomem(); validation_handler.handle_roa_v4 = __handle_roa_v4; validation_handler.handle_roa_v6 = __handle_roa_v6; validation_handler.handle_bgpsec = __handle_bgpsec; - validation_handler.arg = roas; + validation_handler.arg = db; error = perform_standalone_validation(&validation_handler); if (error) { - roa_table_destroy(roas); + db_table_destroy(db); return error; } - *result = roas; + *result = db; return 0; } @@ -233,8 +229,8 @@ vrps_purge(struct deltas **deltas) int vrps_update(bool *changed) { - struct roa_table *old_base; - struct roa_table *new_base; + struct db_table *old_base; + struct db_table *new_base; struct deltas *deltas; /* Deltas in raw form */ struct delta_group deltas_node; /* Deltas in database node form */ serial_t min_serial; @@ -311,10 +307,10 @@ vrps_update(bool *changed) rwlock_unlock(&lock); if (old_base != NULL) - roa_table_destroy(old_base); + db_table_destroy(old_base); /* Print after validation to avoid duplicated info */ - output_print_roas(new_base); + output_print_data(new_base); return 0; @@ -322,8 +318,8 @@ revert_deltas: deltas_refput(deltas); revert_base: /* Print info that was already validated */ - output_print_roas(new_base); - roa_table_destroy(new_base); + output_print_data(new_base); + db_table_destroy(new_base); return error; } @@ -343,7 +339,7 @@ vrps_foreach_base_roa(vrp_foreach_cb cb, void *arg) return error; if (state.base != NULL) - error = roa_table_foreach_roa(state.base, cb, arg); + error = db_table_foreach_roa(state.base, cb, arg); else error = -EAGAIN; @@ -402,7 +398,7 @@ vrps_foreach_filtered_delta(struct deltas_db *deltas, delta_vrp_foreach_cb cb, */ SLIST_INIT(&filtered_vrps); ARRAYLIST_FOREACH(deltas, group, i) { - /* FIXME Add function for router keys */ + /* FIXME Add cb function for router keys */ error = deltas_foreach(group->serial, group->deltas, vrp_ovrd_remove, NULL, &filtered_vrps); if (error) diff --git a/src/rtr/pdu_sender.c b/src/rtr/pdu_sender.c index bd7cb00e..547ef260 100644 --- a/src/rtr/pdu_sender.c +++ b/src/rtr/pdu_sender.c @@ -170,28 +170,36 @@ send_router_key_pdu(int fd, struct router_key const *router_key, uint8_t flags) reserved += (flags << 8); set_header_values(&pdu.header, PDU_TYPE_ROUTER_KEY, reserved); - pdu.ski = router_key->ski; - pdu.ski_len = router_key->ski_len; - pdu.asn = router_key->asn; - pdu.spki = router_key->spk; - pdu.spki_len = router_key->spk_len; + pdu.ski = sk_info_get_ski(router_key->sk); + pdu.ski_len = RK_SKI_LEN; + pdu.asn = router_key->as; + pdu.spki = sk_info_get_spk(router_key->sk); + pdu.spki_len = sk_info_get_spk_len(router_key->sk); pdu.header.length = RTRPDU_HDR_LEN - + router_key->ski_len - + sizeof(router_key->asn) - + router_key->spk_len; + + RK_SKI_LEN + + sizeof(router_key->as) + + pdu.spki_len; + sk_info_refget(router_key->sk); data = malloc(pdu.header.length); - if (data == NULL) - return pr_enomem(); + if (data == NULL) { + error = pr_enomem(); + goto release_sk; + } len = serialize_router_key_pdu(&pdu, data); - if (len != pdu.header.length) + if (len != pdu.header.length) { + sk_info_refput(router_key->sk); + free(data); pr_crit("Serialized Router Key PDU is %zu bytes, not the expected %u.", len, pdu.header.length); + } error = send_response(fd, data, len); - free(data); + +release_sk: + sk_info_refput(router_key->sk); return error; } diff --git a/src/rtr/pdu_sender.h b/src/rtr/pdu_sender.h index 413061d8..58b179cf 100644 --- a/src/rtr/pdu_sender.h +++ b/src/rtr/pdu_sender.h @@ -2,6 +2,7 @@ #define SRC_RTR_PDU_SENDER_H_ #include "pdu.h" +#include "object/router_key.h" #include "rtr/db/vrps.h" void init_sender_common(int, int, uint8_t); diff --git a/src/slurm/slurm_loader.c b/src/slurm/slurm_loader.c index 8b089b4e..482097a1 100644 --- a/src/slurm/slurm_loader.c +++ b/src/slurm/slurm_loader.c @@ -39,10 +39,10 @@ slurm_cleanup(void) static int slurm_pfx_filters_apply(struct vrp const *vrp, void *arg) { - struct roa_table *table = arg; + struct db_table *table = arg; if (slurm_db_vrp_is_filtered(vrp)) - roa_table_remove_roa(table, vrp); + db_table_remove_roa(table, vrp); return 0; } @@ -50,7 +50,7 @@ slurm_pfx_filters_apply(struct vrp const *vrp, void *arg) static int slurm_pfx_assertions_add(struct slurm_prefix *prefix, void *arg) { - struct roa_table *table = arg; + struct db_table *table = arg; struct ipv4_prefix prefix4; struct ipv6_prefix prefix6; struct vrp vrp; @@ -76,7 +76,7 @@ slurm_pfx_assertions_add(struct slurm_prefix *prefix, void *arg) } static int -slurm_pfx_assertions_apply(struct roa_table *base) +slurm_pfx_assertions_apply(struct db_table *base) { return slurm_db_foreach_assertion_prefix(slurm_pfx_assertions_add, base); @@ -88,9 +88,9 @@ slurm_pfx_assertions_apply(struct roa_table *base) * On any error the SLURM won't be applied to @base. */ int -slurm_apply(struct roa_table **base) +slurm_apply(struct db_table **base) { - struct roa_table *new_base; + struct db_table *new_base; bool loaded; int error; @@ -103,25 +103,25 @@ slurm_apply(struct roa_table **base) return 0; /* Deep copy of the base so that updates can be reverted */ - error = roa_table_clone(&new_base, *base); + error = db_table_clone(&new_base, *base); if (error) goto cleanup; - error = roa_table_foreach_roa(new_base, slurm_pfx_filters_apply, + error = db_table_foreach_roa(new_base, slurm_pfx_filters_apply, new_base); if (error) goto release_new; error = slurm_pfx_assertions_apply(new_base); if (!error) { - roa_table_destroy(*base); + db_table_destroy(*base); *base = new_base; goto cleanup; } /** TODO (next iteration) Apply BGPsec filters and assertions */ release_new: - roa_table_destroy(new_base); + db_table_destroy(new_base); cleanup: slurm_cleanup(); return error; diff --git a/src/slurm/slurm_loader.h b/src/slurm/slurm_loader.h index 55093ccd..c9801cc0 100644 --- a/src/slurm/slurm_loader.h +++ b/src/slurm/slurm_loader.h @@ -1,8 +1,8 @@ #ifndef SRC_SLURM_SLURM_LOADER_H_ #define SRC_SLURM_SLURM_LOADER_H_ -#include "rtr/db/roa_table.h" +#include "rtr/db/db_table.h" -int slurm_apply(struct roa_table **); +int slurm_apply(struct db_table **); #endif /* SRC_SLURM_SLURM_LOADER_H_ */ diff --git a/src/validation_handler.c b/src/validation_handler.c index ec17b127..c9cc3bf6 100644 --- a/src/validation_handler.c +++ b/src/validation_handler.c @@ -54,7 +54,8 @@ vhandler_handle_roa_v6(uint32_t as, struct ipv6_prefix const *prefix, } int -vhandler_handle_bgpsec(struct router_key const *router_key) +vhandler_handle_bgpsec(unsigned char const *ski, uint32_t as, + unsigned char const *spk, size_t spk_len) { struct validation_handler const *handler; int error; @@ -64,6 +65,6 @@ vhandler_handle_bgpsec(struct router_key const *router_key) return error; return (handler->handle_bgpsec != NULL) - ? handler->handle_bgpsec(router_key, handler->arg) + ? handler->handle_bgpsec(ski, as, spk, spk_len, handler->arg) : 0; } diff --git a/src/validation_handler.h b/src/validation_handler.h index 85cebf0d..91651220 100644 --- a/src/validation_handler.h +++ b/src/validation_handler.h @@ -29,14 +29,16 @@ struct validation_handler { /** Called every time Fort has successfully validated an IPv6 ROA. */ int (*handle_roa_v6)(uint32_t, struct ipv6_prefix const *, uint8_t, void *); - /** Called every time Fort has successfully a BGPsec certificate */ - int (*handle_bgpsec)(struct router_key const *, void *); + /** Called every time Fort has successfully validated a BGPsec cert */ + int (*handle_bgpsec)(unsigned char const *, uint32_t, + unsigned char const *, size_t, void *); /** Generic user-defined argument for the functions above. */ void *arg; }; int vhandler_handle_roa_v4(uint32_t, struct ipv4_prefix const *, uint8_t); int vhandler_handle_roa_v6(uint32_t, struct ipv6_prefix const *, uint8_t); -int vhandler_handle_bgpsec(struct router_key const *); +int vhandler_handle_bgpsec(unsigned char const *, uint32_t, + unsigned char const *, size_t); #endif /* SRC_VALIDATION_HANDLER_H_ */ diff --git a/test/Makefile.am b/test/Makefile.am index d86011c0..549709b2 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -21,10 +21,10 @@ MY_LDADD = ${CHECK_LIBS} check_PROGRAMS = address.test check_PROGRAMS += clients.test +check_PROGRAMS += db_table.test check_PROGRAMS += line_file.test check_PROGRAMS += pdu_handler.test check_PROGRAMS += rsync.test -check_PROGRAMS += roa_table.test check_PROGRAMS += tal.test check_PROGRAMS += vcard.test check_PROGRAMS += vrps.test @@ -38,15 +38,15 @@ address_test_LDADD = ${MY_LDADD} clients_test_SOURCES = client_test.c clients_test_LDADD = ${MY_LDADD} +db_table_test_SOURCES = rtr/db/db_table_test.c +db_table_test_LDADD = ${MY_LDADD} + line_file_test_SOURCES = line_file_test.c line_file_test_LDADD = ${MY_LDADD} pdu_handler_test_SOURCES = rtr/pdu_handler_test.c pdu_handler_test_LDADD = ${MY_LDADD} ${JANSSON_LIBS} -roa_table_test_SOURCES = rtr/db/roa_table_test.c -roa_table_test_LDADD = ${MY_LDADD} - rsync_test_SOURCES = rsync_test.c rsync_test_LDADD = ${MY_LDADD} diff --git a/test/impersonator.c b/test/impersonator.c index d4175e3a..16a9140d 100644 --- a/test/impersonator.c +++ b/test/impersonator.c @@ -107,6 +107,12 @@ config_get_output_roa(void) return NULL; } +char const * +config_get_output_bgpsec(void) +{ + return NULL; +} + enum incidence_action incidence_get_action(enum incidence_id id) { diff --git a/test/rtr/db/roa_table_test.c b/test/rtr/db/db_table_test.c similarity index 92% rename from test/rtr/db/roa_table_test.c rename to test/rtr/db/db_table_test.c index f3d4dc9b..f83c5e15 100644 --- a/test/rtr/db/roa_table_test.c +++ b/test/rtr/db/db_table_test.c @@ -4,8 +4,9 @@ #include "address.c" #include "log.c" #include "impersonator.c" +#include "object/router_key.c" #include "rtr/db/delta.c" -#include "rtr/db/roa_table.c" +#include "rtr/db/db_table.c" #define ADDR1 htonl(0xC0000201) /* 192.0.2.1 */ #define ADDR2 htonl(0xC0000202) /* 192.0.2.2 */ @@ -94,10 +95,10 @@ START_TEST(test_basic) { struct ipv4_prefix prefix4; struct ipv6_prefix prefix6; - struct roa_table *table; + struct db_table *table; array_index i; - table = roa_table_create(); + table = db_table_create(); ck_assert_ptr_ne(NULL, table); prefix4.addr.s_addr = ADDR1; @@ -152,12 +153,12 @@ START_TEST(test_basic) /* Check table contents */ memset(roas_found, 0, sizeof(roas_found)); total_found = 0; - ck_assert_int_eq(0, roa_table_foreach_roa(table, foreach_cb, NULL)); + ck_assert_int_eq(0, db_table_foreach_roa(table, foreach_cb, NULL)); ck_assert_int_eq(TOTAL_ROAS, total_found); for (i = 0; i < TOTAL_ROAS; i++) ck_assert_int_eq(true, roas_found[i]); - roa_table_destroy(table); + db_table_destroy(table); } END_TEST @@ -165,15 +166,15 @@ START_TEST(test_merge) { struct ipv4_prefix prefix4; struct ipv6_prefix prefix6; - struct roa_table *left, *right, *merged; + struct db_table *left, *right, *merged; array_index i; int left_count, right_count, total_merged; - left = roa_table_create(); + left = db_table_create(); ck_assert_ptr_ne(NULL, left); - right = roa_table_create(); + right = db_table_create(); ck_assert_ptr_ne(NULL, right); - merged = roa_table_create(); + merged = db_table_create(); ck_assert_ptr_ne(NULL, merged); prefix4.addr.s_addr = ADDR1; @@ -229,8 +230,8 @@ START_TEST(test_merge) right_count++; /** Do the merge */ - ck_assert_int_eq(0, roa_table_merge(merged, left)); - ck_assert_int_eq(0, roa_table_merge(merged, right)); + ck_assert_int_eq(0, db_table_merge(merged, left)); + ck_assert_int_eq(0, db_table_merge(merged, right)); /** * Must have: @@ -240,17 +241,17 @@ START_TEST(test_merge) ck_assert_int_eq(total_merged, TOTAL_ROAS); /* Check table contents and that merged table has new memory refs */ - roa_table_destroy(left); - roa_table_destroy(right); + db_table_destroy(left); + db_table_destroy(right); memset(roas_found, 0, sizeof(roas_found)); total_found = 0; - ck_assert_int_eq(0, roa_table_foreach_roa(merged, foreach_cb, NULL)); + ck_assert_int_eq(0, db_table_foreach_roa(merged, foreach_cb, NULL)); ck_assert_int_eq(TOTAL_ROAS, total_found); for (i = 0; i < TOTAL_ROAS; i++) ck_assert_int_eq(true, roas_found[i]); - roa_table_destroy(merged); + db_table_destroy(merged); } END_TEST @@ -265,7 +266,7 @@ Suite *pdu_suite(void) merge = tcase_create("Merge"); tcase_add_test(core, test_merge); - suite = suite_create("ROA Table"); + suite = suite_create("DB Table"); suite_add_tcase(suite, core); suite_add_tcase(suite, merge); return suite; diff --git a/test/rtr/db/vrps_test.c b/test/rtr/db/vrps_test.c index c61988e1..8935cbb0 100644 --- a/test/rtr/db/vrps_test.c +++ b/test/rtr/db/vrps_test.c @@ -9,8 +9,9 @@ #include "json_parser.c" #include "log.c" #include "output_printer.c" +#include "object/router_key.c" #include "rtr/db/delta.c" -#include "rtr/db/roa_table.c" +#include "rtr/db/db_table.c" #include "rtr/db/rtr_db_impersonator.c" #include "rtr/db/vrps.c" #include "slurm/slurm_db.c" @@ -126,7 +127,7 @@ get_vrp_index(struct vrp const *vrp) } static array_index -get_delta_index(struct delta const *delta) +get_delta_index(struct delta_vrp const *delta) { array_index result; @@ -150,7 +151,7 @@ vrp_check(struct vrp const *vrp, void *arg) } static int -delta_check(struct delta const *delta, void *arg) +delta_check(struct delta_vrp const *delta, void *arg) { bool *array = arg; array_index index; @@ -186,7 +187,7 @@ check_base(serial_t expected_serial, bool const *expected_base) } static int -vrp_add(struct delta const *delta, void *arg) +vrp_add(struct delta_vrp const *delta, void *arg) { struct deltas *deltas = arg; struct vrp const *vrp; @@ -250,9 +251,10 @@ 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, actual_deltas)); + delta_check, NULL, actual_deltas)); for (i = 0; i < ARRAY_LEN(actual_deltas); i++) ck_assert_uint_eq(expected_deltas[i], actual_deltas[i]); } diff --git a/test/rtr/pdu_handler_test.c b/test/rtr/pdu_handler_test.c index 1b77f00f..64adca77 100644 --- a/test/rtr/pdu_handler_test.c +++ b/test/rtr/pdu_handler_test.c @@ -10,6 +10,7 @@ #include "log.c" #include "output_printer.c" #include "crypto/base64.c" +#include "object/router_key.c" #include "rtr/pdu.c" #include "rtr/pdu_handler.c" #include "rtr/primitive_reader.c" @@ -17,7 +18,7 @@ #include "rtr/err_pdu.c" #include "rtr/stream.c" #include "rtr/db/delta.c" -#include "rtr/db/roa_table.c" +#include "rtr/db/db_table.c" #include "rtr/db/rtr_db_impersonator.c" #include "rtr/db/vrps.c" #include "slurm/slurm_db.c" @@ -145,7 +146,7 @@ send_prefix_pdu(int fd, struct vrp const *vrp, uint8_t flags) } static int -handle_delta(struct delta const *delta, void *arg) +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)); @@ -158,9 +159,10 @@ send_delta_pdus(int fd, 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, &fd)); + handle_delta, NULL, &fd)); return 0; }