From 1bc9c3bfd262ae0cd269dc8602c01a90fc159bcb Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Mon, 16 Nov 2015 12:03:13 +0100 Subject: [PATCH 1/2] 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 --- sys/include/net/fib.h | 9 ++- .../routing/rpl/gnrc_rpl_control_messages.c | 13 +--- sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c | 6 +- sys/net/network_layer/fib/fib.c | 40 ++++++++---- sys/shell/commands/sc_fib.c | 37 ++++++----- sys/universal_address/universal_address.c | 62 ++++++++++--------- tests/unittests/tests-fib/tests-fib.c | 61 ++++++++++++++---- 7 files changed, 146 insertions(+), 82 deletions(-) diff --git a/sys/include/net/fib.h b/sys/include/net/fib.h index 9b23f8ea0..b25935466 100644 --- a/sys/include/net/fib.h +++ b/sys/include/net/fib.h @@ -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 diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c index 472ad78c1..1831565a5 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_control_messages.c @@ -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)), diff --git a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c index ec7570095..a22ba37fe 100644 --- a/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c +++ b/sys/net/gnrc/routing/rpl/gnrc_rpl_dodag.c @@ -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, diff --git a/sys/net/network_layer/fib/fib.c b/sys/net/network_layer/fib/fib.c index 989fde912..976f438d7 100644 --- a/sys/net/network_layer/fib/fib.c +++ b/sys/net/network_layer/fib/fib.c @@ -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); diff --git a/sys/shell/commands/sc_fib.c b/sys/shell/commands/sc_fib.c index 8a0dc9312..0779c5a56 100644 --- a/sys/shell/commands/sc_fib.c +++ b/sys/shell/commands/sc_fib.c @@ -33,7 +33,7 @@ #define INFO1_TXT "fibroute add via [dev ]" #define INFO2_TXT " [lifetime ]" -#define INFO3_TXT " - the destination address\n" \ +#define INFO3_TXT " - the destination address with optional prefix size, e.g. /116\n" \ " - the address of the next-hop towards the \n" \ " - 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); } diff --git a/sys/universal_address/universal_address.c b/sys/universal_address/universal_address.c index ef0e0cf17..207d8c50d 100644 --- a/sys/universal_address/universal_address.c +++ b/sys/universal_address/universal_address.c @@ -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; } diff --git a/tests/unittests/tests-fib/tests-fib.c b/tests/unittests/tests-fib/tests-fib.c index 9c68c28b1..c5ff06da9 100644 --- a/tests/unittests/tests-fib/tests-fib.c +++ b/tests/unittests/tests-fib/tests-fib.c @@ -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); From 38d5fc24768d6316732d7f5d713c3cb4fb58901f Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Wed, 30 Mar 2016 08:03:23 +0200 Subject: [PATCH 2/2] universal_address: replaced returned literals by defined constants * added and adjusted doxy for the new defined return values * stripped whitespaces for statements in the compare functions --- sys/include/universal_address.h | 31 +++++++++++++++++------ sys/universal_address/universal_address.c | 28 ++++++++++---------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/sys/include/universal_address.h b/sys/include/universal_address.h index 86525f4aa..50106b175 100644 --- a/sys/include/universal_address.h +++ b/sys/include/universal_address.h @@ -42,6 +42,17 @@ extern "C" { #define UNIVERSAL_ADDRESS_SIZE (IPV6_ADDR_BIT_LEN >> 3) #endif +/** @brief return value indicating the compared addresses are equal */ +#define UNIVERSAL_ADDRESS_EQUAL (0) + +/** @brief return value indicating the compared addresses match up to a certain prefix */ +#define UNIVERSAL_ADDRESS_MATCHING_PREFIX (1) + +/** @brief return value indicating all address bits of the entry are `0`. + * Its considered as default route address that matches any other prefix. + */ +#define UNIVERSAL_ADDRESS_IS_ALL_ZERO_ADDRESS (2) + /** * @brief The container descriptor used to identify a universal address entry */ @@ -69,7 +80,7 @@ void universal_address_reset(void); * @param[in] addr_size the number of bytes required for the address entry * * @return pointer to the universal_address_container_t containing the address on success - * NULL if the address could not be inserted + * @return NULL if the address could not be inserted */ universal_address_container_t *universal_address_add(uint8_t *addr, size_t addr_size); @@ -90,7 +101,7 @@ void universal_address_rem(universal_address_container_t *entry); * this value is overwritten with the actual size required * * @return addr if the address is copied to the addr destination - * NULL if the size is unsufficient for copy + * @return NULL if the size is unsufficient for copy */ uint8_t* universal_address_get_address(universal_address_container_t *entry, uint8_t *addr, size_t *addr_size); @@ -107,9 +118,12 @@ uint8_t* universal_address_get_address(universal_address_container_t *entry, * with the number of matching bits till the * first of trailing `0`s * - * @return 0 if the entries are equal - * 1 if the entry match to a certain prefix (trailing '0's in *entry) - * -ENOENT if the given adresses do not match + * @return UNIVERSAL_ADDRESS_EQUAL if the entries are equal + * @return UNIVERSAL_ADDRESS_MATCHING_PREFIX if the entry matches to a certain prefix + * (trailing '0's in @p entry) + * @return UNIVERSAL_ADDRESS_IS_ALL_ZERO_ADDRESS if the entry address is all `0`s + * and considered as default route + * @return -ENOENT if the given adresses do not match */ int universal_address_compare(universal_address_container_t *entry, uint8_t *addr, size_t *addr_size_in_bits); @@ -128,9 +142,10 @@ int universal_address_compare(universal_address_container_t *entry, * e.g. for an ipv6_addr_t it would be sizeof(ipv6_addr_t) * regardless if the stored prefix is < ::/128 * -* @return 0 if the entries are equal -* 1 if the entry match to a certain prefix (trailing '0's in *prefix) -* -ENOENT if the given adresses do not match +* @return UNIVERSAL_ADDRESS_EQUAL if the entries are equal +* @return UNIVERSAL_ADDRESS_MATCHING_PREFIX if the entry matches to a certain prefix +* (trailing '0's in @p prefix) +* @return -ENOENT if the given adresses do not match */ int universal_address_compare_prefix(universal_address_container_t *entry, uint8_t *prefix, size_t prefix_size_in_bits); diff --git a/sys/universal_address/universal_address.c b/sys/universal_address/universal_address.c index 207d8c50d..db9db126a 100644 --- a/sys/universal_address/universal_address.c +++ b/sys/universal_address/universal_address.c @@ -215,13 +215,13 @@ int universal_address_compare(universal_address_container_t *entry, if (test_all_zeros) { *addr_size_in_bits = 0; mutex_unlock(&mtx_access); - return 2; - } + return UNIVERSAL_ADDRESS_IS_ALL_ZERO_ADDRESS; + } /* if we have no distinct bytes the addresses are equal */ if (idx == -1) { mutex_unlock(&mtx_access); - return 0; + return UNIVERSAL_ADDRESS_EQUAL; } /* count equal bits */ @@ -235,7 +235,7 @@ int universal_address_compare(universal_address_container_t *entry, /* get the total number of matching bits */ *addr_size_in_bits = (idx << 3) + j; - ret = 1; + ret = UNIVERSAL_ADDRESS_MATCHING_PREFIX; mutex_unlock(&mtx_access); return ret; @@ -254,31 +254,31 @@ int universal_address_compare_prefix(universal_address_container_t *entry, /* Get the index of the first trailing `0` */ int i = 0; - for( i = entry->address_size-1; i >= 0; --i) { - if( prefix[i] != 0 ) { + for (i = entry->address_size-1; i >= 0; --i) { + if (prefix[i] != 0) { break; } } - if( memcmp(entry->address, prefix, i) == 0 ) { + if (memcmp(entry->address, prefix, i) == 0) { /* if the bytes-1 equals we check the bits of the lowest byte */ uint8_t bitmask = 0x00; /* get a bitmask for the trailing 0b */ - for( uint8_t j = 0; j < 8; ++j ) { - if ( (prefix[i] >> j) & 0x01 ) { + for (uint8_t j = 0; j < 8; ++j) { + if ((prefix[i] >> j) & 0x01) { bitmask = 0xff << j; break; } } - if( (entry->address[i] & bitmask) == (prefix[i] & bitmask) ) { + if ((entry->address[i] & bitmask) == (prefix[i] & bitmask)) { ret = entry->address[i] != prefix[i]; - if( ret == 0 ) { + if (ret == UNIVERSAL_ADDRESS_EQUAL) { /* check if the remaining bits from entry are significant */ i++; - for(; i < entry->address_size; ++i) { - if( entry->address[i] != 0 ) { - ret = 1; + for ( ; i < entry->address_size; ++i) { + if (entry->address[i] != 0) { + ret = UNIVERSAL_ADDRESS_MATCHING_PREFIX; break; } }