mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 06:23:53 +01:00
fib: changed handling of the net prefix
Until now the prefix length has been determined automatically by the FIB This PR changes it to be provided as msb(yte) in the global_flags of an entry
This commit is contained in:
parent
18b7c8e2e4
commit
1bc9c3bfd2
@ -78,9 +78,14 @@ typedef struct fib_destination_set_entry_t {
|
||||
#define FIB_FLAG_RPL_ROUTE (1UL << 0)
|
||||
|
||||
/**
|
||||
* @brief flag to identify if the FIB-Entry is a net prefix (MSB == 1)
|
||||
* @brief flag used as shift for the net prefix length in bits
|
||||
*/
|
||||
#define FIB_FLAG_NET_PREFIX (1UL<<31)
|
||||
#define FIB_FLAG_NET_PREFIX_SHIFT (24)
|
||||
|
||||
/**
|
||||
* @brief flag used as mask for the net prefix length in bits
|
||||
*/
|
||||
#define FIB_FLAG_NET_PREFIX_MASK (0xffUL << FIB_FLAG_NET_PREFIX_SHIFT)
|
||||
|
||||
/**
|
||||
* @brief initializes all FIB entries with 0
|
||||
|
||||
@ -451,7 +451,7 @@ bool _parse_options(int msg_type, gnrc_rpl_instance_t *inst, gnrc_rpl_opt_t *opt
|
||||
uint32_t fib_dst_flags = 0;
|
||||
|
||||
if (target->prefix_length < IPV6_ADDR_BIT_LEN) {
|
||||
fib_dst_flags |= FIB_FLAG_NET_PREFIX;
|
||||
fib_dst_flags = ((uint32_t)(target->prefix_length) << FIB_FLAG_NET_PREFIX_SHIFT);
|
||||
}
|
||||
|
||||
DEBUG("RPL: adding fib entry %s/%d 0x%x\n",
|
||||
@ -816,16 +816,7 @@ void gnrc_rpl_send_DAO(gnrc_rpl_instance_t *inst, ipv6_addr_t *destination, uint
|
||||
}
|
||||
addr = (ipv6_addr_t *) fentry->global->address;
|
||||
if (ipv6_addr_is_global(addr)) {
|
||||
size_t prefix_length;
|
||||
|
||||
if (fentry->global_flags & FIB_FLAG_NET_PREFIX) {
|
||||
universal_address_compare(fentry->global,
|
||||
fentry->global->address,
|
||||
&prefix_length);
|
||||
}
|
||||
else {
|
||||
prefix_length = IPV6_ADDR_BIT_LEN;
|
||||
}
|
||||
size_t prefix_length = (fentry->global_flags >> FIB_FLAG_NET_PREFIX_SHIFT);
|
||||
|
||||
DEBUG("RPL: Send DAO - building target %s/%d\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
|
||||
@ -204,7 +204,7 @@ bool gnrc_rpl_parent_remove(gnrc_rpl_parent_t *parent)
|
||||
dodag->iface,
|
||||
(uint8_t *) ipv6_addr_unspecified.u8,
|
||||
sizeof(ipv6_addr_t),
|
||||
FIB_FLAG_NET_PREFIX,
|
||||
0x0,
|
||||
parent->next->addr.u8,
|
||||
sizeof(ipv6_addr_t),
|
||||
FIB_FLAG_RPL_ROUTE,
|
||||
@ -248,7 +248,7 @@ void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent)
|
||||
dodag->iface,
|
||||
(uint8_t *) ipv6_addr_unspecified.u8,
|
||||
sizeof(ipv6_addr_t),
|
||||
FIB_FLAG_NET_PREFIX,
|
||||
0x00,
|
||||
parent->addr.u8,
|
||||
sizeof(ipv6_addr_t),
|
||||
FIB_FLAG_RPL_ROUTE,
|
||||
@ -300,7 +300,7 @@ static gnrc_rpl_parent_t *_gnrc_rpl_find_preferred_parent(gnrc_rpl_dodag_t *doda
|
||||
dodag->iface,
|
||||
(uint8_t *) ipv6_addr_unspecified.u8,
|
||||
sizeof(ipv6_addr_t),
|
||||
FIB_FLAG_NET_PREFIX,
|
||||
0x00,
|
||||
dodag->parents->addr.u8,
|
||||
sizeof(ipv6_addr_t),
|
||||
FIB_FLAG_RPL_ROUTE,
|
||||
|
||||
@ -132,8 +132,7 @@ static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size,
|
||||
|
||||
int ret_comp = universal_address_compare(table->data.entries[i].global, dst, &match_size);
|
||||
/* If we found an exact match */
|
||||
if (ret_comp == 0 || (is_all_zeros_addr && match_size == 0)) {
|
||||
DEBUG("[fib_find_entry] found an exact match");
|
||||
if ((ret_comp == 0) || (is_all_zeros_addr && (match_size == 0) && (ret_comp == 2))) {
|
||||
entry_arr[0] = &(table->data.entries[i]);
|
||||
*entry_arr_size = 1;
|
||||
/* we will not find a better one so we return */
|
||||
@ -141,14 +140,31 @@ static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size,
|
||||
}
|
||||
else {
|
||||
/* we try to find the most fitting prefix */
|
||||
if ((ret_comp == 1)
|
||||
&& (table->data.entries[i].global_flags & FIB_FLAG_NET_PREFIX)) {
|
||||
if ((prefix_size == 0) || (match_size > prefix_size)) {
|
||||
if (ret_comp == 1) {
|
||||
if (table->data.entries[i].global_flags & FIB_FLAG_NET_PREFIX_MASK) {
|
||||
/* we shift the most upper flag byte back to get the number of prefix bits */
|
||||
size_t global_prefix_len = (table->data.entries[i].global_flags
|
||||
& FIB_FLAG_NET_PREFIX_MASK) >> FIB_FLAG_NET_PREFIX_SHIFT;
|
||||
|
||||
if ((match_size >= global_prefix_len) &&
|
||||
((prefix_size == 0) || (match_size > prefix_size))) {
|
||||
entry_arr[0] = &(table->data.entries[i]);
|
||||
/* we could find a better one so we move on */
|
||||
ret = 0;
|
||||
|
||||
prefix_size = match_size;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ret_comp == 2) {
|
||||
/* we found the default gateway entry, e.g. ::/0 for IPv6
|
||||
* and we keep it only if there is no better one
|
||||
*/
|
||||
if (prefix_size == 0) {
|
||||
entry_arr[0] = &(table->data.entries[i]);
|
||||
/* we could find a better one so we move on */
|
||||
ret = 0;
|
||||
|
||||
prefix_size = match_size;
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
@ -1516,17 +1532,19 @@ void fib_print_routes(fib_table_t *table)
|
||||
uint64_t now = xtimer_now64();
|
||||
|
||||
if (table->table_type == FIB_TABLE_TYPE_SH) {
|
||||
printf("%-" FIB_ADDR_PRINT_LENS "s %-10s %-" FIB_ADDR_PRINT_LENS "s %-10s %-16s"
|
||||
printf("%-" FIB_ADDR_PRINT_LENS "s %-17s %-" FIB_ADDR_PRINT_LENS "s %-10s %-16s"
|
||||
" Interface\n" , "Destination", "Flags", "Next Hop", "Flags", "Expires");
|
||||
|
||||
for (size_t i = 0; i < table->size; ++i) {
|
||||
if (table->data.entries[i].lifetime != 0) {
|
||||
fib_print_address(table->data.entries[i].global);
|
||||
printf(" 0x%08"PRIx32" ", table->data.entries[i].global_flags);
|
||||
if(table->data.entries[i].global_flags & FIB_FLAG_NET_PREFIX) {
|
||||
printf("N ");
|
||||
if(table->data.entries[i].global_flags & FIB_FLAG_NET_PREFIX_MASK) {
|
||||
uint32_t prefix = (table->data.entries[i].global_flags
|
||||
& FIB_FLAG_NET_PREFIX_MASK);
|
||||
printf("N /%-3d ", (int)(prefix >> FIB_FLAG_NET_PREFIX_SHIFT));
|
||||
} else {
|
||||
printf("H ");
|
||||
printf("H ");
|
||||
}
|
||||
|
||||
fib_print_address(table->data.entries[i].next_hop);
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
#define INFO1_TXT "fibroute add <destination> via <next hop> [dev <device>]"
|
||||
#define INFO2_TXT " [lifetime <lifetime>]"
|
||||
#define INFO3_TXT " <destination> - the destination address\n" \
|
||||
#define INFO3_TXT " <destination> - the destination address with optional prefix size, e.g. /116\n" \
|
||||
" <next hop> - the address of the next-hop towards the <destination>\n" \
|
||||
" <device> - the device id of the Interface to use." \
|
||||
" Optional if only one interface is available.\n"
|
||||
@ -79,15 +79,33 @@ static void _fib_usage(int info)
|
||||
|
||||
static void _fib_add(const char *dest, const char *next, kernel_pid_t pid, uint32_t lifetime)
|
||||
{
|
||||
unsigned char *dst = (unsigned char *)dest;
|
||||
size_t dst_size = (strlen(dest));
|
||||
uint32_t prefix = 0;
|
||||
/* Get the prefix length */
|
||||
size_t i = 0;
|
||||
for (i = strlen(dest); i > 0; --i) {
|
||||
if (dest[i] == '/') {
|
||||
prefix = atoi(&dest[i+1]);
|
||||
break;
|
||||
}
|
||||
if (dest[i] == ':' || dest[i] == '.') {
|
||||
i = strlen(dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t dst_size = (i+1);
|
||||
unsigned char dst_arr[dst_size];
|
||||
memset(dst_arr, 0, dst_size);
|
||||
memcpy(dst_arr, dest, i);
|
||||
unsigned char *dst = &dst_arr[0];
|
||||
uint32_t dst_flags = 0;
|
||||
|
||||
unsigned char *nxt = (unsigned char *)next;
|
||||
size_t nxt_size = (strlen(next));
|
||||
uint32_t nxt_flags = 0;
|
||||
|
||||
/* determine destination address */
|
||||
if (inet_pton(AF_INET6, dest, tmp_ipv6_dst)) {
|
||||
if (inet_pton(AF_INET6, (char*)dst, tmp_ipv6_dst)) {
|
||||
dst = tmp_ipv6_dst;
|
||||
dst_size = IN6ADDRSZ;
|
||||
}
|
||||
@ -106,16 +124,7 @@ static void _fib_add(const char *dest, const char *next, kernel_pid_t pid, uint3
|
||||
nxt_size = INADDRSZ;
|
||||
}
|
||||
|
||||
/* Set the prefix flag for a network */
|
||||
dst_flags |= FIB_FLAG_NET_PREFIX;
|
||||
for (size_t i = 0; i < dst_size; ++i) {
|
||||
if (dst[i] != 0) {
|
||||
/* and clear the bit if its not the default route */
|
||||
dst_flags = (dst_flags & ~FIB_FLAG_NET_PREFIX);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dst_flags |= (prefix << FIB_FLAG_NET_PREFIX_SHIFT);
|
||||
fib_add_entry(&gnrc_ipv6_fib_table, pid, dst, dst_size, dst_flags, nxt,
|
||||
nxt_size, nxt_flags, lifetime);
|
||||
}
|
||||
|
||||
@ -196,41 +196,47 @@ int universal_address_compare(universal_address_container_t *entry,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the index of the first trailing `0` (indicates a prefix) */
|
||||
int i = 0;
|
||||
for( i = entry->address_size-1; i > 0; --i) {
|
||||
if( entry->address[i] != 0 ) {
|
||||
/* compare up to fist distinct byte, pretty clumsy method for now */
|
||||
int idx = -1;
|
||||
bool test_all_zeros = true;
|
||||
for (size_t i = 0; i < entry->address_size; i++) {
|
||||
if ((idx == -1) && (entry->address[i] != addr[i])) {
|
||||
idx = i;
|
||||
}
|
||||
if (test_all_zeros) {
|
||||
test_all_zeros = (entry->address[i] == 0);
|
||||
}
|
||||
if ((idx != -1) && !test_all_zeros) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( memcmp(entry->address, addr, i) == 0 ) {
|
||||
/* if the bytes-1 equals we check the bits of the lowest byte */
|
||||
uint8_t bitmask = 0x00;
|
||||
uint8_t j = 0;
|
||||
/* get a bitmask for the trailing 0b */
|
||||
for( ; j < 8; ++j ) {
|
||||
if ( (entry->address[i] >> j) & 0x01 ) {
|
||||
bitmask = 0xff << j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( (entry->address[i] & bitmask) == (addr[i] & bitmask) ) {
|
||||
ret = entry->address[i] != addr[i];
|
||||
*addr_size_in_bits = (i<<3) + (8-j);
|
||||
if( ret == 0 ) {
|
||||
/* check if the remaining bits from addr are significant */
|
||||
i++;
|
||||
for(; i < entry->address_size; ++i) {
|
||||
if( addr[i] != 0 ) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if the address is all 0 its a default route address */
|
||||
if (test_all_zeros) {
|
||||
*addr_size_in_bits = 0;
|
||||
mutex_unlock(&mtx_access);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* if we have no distinct bytes the addresses are equal */
|
||||
if (idx == -1) {
|
||||
mutex_unlock(&mtx_access);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* count equal bits */
|
||||
uint8_t xor = entry->address[idx]^addr[idx];
|
||||
int8_t j = 7;
|
||||
for ( ; j > 0; --j) {
|
||||
if ((xor >> j) & 0x01) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the total number of matching bits */
|
||||
*addr_size_in_bits = (idx << 3) + j;
|
||||
ret = 1;
|
||||
|
||||
mutex_unlock(&mtx_access);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -35,8 +35,8 @@ static void _fill_FIB_unique(size_t entries)
|
||||
size_t add_buf_size = 16;
|
||||
char addr_dst[add_buf_size];
|
||||
char addr_nxt[add_buf_size];
|
||||
uint32_t addr_dst_flags = 0x77777777;
|
||||
uint32_t addr_nxt_flags = 0x77777777;
|
||||
uint32_t addr_dst_flags = 0x00777777;
|
||||
uint32_t addr_nxt_flags = 0x00777777;
|
||||
|
||||
for (size_t i = 0; i < entries; ++i) {
|
||||
/* construct "addresses" for the FIB */
|
||||
@ -59,8 +59,8 @@ static void _fill_FIB_multiple(size_t entries, size_t modulus)
|
||||
size_t add_buf_size = 16;
|
||||
char addr_dst[add_buf_size];
|
||||
char addr_nxt[add_buf_size];
|
||||
uint32_t addr_dst_flags = 0x33333333;
|
||||
uint32_t addr_nxt_flags = 0x33333333;
|
||||
uint32_t addr_dst_flags = 0x00333333;
|
||||
uint32_t addr_nxt_flags = 0x00333333;
|
||||
|
||||
for (size_t i = 0; i < entries; ++i) {
|
||||
/* construct "addresses" for the FIB */
|
||||
@ -73,6 +73,29 @@ static void _fill_FIB_multiple(size_t entries, size_t modulus)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief helper to determine the prefix bits
|
||||
*/
|
||||
static size_t _get_prefix_bits_num(char* addr, size_t addr_len)
|
||||
{
|
||||
/* Get the index of the first trailing `0` */
|
||||
int i = 0;
|
||||
for (i = addr_len-1; i > 0; --i) {
|
||||
if (addr[i] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* now we check the bits of the lowest byte */
|
||||
uint8_t j = 0;
|
||||
for ( ; j < 8; ++j) {
|
||||
if ((addr[i] >> j) & 0x01) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (i << 3) + (8 - j);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief filling the FIB with entries
|
||||
* It is expected to have 20 FIB entries and 40 used universal address entries
|
||||
@ -493,22 +516,27 @@ static void test_fib_14_exact_and_prefix_match(void)
|
||||
snprintf(addr_dst, add_buf_size, "Test addr12");
|
||||
snprintf(addr_nxt, add_buf_size, "Test address %02d", 12);
|
||||
|
||||
/* get the prefix in bits */
|
||||
uint32_t prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size - 1, (FIB_FLAG_NET_PREFIX | 0x12),
|
||||
add_buf_size - 1, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x12),
|
||||
(uint8_t *)addr_nxt, add_buf_size - 1,
|
||||
0x12, 100000);
|
||||
|
||||
snprintf(addr_dst, add_buf_size, "Test addr123");
|
||||
snprintf(addr_nxt, add_buf_size, "Test address %02d", 23);
|
||||
prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size - 1, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size - 1, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x123),
|
||||
(uint8_t *)addr_nxt, add_buf_size - 1,
|
||||
0x23, 100000);
|
||||
|
||||
snprintf(addr_dst, add_buf_size, "Test addr1234");
|
||||
snprintf(addr_nxt, add_buf_size, "Test address %02d", 34);
|
||||
prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size - 1, (FIB_FLAG_NET_PREFIX | 0x1234),
|
||||
add_buf_size - 1, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x1234),
|
||||
(uint8_t *)addr_nxt, add_buf_size - 1,
|
||||
0x34, 100000);
|
||||
|
||||
@ -612,14 +640,16 @@ static void test_fib_16_prefix_match(void)
|
||||
addr_dst[14] = (char)0x80; /* 1000 0000 */
|
||||
addr_lookup[14] = (char)0x87; /* 1000 0111 */
|
||||
|
||||
uint32_t prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size - 1, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size - 1, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x123),
|
||||
(uint8_t *)addr_nxt, add_buf_size - 1,
|
||||
0x23, 100000);
|
||||
|
||||
addr_dst[14] = (char)0x3c; /* 0011 1100 */
|
||||
prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size - 1, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size - 1, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x123),
|
||||
(uint8_t *)addr_nxt, add_buf_size - 1,
|
||||
0x23, 100000);
|
||||
|
||||
@ -634,10 +664,12 @@ static void test_fib_16_prefix_match(void)
|
||||
/* test fail */
|
||||
addr_dst[14] = (char)0x3c; /* 0011 1100 */
|
||||
addr_lookup[14] = (char)0x34; /* 0011 0100 */
|
||||
addr_lookup[13] += 1;
|
||||
add_buf_size = 16;
|
||||
prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size - 1, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size - 1, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x123),
|
||||
(uint8_t *)addr_nxt, add_buf_size -
|
||||
1, 0x23, 100000);
|
||||
|
||||
@ -651,6 +683,7 @@ static void test_fib_16_prefix_match(void)
|
||||
|
||||
/* test success (again) by adjusting the lsb */
|
||||
addr_lookup[14] = (char)0x3e; /* 0011 1110 */
|
||||
addr_lookup[13] -= 1;
|
||||
add_buf_size = 16;
|
||||
|
||||
memset(addr_nxt, 0, add_buf_size);
|
||||
@ -813,7 +846,7 @@ static void test_fib_19_default_gateway(void)
|
||||
|
||||
/* add a default gateway entry */
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size, 0x123,
|
||||
(uint8_t *)addr_nxt, add_buf_size, 0x23,
|
||||
100000);
|
||||
|
||||
@ -888,9 +921,10 @@ static void test_fib_20_replace_prefix(void)
|
||||
addr_lookup[i] = i+1;
|
||||
}
|
||||
|
||||
uint32_t prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
/* add a prefix entry */
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x123),
|
||||
(uint8_t *)addr_nxt, add_buf_size, 0x23,
|
||||
100000);
|
||||
|
||||
@ -918,9 +952,10 @@ static void test_fib_20_replace_prefix(void)
|
||||
addr_dst[i] = i+1;
|
||||
}
|
||||
|
||||
prefix_len = _get_prefix_bits_num(addr_dst, strlen(addr_dst));
|
||||
/* change the prefix entry */
|
||||
fib_add_entry(&test_fib_table, 42, (uint8_t *)addr_dst,
|
||||
add_buf_size, (FIB_FLAG_NET_PREFIX | 0x123),
|
||||
add_buf_size, ((prefix_len << FIB_FLAG_NET_PREFIX_SHIFT) | 0x123),
|
||||
(uint8_t *)addr_nxt, add_buf_size, 0x24,
|
||||
100000);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user