Exemple #1
0
static inline bool is_left_child(const struct lrtr_ip_addr *addr,
				 unsigned int lvl)
{
	/* A node must be inserted as left child if bit <lvl> of the IP address
	 * is 0 otherwise as right child
	 */
	return lrtr_ip_addr_is_zero(lrtr_ip_addr_get_bits(addr, lvl, 1));
}
Exemple #2
0
/*
 * @brief Test IPv4 address bit operations required by trie
 */
static void get_bits_testv4(void)
{
	struct lrtr_ip_addr addr;
	struct lrtr_ip_addr result;

	addr.ver = LRTR_IPV4;
	addr.u.addr4.addr = 0xAABBCC22;

	result = lrtr_ip_addr_get_bits(&addr, 0, 32);
	assert(result.u.addr4.addr == 0xAABBCC22);

	result = lrtr_ip_addr_get_bits(&addr, 0, 1);
	assert(result.u.addr4.addr == 0x80000000);

	result = lrtr_ip_addr_get_bits(&addr, 1, 1);
	assert(result.u.addr4.addr == 0);

	result = lrtr_ip_addr_get_bits(&addr, 2, 1);
	assert(result.u.addr4.addr == 0x20000000);

	result = lrtr_ip_addr_get_bits(&addr, 0, 8);
	assert(result.u.addr4.addr == 0xAA000000);

	result = lrtr_ip_addr_get_bits(&addr, 8, 8);
	assert(result.u.addr4.addr == 0x00BB0000);

	lrtr_ip_str_to_addr("10.10.10.0", &addr);

	result = lrtr_ip_addr_get_bits(&addr, 0, 8);
	assert(lrtr_ip_str_cmp(&result, "10.0.0.0"));

	result = lrtr_ip_addr_get_bits(&addr, 0, 16);
	assert(lrtr_ip_str_cmp(&result, "10.10.0.0"));

	result = lrtr_ip_addr_get_bits(&addr, 8, 8);
	assert(lrtr_ip_str_cmp(&result, "0.10.0.0"));

	result = lrtr_ip_addr_get_bits(&addr, 8, 24);
	assert(lrtr_ip_str_cmp(&result, "0.10.10.0"));

	result = lrtr_ip_addr_get_bits(&addr, 31, 1);
	assert(result.u.addr4.addr == 0);

	result = lrtr_ip_addr_get_bits(&addr, 0, 1);
	assert(result.u.addr4.addr == 0);

	result = lrtr_ip_addr_get_bits(&addr, 3, 3);
	assert(lrtr_ip_str_cmp(&result, "8.0.0.0"));

	assert(lrtr_ip_str_to_addr("132.200.0.0", &addr) == 0);
	result = lrtr_ip_addr_get_bits(&addr, 0, 1);
	assert(result.u.addr4.addr == 0x80000000);

	assert(lrtr_ip_str_to_addr("101.200.0.0", &addr) == 0);
	result = lrtr_ip_addr_get_bits(&addr, 0, 1);
	assert(result.u.addr4.addr == 0);

	addr.u.addr4.addr = 0x6D698000;
	result = lrtr_ip_addr_get_bits(&addr, 0, 19);
	assert(result.u.addr4.addr == 0x6D698000);

	/* ip_str_to_addr("109.105.128.0", &addr);
	 * result = ip_addr_get_bits(&addr, 0, 8);
	 * printf("%u\n", result.u.addr4.addr);
	 */
	char buf[INET_ADDRSTRLEN];

	assert(lrtr_ip_str_to_addr("10.10.10.5", &addr) == 0);
	assert(lrtr_ip_addr_to_str(&addr, buf, sizeof(buf)) == 0);
	assert(strcmp("10.10.10.5", buf) == 0);
}
Exemple #3
0
/*
 * @brief Test IPv6 address bit operations required by trie
 */
static void get_bits_testv6(void)
{
	struct lrtr_ip_addr addr;
	struct lrtr_ip_addr result;

	addr.ver = LRTR_IPV6;
	addr.u.addr6.addr[0] = 0x22AABBCC;
	addr.u.addr6.addr[1] = 0xDDEEFF99;
	addr.u.addr6.addr[2] = 0x33001122;
	addr.u.addr6.addr[3] = 0x33445566;

	result = lrtr_ip_addr_get_bits(&addr, 0, 128);
	assert(result.u.addr6.addr[0] == addr.u.addr6.addr[0] &&
	       result.u.addr6.addr[1] == addr.u.addr6.addr[1] &&
	       result.u.addr6.addr[2] == addr.u.addr6.addr[2] &&
	       result.u.addr6.addr[3] == addr.u.addr6.addr[3]);

	result = lrtr_ip_addr_get_bits(&addr, 0, 64);
	assert(result.u.addr6.addr[0] == addr.u.addr6.addr[0] &&
	       result.u.addr6.addr[1] == addr.u.addr6.addr[1] &&
	       result.u.addr6.addr[2] == 0 &&
	       result.u.addr6.addr[3] == 0);

	bzero(&result, sizeof(result));
	result = lrtr_ip_addr_get_bits(&addr, 64, 64);
	assert(result.u.addr6.addr[0] == 0);
	assert(result.u.addr6.addr[1] == 0);
	assert(result.u.addr6.addr[2] == addr.u.addr6.addr[2]);
	assert(result.u.addr6.addr[3] == addr.u.addr6.addr[3]);

	result = lrtr_ip_addr_get_bits(&addr, 0, 8);
	assert(result.u.addr6.addr[0] == 0x22000000 &&
	       result.u.addr6.addr[1] == 0);

	result = lrtr_ip_addr_get_bits(&addr, 64, 8);
	assert(result.u.addr6.addr[1] == 0 &&
	       result.u.addr6.addr[2] == 0x33000000);

	result = lrtr_ip_addr_get_bits(&addr, 7, 8);
	assert(result.u.addr6.addr[0] == 0xAA0000 &&
	       result.u.addr6.addr[1] == 0);

	result = lrtr_ip_addr_get_bits(&addr, 68, 7);
	assert(result.u.addr6.addr[0] == 0 &&
	       result.u.addr6.addr[2] == 0x03000000);

	char buf[INET6_ADDRSTRLEN];

	lrtr_ip_str_to_addr("fe80::862b:2bff:fe9a:f50f", &addr);
	addr.ver = LRTR_IPV6;
	assert(addr.u.addr6.addr[0] == 0xfe800000);
	assert(addr.u.addr6.addr[1] == 0);
	assert(addr.u.addr6.addr[2] == 0x862b2bff);
	assert(addr.u.addr6.addr[3] == 0xfe9af50f);

	assert(lrtr_ip_str_to_addr("2001::", &addr) == 0);
	assert(addr.u.addr6.addr[0] == 0x20010000);
	assert(addr.u.addr6.addr[1] == 0);
	assert(addr.u.addr6.addr[2] == 0);
	assert(addr.u.addr6.addr[3] == 0);

	assert(lrtr_ip_addr_to_str(&addr, buf, sizeof(buf)) == 0);
	assert(strcmp("2001::", buf) == 0);

	lrtr_ip_str_to_addr("2001:0db8:85a3:08d3:1319:8a2e:0370:7344", &addr);
	assert(lrtr_ip_addr_to_str(&addr, buf, sizeof(buf)) == 0);
	assert(strcmp("2001:db8:85a3:8d3:1319:8a2e:370:7344", buf) == 0);

	result = lrtr_ip_addr_get_bits(&addr, 0, 16);
	assert(lrtr_ip_addr_to_str(&result, buf, sizeof(buf)) == 0);
	assert(lrtr_ip_str_cmp(&result, "2001::"));

	result = lrtr_ip_addr_get_bits(&addr, 16, 16);
	assert(lrtr_ip_addr_to_str(&result, buf, sizeof(buf)) == 0);
	assert(lrtr_ip_str_cmp(&result, "0:db8::"));
	result = lrtr_ip_addr_get_bits(&addr, 0, 1);
	assert(lrtr_ip_str_cmp(&result, "::"));

	result = lrtr_ip_addr_get_bits(&addr, 126, 1);
	assert(lrtr_ip_addr_to_str(&result, buf, sizeof(buf)) == 0);
	assert(lrtr_ip_str_cmp(&result, "::"));
}
Exemple #4
0
int pfx_table_validate_r(struct pfx_table *pfx_table, struct pfx_record **reason, unsigned int *reason_len, const uint32_t asn, const struct lrtr_ip_addr *prefix, const uint8_t prefix_len, enum pfxv_state *result)
{
    //assert(reason_len == NULL || *reason_len  == 0);
    //assert(reason == NULL || *reason == NULL);

    pthread_rwlock_rdlock(&(pfx_table->lock));
    struct lpfst_node *root = pfx_table_get_root(pfx_table, prefix->ver);
    if(root == NULL) {
        pthread_rwlock_unlock(&pfx_table->lock);
        *result = BGP_PFXV_STATE_NOT_FOUND;
        pfx_table_free_reason(reason, reason_len);
        return PFX_SUCCESS;
    }

    unsigned int lvl = 0;
    struct lpfst_node *node = lpfst_lookup(root, prefix, prefix_len, &lvl);
    if(node == NULL) {
        pthread_rwlock_unlock(&pfx_table->lock);
        *result = BGP_PFXV_STATE_NOT_FOUND;
        pfx_table_free_reason(reason, reason_len);
        return PFX_SUCCESS;
    }

    if(reason_len != NULL && reason != NULL) {
        *reason_len = ((struct node_data *) node->data)->len;
        *reason = realloc(*reason, *reason_len * sizeof(struct pfx_record));
        if(*reason == NULL) {
            pthread_rwlock_unlock(&pfx_table->lock);
            pfx_table_free_reason(reason, reason_len);
            return PFX_ERROR;
        }
        if(pfx_table_node2pfx_record(node, *reason, *reason_len) == PFX_ERROR) {
            pthread_rwlock_unlock(&pfx_table->lock);
            pfx_table_free_reason(reason, reason_len);
            return PFX_ERROR;
        }
    }

    while(!pfx_table_elem_matches(node->data, asn, prefix_len)) {
        if(lrtr_ip_addr_is_zero(lrtr_ip_addr_get_bits(prefix, lvl++, 1))) //post-incr lvl, lpfst_lookup is performed on child_nodes => parent lvl + 1
            node = lpfst_lookup(node->lchild, prefix, prefix_len, &lvl);
        else
            node = lpfst_lookup(node->rchild, prefix, prefix_len, &lvl);

        if(node == NULL) {
            pthread_rwlock_unlock(&pfx_table->lock);
            *result = BGP_PFXV_STATE_INVALID;
            return PFX_SUCCESS;
        }

        if(reason_len != NULL && reason != NULL) {
            unsigned int r_len_old = *reason_len;
            *reason_len += ((struct node_data *) node->data)->len;
            *reason = realloc(*reason, *reason_len * sizeof(struct pfx_record));
            struct pfx_record *start = *reason + r_len_old;
            if(*reason == NULL) {
                pthread_rwlock_unlock(&pfx_table->lock);
                pfx_table_free_reason(reason, reason_len);
                return PFX_ERROR;
            }
            if(pfx_table_node2pfx_record(node, start, ((struct node_data *) node->data)->len) == PFX_ERROR) {
                pthread_rwlock_unlock(&pfx_table->lock);
                pfx_table_free_reason(reason, reason_len);
                return PFX_ERROR;
            }
        }
    }

    pthread_rwlock_unlock(&pfx_table->lock);
    *result = BGP_PFXV_STATE_VALID;
    return PFX_SUCCESS;
}