diff --git a/sys/net/include/fib/fib.h b/sys/net/include/fib/fib.h index 5089a77f0b95..86e4e4f57842 100644 --- a/sys/net/include/fib/fib.h +++ b/sys/net/include/fib/fib.h @@ -17,7 +17,7 @@ * @brief Types and functions for FIB * @author Martin Landsmann */ - + #ifndef _FIB_H #define _FIB_H @@ -26,11 +26,14 @@ extern "C" { #endif /** - * @brief RRP message content to mangle pointer and size to the address + * @brief Reactive Routing Protocol (RRP) message content to request/reply route discovery */ typedef struct rrp_address_msg_t { uint8_t *address; /**< The pointer to the address */ uint8_t address_size; /**< The address size */ + kernel_pid_t iface_id; /**< The interface used for the next-hop reply. + If it is KERNEL_PID_UNDEF, no next-hop has been found. */ + uint32_t lifetime; /**< The lifetime of this next-hop */ } rrp_address_msg_t; #define FIB_MSG_RRP_SIGNAL (0x99) /**< message type for RRP notifications */ @@ -42,7 +45,7 @@ typedef struct rrp_address_msg_t { #define FIB_ERROR_INSUFICCIENT_OUT_SIZE (-3) /**< error value for invalid output buffer size */ /** - * @brief initializes the datastructure for the entries + * @brief initializes all FIB entries with 0 */ void fib_init(void); diff --git a/sys/net/include/fib/fib_table.h b/sys/net/include/fib/fib_table.h index 2e6abba95542..0ca32a4d8eea 100644 --- a/sys/net/include/fib/fib_table.h +++ b/sys/net/include/fib/fib_table.h @@ -7,9 +7,8 @@ */ /** - * @defgroup fib forwarding information base * @brief forwarding table structs - * @ingroup net + * @ingroup net_fib * * @{ * diff --git a/sys/net/network_layer/fib/fib.c b/sys/net/network_layer/fib/fib.c index 18be209ebca5..7b63e8be35d1 100644 --- a/sys/net/network_layer/fib/fib.c +++ b/sys/net/network_layer/fib/fib.c @@ -75,10 +75,9 @@ static fib_entry_t fib_table[FIB_MAX_FIB_TABLE_ENTRIES]; * @param[in, out] entry_arr_size the number of entries provided by entry_arr (should be always 1) * this value is overwritten with the actual found number * - * @return FIB_SUCCESS if the search ended without errors - * on *entry_arr_size 0 no entry has been found matching the searched address - * on *entry_arr_size 1 an entry has been found - * FIB_ERROR if *entry_arr_size >1 indicating ambigious entries in the FIB + * @return FIB_SUCCESS if we found a next-hop prefix + * FIB_SUCCESS_EXACT_MATCH if we found the exact address next-hop + * FIB_ERROR_DESTINATION_UNREACHABLE if no fitting next-hop is available */ static int fib_find_entry(uint8_t *glob_dst, size_t glob_dst_size, fib_entry_t **entry_arr, size_t *entry_arr_size) @@ -90,7 +89,7 @@ static int fib_find_entry(uint8_t *glob_dst, size_t glob_dst_size, size_t count = 0; size_t prefix_size = 0; size_t match_size = glob_dst_size; - int ret = FIB_SUCCESS; + int ret = FIB_ERROR_DESTINATION_UNREACHABLE; fib_timestamp.seconds = now.seconds; fib_timestamp.microseconds = now.microseconds; @@ -119,6 +118,7 @@ static int fib_find_entry(uint8_t *glob_dst, size_t glob_dst_size, /* we try to find the most fitting prefix */ if( match_size > prefix_size ) { entry_arr[0] = &(fib_table[i]); + ret = FIB_SUCCESS; } } prefix_size = match_size; @@ -234,13 +234,17 @@ static int fib_remove(fib_entry_t *entry) * @param[in] glob_dst the destination address * @param[in] glob_dst_size the destination address size * + * @return FIB_SUCCESS on a new available entry, + * FIB_ERROR if no suiting entry is provided. */ -static void fib_signal_rrp(uint8_t *glob_dst, size_t glob_dst_size) +static int fib_signal_rrp(uint8_t *glob_dst, size_t glob_dst_size) { msg_t msg, reply; rrp_address_msg_t content; + rrp_address_msg_t* rrp_reply; content.address = glob_dst; content.address_size = glob_dst_size; + int ret = FIB_ERROR; msg.type = FIB_MSG_RRP_SIGNAL; msg.content.ptr = (void *)&content; @@ -251,14 +255,35 @@ static void fib_signal_rrp(uint8_t *glob_dst, size_t glob_dst_size) msg.content.ptr, (int)i, (int)notify_rrp[i]); /* the receiver, i.e. the RRP, MUST copy the content value - * using the provided pointer after the msg_reply() call + * using the provided pointer after replying it * will lead to errors - * (I could force the copy by providing a pointer to a local copy in this context) */ msg_send_receive(&msg, &reply, notify_rrp[i]); DEBUG("[fib_signal_rrp] got reply."); + rrp_reply = ((rrp_address_msg_t*)(reply.content.ptr)); + + if( rrp_reply->iface_id != KERNEL_PID_UNDEF && rrp_reply->lifetime != 0 ) { + /* we try to create a new entry as no fitting entry has been found in advance */ + int err = fib_create_entry(rrp_reply->iface_id, \ + glob_dst, \ + glob_dst_size, \ + rrp_reply->address, \ + rrp_reply->address_size, \ + rrp_reply->lifetime); + if( err == FIB_ERROR ) { + DEBUG("[fib_signal_rrp] the entry could not be created."); + } else { + ret = FIB_SUCCESS; + } + } else { + DEBUG("[fib_signal_rrp] No route has been found."); + } + /* reply the RRP that we have processed the message */ + msg_reply(&reply, &reply); } } + + return ret; } int fib_table_add_entry(kernel_pid_t iface_id, uint8_t *glob_dst, size_t glob_dst_size, @@ -338,14 +363,16 @@ int fib_get_next_hop(uint8_t *glob_dst, size_t glob_dst_size, kernel_pid_t *ifac int ret = fib_find_entry(glob_dst, glob_dst_size, &(entry[0]), &count); - if (ret == FIB_SUCCESS || ret == FIB_SUCCESS_EXACT_MATCH) { - - if (count == 0) { - /* notify all RRPs for route discovery if available */ - fib_signal_rrp(glob_dst, glob_dst_size); - mutex_unlock(&mtx_access); - return FIB_ERROR_DESTINATION_UNREACHABLE; + if ( !(ret == FIB_SUCCESS || ret == FIB_SUCCESS_EXACT_MATCH) ) { + /* notify all RRPs for route discovery if available */ + if( fib_signal_rrp(glob_dst, glob_dst_size) == FIB_SUCCESS ) { + count = 1; + /* now lets see if the RRPs have found a valid next-hop */ + ret = fib_find_entry(glob_dst, glob_dst_size, &(entry[0]), &count); } + } + + if (ret == FIB_SUCCESS || ret == FIB_SUCCESS_EXACT_MATCH) { ret = universal_address_get_address(entry[0]->next_hop, next_hop, next_hop_size); @@ -353,9 +380,9 @@ int fib_get_next_hop(uint8_t *glob_dst, size_t glob_dst_size, kernel_pid_t *ifac mutex_unlock(&mtx_access); return FIB_ERROR_INSUFICCIENT_OUT_SIZE; } - } - else { - DEBUG("[fib_get_next_hop] ambigious entries in FIB, this should not happen!"); + } else { + mutex_unlock(&mtx_access); + return FIB_ERROR_DESTINATION_UNREACHABLE; } *iface_id = entry[0]->iface_id; diff --git a/tests/fib/main.c b/tests/fib/main.c index da5127690132..401160e78f6f 100644 --- a/tests/fib/main.c +++ b/tests/fib/main.c @@ -34,8 +34,10 @@ void *rrp_stub_thread(void *arg) { (void)arg; fib_register_rrp(); - msg_t rcv; + msg_t rcv, reply; + rrp_address_msg_t rply_msg; rrp_address_msg_t* msg; + unsigned char nxt_hop[] = "RRP next-hop 01"; msg_receive(&rcv); msg = (rrp_address_msg_t*)(rcv.content.ptr); @@ -47,8 +49,18 @@ void *rrp_stub_thread(void *arg) printf("%c", msg->address[i]); }puts(""); - msg_reply(&rcv, &rcv); + printf("[rrp_sub_thread] found next-hop: %s\n", (char *)nxt_hop); + rply_msg.address = nxt_hop; + rply_msg.address_size = strlen((char*)nxt_hop); + rply_msg.lifetime = 123400; + rply_msg.iface_id = 42; + reply.content.ptr = (void*)&rply_msg; + printf("[rrp_sub_thread] reply, and wait for FIB process the next-hop.\n"); + msg_reply(&rcv, &reply); + msg_receive(&rcv); + + printf("[rrp_sub_thread] tear down.\n"); return NULL; } @@ -447,8 +459,8 @@ void TEST_13(void){ /* * @brief get next hop for unknown destination call RRP handler stub -* It is expected to get no next hop and receive FIB_ERROR_DESTINATION_UNREACHABLE * It is expected to inform RRP handler thread +* It is expected to get a next-hop and receive FIB_SUCCESS */ void TEST_14(void){ puts("[TEST_14] signal RRP."); @@ -461,7 +473,7 @@ void TEST_14(void){ CREATE_STACKTEST, rrp_stub_thread, "RRP", "RRP"); - size_t entries = 20; + size_t entries = 19; _fill_FIB_multiple(entries, 11); /* // uncomment for tracing @@ -474,7 +486,7 @@ void TEST_14(void){ int ret = fib_get_next_hop( (uint8_t*)addr_dst, add_buf_size-1, &iface_id, (uint8_t*)addr_nxt, &add_buf_size ); printf("[TEST_14] ret: %d, is ", ret); - (ret == FIB_ERROR_DESTINATION_UNREACHABLE)?puts("FIB_ERROR_DESTINATION_UNREACHABLE as expected"):puts("unexpected value!"); + (ret == FIB_SUCCESS)?puts("FIB_SUCCESS as expected"):puts("unexpected value!"); fib_deinit(); puts("");