/** * @brief Delete records from prefix table */ static void rec_del(struct pfx_table *pfxt) { const int tid = getpid(); struct pfx_record rec; rec.min_len = 32; rec.max_len = 32; rec.prefix.ver = LRTR_IPV4; rec.prefix.u.addr4.addr = 0; printf("removing records\n"); for (uint32_t i = max_i; i >= min_i; i--) { rec.socket = NULL; rec.min_len = 32; rec.max_len = 32; rec.asn = tid % 2; rec.prefix.ver = LRTR_IPV4; rec.prefix.u.addr4.addr = htonl(i); pfx_table_remove(pfxt, &rec); rec.asn = (tid % 2) + 1; pfx_table_remove(pfxt, &rec); rec.prefix.ver = LRTR_IPV6; rec.min_len = 128; rec.max_len = 128; rec.prefix.u.addr6.addr[1] = min_i + 0xFFFFFFFF; rec.prefix.u.addr6.addr[0] = htonl(i) + 0xFFFFFFFF; pfx_table_remove(pfxt, &rec); usleep(rand() / (RAND_MAX / 20)); } printf("Done\n"); }
/* * @brief Removes all Prefix from the pfx_table with flag field == ADD, ADDs all Prefix PDU to the pfx_table with flag * field == REMOVE. */ static int rtr_undo_update_pfx_table(struct rtr_socket *rtr_socket, void *pdu) { const enum pdu_type type = rtr_get_pdu_type(pdu); assert(type == IPV4_PREFIX || type == IPV6_PREFIX); struct pfx_record pfxr; rtr_prefix_pdu_2_pfx_record(rtr_socket, pdu, &pfxr, type); int rtval = RTR_ERROR; //invert add/remove operation if (((struct pdu_ipv4 *) pdu)->flags == 1) rtval = pfx_table_remove(rtr_socket->pfx_table, &pfxr); else if (((struct pdu_ipv4 *) pdu)->flags == 0) rtval = pfx_table_add(rtr_socket->pfx_table, &pfxr); return rtval; }
static int rtr_update_pfx_table(struct rtr_socket *rtr_socket, const void *pdu) { const enum pdu_type type = rtr_get_pdu_type(pdu); assert(type == IPV4_PREFIX || type == IPV6_PREFIX); struct pfx_record pfxr; size_t pdu_size = (type == IPV4_PREFIX ? sizeof(struct pdu_ipv4) : sizeof(struct pdu_ipv6)); rtr_prefix_pdu_2_pfx_record(rtr_socket, pdu, &pfxr, type); int rtval; if (((struct pdu_ipv4 *) pdu)->flags == 1) rtval = pfx_table_add(rtr_socket->pfx_table, &pfxr); else if (((struct pdu_ipv4 *) pdu)->flags == 0) rtval = pfx_table_remove(rtr_socket->pfx_table, &pfxr); else { const char txt[] = "Prefix PDU with invalid flags value received"; RTR_DBG("%s", txt); rtr_send_error_pdu(rtr_socket, pdu, pdu_size, CORRUPT_DATA, txt, sizeof(txt)); return RTR_ERROR; } if (rtval == PFX_DUPLICATE_RECORD) { char ip[INET6_ADDRSTRLEN]; lrtr_ip_addr_to_str(&(pfxr.prefix), ip, INET6_ADDRSTRLEN); RTR_DBG("Duplicate Announcement for record: %s/%u-%u, ASN: %u, received", ip, pfxr.min_len, pfxr.max_len, pfxr.asn); rtr_send_error_pdu(rtr_socket, pdu, pdu_size, DUPLICATE_ANNOUNCEMENT , NULL, 0); rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); return RTR_ERROR; } else if (rtval == PFX_RECORD_NOT_FOUND) { RTR_DBG1("Withdrawal of unknown record"); rtr_send_error_pdu(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 (rtval == PFX_ERROR) { const char txt[] = "PFX_TABLE Error"; RTR_DBG("%s", txt); rtr_send_error_pdu(rtr_socket, pdu, pdu_size, INTERNAL_ERROR, txt, sizeof(txt)); rtr_change_socket_state(rtr_socket, RTR_ERROR_FATAL); return RTR_ERROR; } return RTR_SUCCESS; }
int test_rtr_validation() { cfg_tr = bgpstream_rtr_start_connection(TEST_RPKI_VALIDATOR_URL, TEST_RPKI_VALIDATOR_PORT, NULL, NULL, NULL, NULL, NULL, NULL); struct pfx_table *pfxt = cfg_tr->groups[0].sockets[0]->pfx_table; struct pfx_record pfx_v4; char ipv4_address[INET_ADDRSTRLEN]; pfx_v4.min_len = TEST_MIN_LEN; pfx_v4.max_len = TEST_MAX_LEN; pfx_v4.socket = TEST_SOCKET; pfx_v4.asn = TEST_ASN; strcpy(ipv4_address, TEST_IP_ADDR); lrtr_ip_str_to_addr(ipv4_address, &pfx_v4.prefix); pfx_table_remove(pfxt, &pfx_v4); struct pfx_record pfx_v6; char ipv6_address[INET6_ADDRSTRLEN]; pfx_v6.min_len = 48; pfx_v6.max_len = 48; pfx_v6.socket = NULL; pfx_v6.asn = 12654; strcpy(ipv6_address, "2001:7fb:fd02::\0"); lrtr_ip_str_to_addr(ipv6_address, &pfx_v6.prefix); pfx_table_remove(pfxt, &pfx_v6); struct reasoned_result res; CHECK("RTR: Add a valid pfx_record to pfx_table", pfx_table_add(pfxt, &pfx_v4) == PFX_SUCCESS); res = bgpstream_rtr_validate_reason(cfg_tr, pfx_v4.asn, ipv4_address, pfx_v4.max_len); CHECK("RTR: Compare valid IPv4 ROA with validation result", res.result == BGP_PFXV_STATE_VALID); CHECK("RTR: Add a valid pfx_record to pfx_table", pfx_table_add(pfxt, &pfx_v6) == PFX_SUCCESS); res = bgpstream_rtr_validate_reason(cfg_tr, pfx_v6.asn, ipv6_address, pfx_v6.max_len); CHECK("RTR: Compare valid IPv6 ROA with validation result", res.result == BGP_PFXV_STATE_VALID); res = bgpstream_rtr_validate_reason(cfg_tr, 196615, ipv4_address, pfx_v4.max_len); CHECK("RTR: Compare invalid (asn) IPv4 ROA with validation result", res.result == BGP_PFXV_STATE_INVALID); res = bgpstream_rtr_validate_reason(cfg_tr, 196615, ipv6_address, pfx_v6.max_len); CHECK("RTR: Compare invalid (asn) IPv6 ROA with validation result", res.result == BGP_PFXV_STATE_INVALID); res = bgpstream_rtr_validate_reason(cfg_tr, pfx_v4.asn, ipv4_address, 30); CHECK("RTR: Compare invalid (max len) IPv4 ROA with validation result", res.result == BGP_PFXV_STATE_INVALID); res = bgpstream_rtr_validate_reason(cfg_tr, pfx_v6.asn, ipv6_address, 50); CHECK("RTR: Compare invalid (max len) IPv6 ROA with validation result", res.result == BGP_PFXV_STATE_INVALID); pfx_v4.asn = 12345; lrtr_ip_str_to_addr("84.205.83.0\0", &pfx_v4.prefix); pfx_table_remove(pfxt, &pfx_v4); res = bgpstream_rtr_validate_reason(cfg_tr, 12345, "84.205.83.0\0", pfx_v4.max_len); CHECK("RTR: Compare none existend IPv4 ROA with validation result", res.result == BGP_PFXV_STATE_NOT_FOUND); pfx_v6.asn = 12345; lrtr_ip_str_to_addr("2001:7fb:ff03::\0", &pfx_v6.prefix); pfx_table_remove(pfxt, &pfx_v6); res = bgpstream_rtr_validate_reason(cfg_tr, 12345, "2001:7fb:ff03::\0", pfx_v6.max_len); CHECK("RTR: Compare none existend IPv6 ROA with validation result", res.result == BGP_PFXV_STATE_NOT_FOUND); free(res.reason); bgpstream_rtr_close_connection(cfg_tr); return 0; }