From: Alberto Leiva Popper Date: Fri, 5 Jun 2026 00:14:56 +0000 (-0600) Subject: Apply PDU ordering from 8210bis-25#section-11.2 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=refs%2Fheads%2Faspa;p=thirdparty%2FFORT-validator.git Apply PDU ordering from 8210bis-25#section-11.2 --- diff --git a/src/rtr/db/db_table.c b/src/rtr/db/db_table.c index 5b51983a..1764cdef 100644 --- a/src/rtr/db/db_table.c +++ b/src/rtr/db/db_table.c @@ -266,18 +266,20 @@ cmp_vrp(struct hashable_roa *_a, struct hashable_roa *_b) cmp = cmp_u8(a->addr_fam, b->addr_fam); if (cmp) return cmp; - cmp = cmp_u32(a->asn, b->asn); - if (cmp) return cmp; switch (a->addr_fam) { - case AF_INET: cmp = memcmp(&a->prefix.v4, &b->prefix.v4, 4); break; - case AF_INET6: cmp = memcmp(&a->prefix.v6, &b->prefix.v6, 16); break; + case AF_INET: cmp = memcmp(&b->prefix.v4, &a->prefix.v4, 4); break; + case AF_INET6: cmp = memcmp(&b->prefix.v6, &a->prefix.v6, 16); break; } if (cmp) return cmp; - cmp = cmp_u8(a->prefix_length, b->prefix_length); + cmp = cmp_u8(b->max_prefix_length, a->max_prefix_length); + if (cmp) return cmp; + + cmp = cmp_u8(b->prefix_length, a->prefix_length); if (cmp) return cmp; - return cmp_u8(a->max_prefix_length, b->max_prefix_length); + + return cmp_u32(b->asn, a->asn); } static int @@ -287,11 +289,11 @@ cmp_rk(struct hashable_key *_a, struct hashable_key *_b) struct router_key *b = &_b->data; int cmp; - cmp = cmp_u32(a->as, b->as); - if (cmp) return cmp; cmp = memcmp(a->ski, b->ski, RK_SKI_LEN); if (cmp) return cmp; - return memcmp(a->spk, b->spk, RK_SPKI_LEN); + cmp = memcmp(a->spk, b->spk, RK_SPKI_LEN); + if (cmp) return cmp; + return cmp_u32(a->as, b->as); } static int diff --git a/src/rtr/pdu_handler.c b/src/rtr/pdu_handler.c index ad3ed4eb..8646ee86 100644 --- a/src/rtr/pdu_handler.c +++ b/src/rtr/pdu_handler.c @@ -312,8 +312,28 @@ internal_error: return err_pdu_send_internal_error(stream.fd, stream.ver); } +struct withdrawal { + unsigned char raw[22]; +}; + +struct withdrawal_array { + struct withdrawal *a; /* array */ + size_t n; /* array length */ + size_t c; /* array capacity */ +}; + +static void +add_withdrawal(struct withdrawal_array *wds, unsigned char const *chunk, size_t size) +{ + if (wds->n >= wds->c) { + wds->c <<= 1; + wds->a = prealloc(wds->a, wds->c * sizeof(struct withdrawal)); + } + memcpy(wds->a[wds->n++].raw, chunk, size); +} + static int -send_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial) +send_pfx_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial) { FILE *ofile = NULL; FILE *nfile = NULL; @@ -321,12 +341,18 @@ send_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial) unsigned char *buf2; unsigned char const *ochunk; unsigned char const *nchunk; + struct withdrawal_array wds; + ssize_t w; int cmp; int error; buf1 = pmalloc(rs->rawlen); buf2 = pmalloc(rs->rawlen); + wds.n = 0; + wds.c = 128; + wds.a = pmalloc(wds.c * sizeof(struct withdrawal)); + error = rtr_open_file(oserial, rs->type, "r", &ofile); if (error) goto end; @@ -343,15 +369,13 @@ send_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial) while (ochunk && nchunk) { cmp = memcmp(ochunk, nchunk, rs->rawlen); - if (cmp < 0) { - error = rs->send(rs, ochunk, FLAG_WITHDRAWAL); - if (error) - goto end; + if (cmp > 0) { + add_withdrawal(&wds, ochunk, rs->rawlen); ochunk = next_chunk(ofile, buf1, rs->rawlen, &error); if (error) goto end; - } else if (cmp > 0) { + } else if (cmp < 0) { error = rs->send(rs, nchunk, FLAG_ANNOUNCEMENT); if (error) goto end; @@ -369,33 +393,39 @@ send_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial) } } - while (ochunk) { - error = rs->send(rs, ochunk, FLAG_WITHDRAWAL); + while (nchunk) { + error = rs->send(rs, nchunk, FLAG_ANNOUNCEMENT); if (error) goto end; - ochunk = next_chunk(ofile, buf1, rs->rawlen, &error); + nchunk = next_chunk(nfile, buf2, rs->rawlen, &error); if (error) goto end; } - while (nchunk) { - error = rs->send(rs, nchunk, FLAG_ANNOUNCEMENT); + while (ochunk) { + add_withdrawal(&wds, ochunk, rs->rawlen); + ochunk = next_chunk(ofile, buf1, rs->rawlen, &error); if (error) goto end; - nchunk = next_chunk(nfile, buf2, rs->rawlen, &error); + } + + for (w = wds.n - 1; w >= 0; w--) { + error = rs->send(rs, wds.a[w].raw, FLAG_WITHDRAWAL); if (error) goto end; } end: if (nfile) fclose(nfile); if (ofile) fclose(ofile); + free(wds.a); free(buf2); free(buf1); return error; } static int -send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial) +send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial, + bool announce) { FILE *ofile = NULL; FILE *nfile = NULL; @@ -426,14 +456,18 @@ send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial) while (ochunk && nchunk) { cmp = memcmp(ochunk, nchunk, 4); /* AS only */ if (cmp < 0) { - error = send_aspa_withdraw(fd, ver, ochunk, ofile); + error = announce + ? skip_providers(ochunk, ofile) + : send_aspa_withdraw(fd, ver, ochunk, ofile); if (error) goto end; ochunk = next_chunk(ofile, buf1, 8, &error); if (error) goto end; } else if (cmp > 0) { - error = send_aspa_announce(fd, ver, nchunk, nfile); + error = announce + ? send_aspa_announce(fd, ver, nchunk, nfile) + : skip_providers(nchunk, nfile); if (error) goto end; nchunk = next_chunk(nfile, buf2, 8, &error); @@ -449,7 +483,7 @@ send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial) goto end; } - if (!providers_equal(&oprovs, &nprovs)) { + if (announce && !providers_equal(&oprovs, &nprovs)) { aspa.customer = read_u32(nchunk); aspa.providers = nprovs; error = send_aspa_announce_pdu(fd, ver, &aspa); @@ -472,22 +506,24 @@ send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial) } } - while (ochunk) { - error = send_aspa_withdraw(fd, ver, ochunk, ofile); - if (error) - goto end; - ochunk = next_chunk(ofile, buf1, 8, &error); - if (error) - goto end; - } - - while (nchunk) { - error = send_aspa_announce(fd, ver, nchunk, nfile); - if (error) - goto end; - nchunk = next_chunk(nfile, buf2, 8, &error); - if (error) - goto end; + if (announce) { + while (nchunk) { + error = send_aspa_announce(fd, ver, nchunk, nfile); + if (error) + goto end; + nchunk = next_chunk(nfile, buf2, 8, &error); + if (error) + goto end; + } + } else { + while (ochunk) { + error = send_aspa_withdraw(fd, ver, ochunk, ofile); + if (error) + goto end; + ochunk = next_chunk(ofile, buf1, 8, &error); + if (error) + goto end; + } } end: if (ofile) fclose(ofile); @@ -540,17 +576,18 @@ handle_serial_query_pdu(struct rtr_request *request) stream.type = "vrp4"; stream.rawlen = 10; stream.send = send_vrp4; - error = send_delta(&stream, oserial, nserial); + error = send_pfx_delta(&stream, oserial, nserial); if (error) goto internal_error; stream.type = "vrp6"; stream.rawlen = 22; stream.send = send_vrp6; - error = send_delta(&stream, oserial, nserial); + error = send_pfx_delta(&stream, oserial, nserial); if (error) goto internal_error; + /* if (stream.ver >= RTR_V1) { stream.type = "rk"; stream.rawlen = 4 + RK_SKI_LEN + RK_SPKI_LEN; @@ -559,9 +596,15 @@ handle_serial_query_pdu(struct rtr_request *request) if (error) goto internal_error; } + */ if (stream.ver >= RTR_V2) { - error = send_aspa_delta(stream.fd, stream.ver, oserial, nserial); + error = send_aspa_delta(stream.fd, stream.ver, oserial, nserial, + true); + if (error) + goto internal_error; + error = send_aspa_delta(stream.fd, stream.ver, oserial, nserial, + false); if (error) goto internal_error; } diff --git a/test/rtr/pdu_handler_test.c b/test/rtr/pdu_handler_test.c index 6d54a240..73d46a7b 100644 --- a/test/rtr/pdu_handler_test.c +++ b/test/rtr/pdu_handler_test.c @@ -230,12 +230,12 @@ check_response(void) pr_op_debug("Expected:"); for (i = 0; i < e; i++) - pr_op_debug("- %s %u %u", pdutype2str(expected[i].type), - expected[i].as, expected[i].flags); + pr_op_debug("%s %s as:%u", expected[i].flags ? "+" : "-", + pdutype2str(expected[i].type), expected[i].as); pr_op_debug("Actual:"); for (i = 0; i < a; i++) - pr_op_debug("- %s %u %u", pdutype2str(actual[i].type), - actual[i].as, actual[i].flags); + pr_op_debug("%s %s as:%u", expected[i].flags ? "+" : "-", + pdutype2str(actual[i].type), actual[i].as); ck_assert_uint_eq(e, a); for (i = 0; i < e; i++) { @@ -348,10 +348,10 @@ START_TEST(test_natural_flows) e = 0; expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); - expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT); + expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT); + expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT); @@ -363,7 +363,7 @@ START_TEST(test_natural_flows) expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); rcv_serial_query(session, 1); @@ -387,14 +387,14 @@ START_TEST(test_natural_flows) e = 0; expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); - expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL); + expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL); + expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_ANNOUNCEMENT); + expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); rcv_serial_query(session, 1); @@ -402,7 +402,7 @@ START_TEST(test_natural_flows) expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); rcv_serial_query(session, 2); @@ -433,7 +433,7 @@ START_TEST(test_natural_flows) expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_WITHDRAWAL); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); rcv_serial_query(session, 2); @@ -444,8 +444,8 @@ START_TEST(test_natural_flows) expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_WITHDRAWAL); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); @@ -496,10 +496,10 @@ START_TEST(test_delta_forget) e = 0; expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); - expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT); + expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT); + expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT); @@ -511,7 +511,7 @@ START_TEST(test_delta_forget) expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); rcv_serial_query(session, 1); @@ -541,7 +541,7 @@ START_TEST(test_delta_forget) expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0); expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0); rcv_serial_query(session, 2); @@ -577,8 +577,8 @@ START_TEST(test_delta_forget) expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_WITHDRAWAL); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT); - expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT); +// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT); expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_WITHDRAWAL); expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);