From b20fad3e78b8d19e67e477b747bb2a6d77387e9a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sat, 22 Feb 2014 22:55:33 +0100 Subject: [PATCH 01/48] add olsr2 --- Makefile.dep | 18 ++ sys/Makefile | 3 + sys/net/include/olsr2/olsr2.h | 21 ++ sys/net/routing/olsr2/Makefile | 3 + sys/net/routing/olsr2/constants.h | 42 ++++ sys/net/routing/olsr2/debug.h | 64 +++++ sys/net/routing/olsr2/list.c | 149 ++++++++++++ sys/net/routing/olsr2/list.h | 50 ++++ sys/net/routing/olsr2/main.c | 182 ++++++++++++++ sys/net/routing/olsr2/nhdp.c | 113 +++++++++ sys/net/routing/olsr2/nhdp.h | 13 + sys/net/routing/olsr2/node.c | 148 ++++++++++++ sys/net/routing/olsr2/node.h | 85 +++++++ sys/net/routing/olsr2/olsr.c | 389 ++++++++++++++++++++++++++++++ sys/net/routing/olsr2/olsr.h | 19 ++ sys/net/routing/olsr2/olsr_init.c | 201 +++++++++++++++ sys/net/routing/olsr2/reader.c | 297 +++++++++++++++++++++++ sys/net/routing/olsr2/reader.h | 11 + sys/net/routing/olsr2/routing.c | 159 ++++++++++++ sys/net/routing/olsr2/routing.h | 22 ++ sys/net/routing/olsr2/util.c | 84 +++++++ sys/net/routing/olsr2/util.h | 21 ++ sys/net/routing/olsr2/writer.c | 269 +++++++++++++++++++++ sys/net/routing/olsr2/writer.h | 19 ++ 24 files changed, 2382 insertions(+) create mode 100644 sys/net/include/olsr2/olsr2.h create mode 100644 sys/net/routing/olsr2/Makefile create mode 100644 sys/net/routing/olsr2/constants.h create mode 100644 sys/net/routing/olsr2/debug.h create mode 100644 sys/net/routing/olsr2/list.c create mode 100644 sys/net/routing/olsr2/list.h create mode 100644 sys/net/routing/olsr2/main.c create mode 100644 sys/net/routing/olsr2/nhdp.c create mode 100644 sys/net/routing/olsr2/nhdp.h create mode 100644 sys/net/routing/olsr2/node.c create mode 100644 sys/net/routing/olsr2/node.h create mode 100644 sys/net/routing/olsr2/olsr.c create mode 100644 sys/net/routing/olsr2/olsr.h create mode 100644 sys/net/routing/olsr2/olsr_init.c create mode 100644 sys/net/routing/olsr2/reader.c create mode 100644 sys/net/routing/olsr2/reader.h create mode 100644 sys/net/routing/olsr2/routing.c create mode 100644 sys/net/routing/olsr2/routing.h create mode 100644 sys/net/routing/olsr2/util.c create mode 100644 sys/net/routing/olsr2/util.h create mode 100644 sys/net/routing/olsr2/writer.c create mode 100644 sys/net/routing/olsr2/writer.h diff --git a/Makefile.dep b/Makefile.dep index d919119e4ece..23bafe87dc7c 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -2,6 +2,24 @@ ifneq (,$(filter libcoap,$(USEPKG))) USEMODULE += pnet endif +ifneq (,$(filter olsr2,$(USEMODULE))) + ifeq (,$(filter vtimer,$(USEMODULE))) + USEMODULE += vtimer + endif + ifeq (,$(filter destiny,$(USEMODULE))) + USEMODULE += destiny + endif + ifeq (,$(filter sixlowpan,$(USEMODULE))) + USEMODULE += sixlowpan + endif + ifeq (,$(filter oonf_common,$(USEMODULE))) + USEMODULE += oonf_common + endif + ifeq (,$(filter oonf_rfc5444,$(USEMODULE))) + USEMODULE += oonf_rfc5444 + endif +endif + ifneq (,$(filter pnet,$(USEMODULE))) USEMODULE += posix USEMODULE += socket_base diff --git a/sys/Makefile b/sys/Makefile index effe97398c7b..8b7985464dfc 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -80,6 +80,9 @@ endif ifneq (,$(filter rpl,$(USEMODULE))) DIRS += net/routing/rpl endif +ifneq (,$(filter olsr2,$(USEMODULE))) + DIRS += net/routing/olsr2 +endif ifneq (,$(filter routing,$(USEMODULE))) DIRS += net/routing endif diff --git a/sys/net/include/olsr2/olsr2.h b/sys/net/include/olsr2/olsr2.h new file mode 100644 index 000000000000..8a3ca3558f60 --- /dev/null +++ b/sys/net/include/olsr2/olsr2.h @@ -0,0 +1,21 @@ +#include "sixlowpan/types.h" + +/** + * @brief Start routing using olsr2 + * This initializes and starts all neccecary + * background threads for OLSRv2 routing, control + * messages will be send and received on MANET_PORT + */ +void olsr_init(void); + +/** + * @brief prints all known routers of the MANET + */ +void print_topology_set(void); + +#ifdef ENABLE_NAME +/** + * @brief get the IP address of a MANET router from it's hostname + */ +ipv6_addr_t* get_ip_by_name(char* name); +#endif diff --git a/sys/net/routing/olsr2/Makefile b/sys/net/routing/olsr2/Makefile new file mode 100644 index 000000000000..b2513e8c285c --- /dev/null +++ b/sys/net/routing/olsr2/Makefile @@ -0,0 +1,3 @@ +MODULE:= $(shell basename $(CURDIR)) + +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h new file mode 100644 index 000000000000..7362f4136302 --- /dev/null +++ b/sys/net/routing/olsr2/constants.h @@ -0,0 +1,42 @@ +#ifndef CONSTANTS_H_ +#define CONSTANTS_H_ + +/* RFC5498 */ +#define MANET_PORT 269 + +/* in seconds */ +#define HELLO_REFRESH_INTERVAL 2 +#define TC_REFRESH_INTERVAL 5 +#define HOLD_TIME (3 * TC_REFRESH_INTERVAL) + +#define TC_HOP_LIMIT 16 + +#define HYST_SCALING 0.4 +#define HYST_LOW 0.3 +#define HYST_HIGH 0.8 + +/* 1s */ +#define MAX_JITTER 1000000 + +#define FLOODING_MPR_SELECTOR 1 +#define ROUTING_MPR_SELECTOR 2 + +#define RFC5444_TLV_NODE_NAME 42 + +/* NHDP message TLV array index */ +enum { + IDX_TLV_ITIME, /* Interval time */ + IDX_TLV_VTIME, /* validity time */ + IDX_TLV_NODE_NAME, /* name of the node */ +}; + +/* NHDP address TLV array index */ +enum { + IDX_ADDRTLV_LOCAL_IF, /* is local if */ + IDX_ADDRTLV_LINK_STATUS, /* link status TODO */ + IDX_ADDRTLV_MPR, /* neighbor selected as mpr */ + IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ + IDX_ADDRTLV_METRIC, +}; + +#endif /* CONSTANTS_H_ */ diff --git a/sys/net/routing/olsr2/debug.h b/sys/net/routing/olsr2/debug.h new file mode 100644 index 000000000000..01e9273b036f --- /dev/null +++ b/sys/net/routing/olsr2/debug.h @@ -0,0 +1,64 @@ +#ifndef DEBUG_H_ +#define DEBUG_H_ + +#ifdef ENABLE_DEBUG_OLSR +#ifndef RIOT +#include +#include +#endif /* not RIOT */ +#include +#include +#include "common/netaddr.h" + +struct netaddr_str nbuf[4]; +int debug_ticks; + +#define DEBUG_TICK debug_ticks++ + +#ifdef RIOT +#define DEBUG(fmt, ...) printf((fmt "\n"), ##__VA_ARGS__) +#define TRACE_FUN(fmt, ...) printf(("%s(" fmt ")\n"), __FUNCTION__, ##__VA_ARGS__) + +#else + +time_t _t_tmr; +char _t_buf[9]; +#define DEBUG(fmt, ...) { \ + _t_tmr = time_now(); \ + strftime(_t_buf, sizeof _t_buf, "%H:%M:%S", localtime(&_t_tmr)); \ + printf(("[%d, %s] " fmt "\n"), debug_ticks, _t_buf, ##__VA_ARGS__); \ + } + +#define TRACE_FUN(fmt, ...) { \ + _t_tmr = time_now(); \ + strftime(_t_buf, sizeof _t_buf, "%H:%M:%S", localtime(&_t_tmr)); \ + printf(("[%d, %s] %s(" fmt ")\n"), debug_ticks, _t_buf, __FUNCTION__, ##__VA_ARGS__); \ + } + +static inline void print_trace(void) { + void *array[10]; + size_t size; + char **strings; + size_t i; + + size = backtrace(array, 10); + strings = backtrace_symbols(array, size); + + printf("Obtained %zd stack frames.\n", size); + + for (i = 0; i < size; i++) + printf ("%s\n", strings[i]); + + free(strings); +} + +#endif /* not RIOT */ + +#else /* no ENABLE_DEBUG_OLSR */ + +#define DEBUG(...) +#define DEBUG_TICK +#define TRACE_FUN(...) + +#endif +#endif diff --git a/sys/net/routing/olsr2/list.c b/sys/net/routing/olsr2/list.c new file mode 100644 index 000000000000..98bf9c5d27d3 --- /dev/null +++ b/sys/net/routing/olsr2/list.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include +#include + +#include "list.h" + +struct simple_list_elem { + struct simple_list_elem* next; +}; + +void* __Simple_list_add_tail(struct simple_list_elem** head, void* mem) { + struct simple_list_elem* _head = *head; + + /* check out-of-memory condition */ + if (mem == NULL) + return NULL; + + if (!_head) { + *head = mem; + return *head; + } + + while (_head->next) { + _head = _head->next; + } + + _head = _head->next = mem; + return _head; +} + +void* __Simple_list_add_head(struct simple_list_elem** head, void* mem) { + struct simple_list_elem* _head = *head; + + /* check out-of-memory condition */ + if (mem == NULL) + return NULL; + + *head = mem; + (*head)->next = _head; + + return *head; +} + +void* __Simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) { + struct simple_list_elem* _head = *head; + struct simple_list_elem* prev = 0; + + /* check out-of-memory condition */ + if (mem == NULL) + return NULL; + + if (!_head) { + *head = mem; + return *head; + } + + while(_head) { + int* buff = (void*) _head + offset; + if (*buff > needle) { + if (prev) { + prev->next = mem; + prev->next->next = _head; + return prev->next; + } + + prev = mem; + prev->next = _head; + *head = prev; + return prev; + } + prev = _head; + _head = _head->next; + } + + _head = prev->next = mem; + return _head; +} + +void* __Simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) { + while (head) { + void** buff = (void*) head + offset; + + if (size == 0 && *buff == needle) + return head; + if (size > 0 && memcmp(*buff, needle, size) == 0) + return head; + head = head->next; + } + + return 0; +} + +void* __Simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) { + while (head) { + void** buff = (void*) head + offset; + + if (compare(*buff, needle) == 0) + return head; + + head = head->next; + } + + return 0; +} + +void* __Simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) { + struct simple_list_elem* _head = *head; + struct simple_list_elem* prev = 0; + + while (_head && _head != node) { + prev = _head; + _head = _head->next; + } + + /* not found */ + if (_head != node) + return NULL; + + /* remove head */ + if (!prev) + *head = _head->next; + else + prev->next = node->next; + + if (keep) + return node; + + free(node); + return (void*) 1; +} + +void __Simple_list_clear(struct simple_list_elem** head) { + struct simple_list_elem *tmp, *_head = *head; + + while (_head != NULL) { + tmp = _head; + _head = _head->next; + free(tmp); + } + + *head = NULL; +} diff --git a/sys/net/routing/olsr2/list.h b/sys/net/routing/olsr2/list.h new file mode 100644 index 000000000000..e74efc460058 --- /dev/null +++ b/sys/net/routing/olsr2/list.h @@ -0,0 +1,50 @@ +#ifndef SIMPLE_LIST_H_ +#define SIMPLE_LIST_H_ +#include +#include + +struct simple_list_elem; + +#define simple_list_add_head(head) __Simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) +#define simple_list_set_head(head, node) __Simple_list_add_head((struct simple_list_elem**) head, node) +#define simple_list_add_tail(head) __Simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) +#define simple_list_set_tail(head, node) __Simple_list_add_tail((struct simple_list_elem**) (head), (node)) +#define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ + __Simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) +#define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ + __Simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) +#define simple_list_find(head, value) (head) == 0 ? NULL : \ + __Simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) +#define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ + __Simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) +#define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ + __Simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) +#define simple_list_remove(head, node) __Simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) +#define simple_list_extract(head, node) __Simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) +#define simple_list_clear(head) __Simple_list_clear((struct simple_list_elem**) (head)) + +#define simple_list_for_each(head, node) for ((node) = (head); (node); (node) = (node)->next) +#define simple_list_for_each_safe(head, node, prev, skipped) \ + for ((skipped) = 0, (prev) = 0, (node) = (head);\ + (node); \ + (prev) = ((skipped) ? (prev) : (node)), \ + (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) +#define simple_list_for_each_remove(head, node, prev) do { \ + if (!prev) { \ + (skipped) = 1; \ + *(head) = (*(head))->next; \ + } else \ + (prev)->next = (node)->next; \ + free(node); \ + (node) = (prev) ? (prev) : *(head); \ + } while (0) + +void* __Simple_list_add_head(struct simple_list_elem** head, void* mem); +void* __Simple_list_add_tail(struct simple_list_elem** head, void* mem); +void* __Simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset); +void* __Simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size); +void* __Simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)); +void* __Simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep); +void __Simple_list_clear(struct simple_list_elem** head); + +#endif /* SIMPLE_LIST_H_ */ diff --git a/sys/net/routing/olsr2/main.c b/sys/net/routing/olsr2/main.c new file mode 100644 index 000000000000..d40436410447 --- /dev/null +++ b/sys/net/routing/olsr2/main.c @@ -0,0 +1,182 @@ +/*********************************************** + * This file is for easy testing on Linux only * + ***********************************************/ + +#ifndef RIOT +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include "rfc5444/rfc5444_writer.h" + +#include "constants.h" +#include "debug.h" +#include "node.h" +#include "olsr.h" +#include "reader.h" +#include "writer.h" + +int sockfd; +struct sockaddr_in servaddr; + +sigset_t block_io; + +struct ip_lite { + struct netaddr src; + size_t length; +}; + +void write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), + struct rfc5444_writer_target *iface __attribute__((unused)), + void *buffer, size_t length) { + + DEBUG("write_packet(%zd bytes)", length); + + struct ip_lite* new_buffer = malloc(sizeof(struct ip_lite) + length); + memcpy(new_buffer + 1, buffer, length); + memcpy(&new_buffer->src, get_local_addr(), sizeof(struct netaddr)); + new_buffer->length = length; + + sendto(sockfd, new_buffer, sizeof(struct ip_lite) + new_buffer->length, 0, + (struct sockaddr*) &servaddr, sizeof(servaddr)); +} + +void enable_receive(void) { + sigprocmask (SIG_UNBLOCK, &block_io, NULL); +} + +void disable_receive(void) { + sigprocmask (SIG_BLOCK, &block_io, NULL); +} + +void sigio_handler(int sig __attribute__((unused))) { + char buffer[1500]; + struct sockaddr_storage sender; + socklen_t sendsize = sizeof(sender); + + disable_receive(); + + while (recvfrom(sockfd, &buffer, sizeof buffer, 0, (struct sockaddr*)&sender, &sendsize) > 0) { + struct ip_lite* header = (struct ip_lite*) &buffer; + + reader_handle_packet(header + 1, header->length, &header->src); + } + enable_receive(); +} + +void init_socket(in_addr_t addr, int port) { + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + + memset(&servaddr, 0, sizeof servaddr); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = addr; + servaddr.sin_port = htons(port); +} + +int enable_asynch(int sock) { + int flags; + struct sigaction sa; + + flags = fcntl(sock, F_GETFL); + fcntl(sock, F_SETFL, flags | O_ASYNC | O_NONBLOCK); + + sa.sa_flags = 0; + sa.sa_handler = sigio_handler; + sigemptyset(&sa.sa_mask); + + if (sigaction(SIGIO, &sa, NULL)) + return -1; + + if (fcntl(sock, F_SETOWN, getpid()) < 0) + return -1; + + if (fcntl(sock, F_SETSIG, SIGIO) < 0) + return -1; + + return 0; +} + +int main(int argc, char** argv) { + const char* this_ip; + + if (argc != 4) { + printf("usage: %s \n", argv[0]); + return -1; + } + + this_ip = argv[3]; + + init_socket(inet_addr(argv[1]), atoi(argv[2])); + + /* set timeout for name probing */ + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + DEBUG("probing for name…"); + /* send HELLO */ + sendto(sockfd, this_ip, strlen(this_ip), 0, (struct sockaddr*) &servaddr, sizeof(servaddr)); + /* get our name */ + char this_name[32]; + ssize_t size = recvfrom(sockfd, this_name, sizeof this_name, 0, 0, 0); + if (size < 0) { + strcpy(this_name, "(null)"); + } else + this_name[size] = 0; + +#ifdef ENABLE_NAME + local_name = strdup(this_name); +#endif + + node_init(); + + get_local_addr()->_type = AF_INET6; + get_local_addr()->_prefix_len = 128; + inet_pton(AF_INET6, this_ip, get_local_addr()->_addr); + + DEBUG("This is node %s with IP %s", + local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); + + reader_init(); + writer_init(write_packet); + + /* Initialize the signal mask. */ + sigemptyset (&block_io); + sigaddset (&block_io, SIGIO); + + enable_asynch(sockfd); + + bool dont_skip_tc = true; + while (1) { + /* TC messages have a longer interval */ + dont_skip_tc = !dont_skip_tc; + sleep_s(HELLO_REFRESH_INTERVAL); + + disable_receive(); + + // print_neighbors(); + print_topology_set(); + print_routing_graph(); + + writer_send_hello(); + if (dont_skip_tc) + writer_send_tc(); + + DEBUG_TICK; + enable_receive(); + } + + reader_cleanup(); + writer_cleanup(); + + return 0; +} + +#endif /* no RIOT */ diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c new file mode 100644 index 000000000000..befd266cb6b4 --- /dev/null +++ b/sys/net/routing/olsr2/nhdp.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include + +#include "nhdp.h" +#include "util.h" +#include "debug.h" +#include "node.h" +#include "routing.h" +#include "constants.h" + +#include "common/avl.h" + +static struct olsr_node* _node_replace(struct olsr_node* old_n) { + struct olsr_node* new_n = calloc(1, sizeof (struct nhdp_node)); + + if (new_n == NULL) + return old_n; + + /* remove things that held a pointer to this */ + avl_remove(get_olsr_head(), &old_n->node); + bool _free_node = remove_free_node(old_n); + + memcpy(new_n, old_n, sizeof(struct olsr_node)); + memset(&new_n->node, 0, sizeof(new_n->node)); // just to be sure + + new_n->type = NODE_TYPE_NHDP; + new_n->node.key = new_n->addr; + avl_insert(get_olsr_head(), &new_n->node); + + free(old_n); + + if (_free_node) + add_free_node(new_n); + + return new_n; +} + +struct olsr_node* add_neighbor(struct netaddr* addr, uint8_t vtime, char* name) { + struct olsr_node* n = get_node(addr); + + if (n == NULL) { + DEBUG("\tadding new neighbor: %s", netaddr_to_str_s(&nbuf[0], addr)); + n = calloc(1, sizeof(struct nhdp_node)); + + if (n == NULL) + return NULL; + + n->addr = netaddr_dup(addr); + + if (n->addr == NULL) { + free(n); + return NULL; + } + + n->type = NODE_TYPE_NHDP; + n->distance = 1; + h1_deriv(n)->link_quality = HYST_SCALING; + n->pending = 1; +#ifdef ENABLE_NAME + if (name != NULL) + n->name = strdup(name); +#endif + + n->node.key = n->addr; + avl_insert(get_olsr_head(), &n->node); + } else if (n->type != NODE_TYPE_NHDP) { + DEBUG("\tconverting olsr node %s to nhdp node", + netaddr_to_str_s(&nbuf[0], n->addr)); + n = _node_replace(n); + } + + /* add_other_route would otherwise not update expires */ + if (n->next_addr == NULL) + n->expires = time_now() + vtime; + + add_other_route(n, get_local_addr(), vtime); + + return n; +} + +#ifdef ENABLE_DEBUG_OLSR +void print_neighbors(void) { + struct olsr_node* node; + + DEBUG("1-hop neighbors:"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance == 1 && node->type == NODE_TYPE_NHDP) + DEBUG("\tneighbor: %s (%s) (mpr for %d nodes)", + node->name, + netaddr_to_str_s(&nbuf[0], node->addr), + h1_deriv(node)->mpr_neigh); + } + + DEBUG("2-hop neighbors:"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance == 2) + DEBUG("\t%s (%s) -> %s -> %s (%s)", + node->name, netaddr_to_str_s(&nbuf[0], node->addr), + netaddr_to_str_s(&nbuf[1], node->next_addr), + local_name, + netaddr_to_str_s(&nbuf[2], get_local_addr())); + } +} +#else +void print_neighbors(void) {} +#endif diff --git a/sys/net/routing/olsr2/nhdp.h b/sys/net/routing/olsr2/nhdp.h new file mode 100644 index 000000000000..7e5dd33a7a20 --- /dev/null +++ b/sys/net/routing/olsr2/nhdp.h @@ -0,0 +1,13 @@ +#ifndef NHDP_H_ +#define NHDP_H_ + +#include "common/avl.h" +#include "common/netaddr.h" + +#include "node.h" + +struct olsr_node* add_neighbor(struct netaddr* addr, uint8_t vtime, char* name); + +void print_neighbors(void); + +#endif /* NHDP_H_ */ diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c new file mode 100644 index 000000000000..b99473a5ab65 --- /dev/null +++ b/sys/net/routing/olsr2/node.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include + +#include "node.h" +#include "list.h" +#include "debug.h" + +#include "common/netaddr.h" + +static struct netaddr_rc local_addr; +static struct avl_tree olsr_head; + +#ifdef ENABLE_NAME +char* local_name; +#endif + +static void _decrease_mpr_neigh(struct olsr_node* node) { + /* update MPR information */ + if (node->distance == 2) { + struct nhdp_node* n1 = h1_deriv(get_node(node->last_addr)); + if (n1 != NULL && n1->mpr_neigh > 0) + n1->mpr_neigh--; + } +} + +static int _addr_cmp(const void* a, const void* b) { + return memcmp(a, b, NETADDR_MAX_LENGTH); +} + +int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b) { + return netaddr_cmp(a->addr, b->addr); +} + +void node_init(void) { + local_addr._refs = 1; + avl_init(get_olsr_head(), _addr_cmp, false); +} + +struct netaddr* get_local_addr(void) { + return (struct netaddr*) &local_addr; +} + +struct avl_tree* get_olsr_head(void) { + return &olsr_head; +} + +struct olsr_node* get_node(struct netaddr* addr) { + struct olsr_node *n; // for typeof + if (addr == NULL) + return NULL; + return avl_find_element(get_olsr_head(), addr, n, node); +} + +void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t vtime) { + /* make sure the route is not already the default route */ + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { + node->expires = time_now() + vtime; + return; + } + + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + if (route != NULL) { + route->expires = time_now() + vtime; + return; + } + + route = simple_list_add_head(&node->other_routes); + + if (route == NULL) { + printf("ERROR: out of memory in %s\n", __FUNCTION__); + return; + } + + route->last_addr = netaddr_reuse(last_addr); + route->expires = time_now() + vtime; +} + +void remove_default_node(struct olsr_node* node) { + if (node->last_addr) { + _decrease_mpr_neigh(node); + node->last_addr = netaddr_free(node->last_addr); + } + + node->next_addr = netaddr_free(node->next_addr); +} + +/* + * moves the default route of node to other_routes + */ +void push_default_route(struct olsr_node* node) { + struct netaddr* last_addr = node->last_addr; + + if (node->last_addr == NULL) + return; + + _decrease_mpr_neigh(node); + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + + if (route != NULL) { + node->last_addr = netaddr_free(node->last_addr); + return; + } + + route = simple_list_add_head(&node->other_routes); + + if (route == NULL) { + printf("ERROR: out of memory in %s\n", __FUNCTION__); + return; + } + + route->expires = node->expires; + route->last_addr = node->last_addr; + node->last_addr = NULL; +} + +void pop_other_route(struct olsr_node* node, struct netaddr* last_addr) { + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + if (netaddr_cmp(route->last_addr, last_addr)) + continue; + + node->last_addr = route->last_addr; + node->expires = route->expires; + simple_list_for_each_remove(&node->other_routes, route, prev); + break; + } +} + +void remove_other_route(struct olsr_node* node, struct netaddr* last_addr) { + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + if (netaddr_cmp(route->last_addr, last_addr)) + continue; + + netaddr_free(route->last_addr); + simple_list_for_each_remove(&node->other_routes, route, prev); + break; + } +} diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h new file mode 100644 index 000000000000..a3ff9891c236 --- /dev/null +++ b/sys/net/routing/olsr2/node.h @@ -0,0 +1,85 @@ +#ifndef NODE_H_ +#define NODE_H_ + +#include "common/avl.h" +#include "common/netaddr.h" + +#include "util.h" +#include "debug.h" + +#ifdef ENABLE_NAME +extern char* local_name; +#endif + +/* if a connection is lost, the loss will be reported LOST_ITER_MAX times in HELLO and TC messages. */ +#define LOST_ITER_MAX (1 << 3) + +enum { + NODE_TYPE_OLSR, + NODE_TYPE_NHDP +}; + +/* simple list to store alternative routes */ +struct alt_route { + struct alt_route* next; + + struct netaddr* last_addr; + time_t expires; +}; + +struct olsr_node { + struct avl_node node; /* for routing table Information Base */ + + struct netaddr* addr; /* node address */ + struct netaddr* next_addr; /* neighbor addr to send packets to for this node*/ + struct netaddr* last_addr; /* node that announced this node */ + struct alt_route* other_routes; /* other possible last_addrs */ + + time_t expires; /* time when this tuple is invalid */ + uint16_t seq_no; /* last seq_no from last_addr */ + uint8_t distance; /* hops between us and the node */ + + uint8_t type : 1; /* node type */ + uint8_t mpr_selector: 2; /* whether the node selected us as a MPR - only 1-hop */ + uint8_t pending : 3; /* whether the link can already be used - only 1-hop */ + uint8_t lost : 4; /* [4 bit] if set, the node will be annouced as lost - only 1-hop */ + +#ifdef ENABLE_NAME + char* name; /* node name from graph.gv */ +#endif +}; + +struct nhdp_node { + struct olsr_node super; + + /* number of 2-hop neighbors reached through this node aka if this value is > 0, it's a MPR */ + uint8_t mpr_neigh; + + /* average packet loss, decides if it should be used as 1-hop neigh */ + float link_quality; +}; + +static inline struct olsr_node* h1_super(struct nhdp_node* n) { return (struct olsr_node*) n; } +static inline struct nhdp_node* h1_deriv(struct olsr_node* n) { + if (n == NULL) + return 0; + + if (n->type != NODE_TYPE_NHDP) + return 0; + + return (struct nhdp_node*) n; +} + +void node_init(void); +struct netaddr* get_local_addr(void); +struct avl_tree* get_olsr_head(void); +int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b); +struct olsr_node* get_node(struct netaddr* addr); + +void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t vtime); +void remove_other_route(struct olsr_node* node, struct netaddr* last_addr); +void remove_default_node(struct olsr_node* node); +void push_default_route(struct olsr_node* node); +void pop_other_route(struct olsr_node* node, struct netaddr* last_addr); + +#endif /* NODE_H_ */ diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c new file mode 100644 index 000000000000..ee5525ac67f7 --- /dev/null +++ b/sys/net/routing/olsr2/olsr.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include +#include + +#ifdef ENABLE_NAME +#include +#endif + +#include "common/netaddr.h" + +#include "olsr.h" +#include "util.h" +#include "debug.h" +#include "routing.h" +#include "constants.h" +#include "list.h" + +static struct olsr_node* _new_olsr_node(struct netaddr* addr, + uint8_t distance, uint8_t vtime, char* name) { + + struct olsr_node* n = calloc(1, sizeof(struct olsr_node)); + + if (n == NULL) + return NULL; + + n->addr = netaddr_dup(addr); + + if (n->addr == NULL) { + free(n); + return NULL; + } + + n->node.key = n->addr; + n->type = NODE_TYPE_OLSR; + n->distance = distance; + n->expires = time_now() + vtime; +#ifdef ENABLE_NAME + if (name) + n->name = strdup(name); +#endif + + avl_insert(get_olsr_head(), &n->node); + return n; +} + +/* + * find a new route for nodes that use last_addr as their default route + * if lost_node_addr is not null, all reference to it will be removed (aka lost node) + */ +static void _update_children(struct netaddr* last_addr, struct netaddr* lost_node_addr) { + TRACE_FUN("%s, %s", netaddr_to_str_s(&nbuf[0], last_addr), + netaddr_to_str_s(&nbuf[1], lost_node_addr)); + + struct olsr_node *node; + avl_for_each_element(get_olsr_head(), node, node) { + + if (lost_node_addr != NULL) + remove_other_route(node, lost_node_addr); + + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { + + if (lost_node_addr != NULL) + remove_default_node(node); + else + push_default_route(node); + + add_free_node(node); + + _update_children(node->addr, lost_node_addr); + } + } +} + +static void _olsr_node_expired(struct olsr_node* node) { + TRACE_FUN(); + + remove_default_node(node); + _update_children(node->addr, NULL); + + add_free_node(node); + + // 1-hop neighbors will become normal olsr_nodes here, should we care? (possible waste of memory) +} + +static void _remove_olsr_node(struct olsr_node* node) { + TRACE_FUN(); + + avl_remove(get_olsr_head(), &node->node); + remove_free_node(node); + + /* remove other routes from node that is about to be deleted */ + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + netaddr_free(route->last_addr); + simple_list_for_each_remove(&node->other_routes, route, prev); + } + + remove_default_node(node); + _update_children(node->addr, node->addr); + +#ifdef ENABLE_NAME + if (node->name) + free(node->name); +#endif + netaddr_free(node->addr); + free(node); +} + +static bool _route_expired(struct olsr_node* node, struct netaddr* last_addr) { + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + return time_now() > node->expires; + + if (node->other_routes == NULL) + return true; + + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + + if (route == NULL) + return true; + + return time_now() > route->expires; +} + +static void _update_link_quality(struct nhdp_node* node) { + TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); + if (_route_expired(h1_super(node), get_local_addr())) + node->link_quality = node->link_quality * (1 - HYST_SCALING); + else + node->link_quality = node->link_quality * (1 - HYST_SCALING) + HYST_SCALING; + + if (!h1_super(node)->pending && node->link_quality < HYST_LOW) { + h1_super(node)->pending = 1; + h1_super(node)->lost = LOST_ITER_MAX; + node->mpr_neigh = 0; + + add_free_node(h1_super(node)); + push_default_route(h1_super(node)); + _update_children(h1_super(node)->addr, NULL); + } + + if (h1_super(node)->pending && node->link_quality > HYST_HIGH) { + h1_super(node)->pending = 0; + h1_super(node)->lost = 0; + + /* node may just have become a 1-hop node */ + if (h1_super(node)->last_addr != NULL) + push_default_route(h1_super(node)); + + add_free_node(h1_super(node)); + } +} + +bool remove_expired(struct olsr_node* node) { + time_t _now = time_now(); + + if (node->type == NODE_TYPE_NHDP) + _update_link_quality(h1_deriv(node)); + + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + if (_now - route->expires < HOLD_TIME) + continue; + + DEBUG("alternative route to %s (%s) via %s expired, removing it", + node->name, netaddr_to_str_s(&nbuf[0], node->addr), + netaddr_to_str_s(&nbuf[1], route->last_addr)); + simple_list_for_each_remove(&node->other_routes, route, prev); + } + + if (_now - node->expires > HOLD_TIME) { + + DEBUG("%s (%s) expired", + node->name, netaddr_to_str_s(&nbuf[0], node->addr)); + + if (node->other_routes == NULL) { + _remove_olsr_node(node); + return true; + } else + _olsr_node_expired(node); + } + + return false; +} + +void route_expired(struct olsr_node* node, struct netaddr* last_addr) { + DEBUG("%s (%s) over %s expired", + node->name, netaddr_to_str_s(&nbuf[0], node->addr), + netaddr_to_str_s(&nbuf[1], last_addr)); + + if (node->last_addr == NULL || netaddr_cmp(node->last_addr, last_addr) != 0) { + remove_other_route(node, last_addr); + if (node->other_routes == NULL) + _remove_olsr_node(node); + return; + } + + if (node->other_routes == NULL) + _remove_olsr_node(node); + else + _olsr_node_expired(node); +} + +void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, char* name) { + struct olsr_node* n = get_node(addr); + + if (n == NULL) + n = _new_olsr_node(addr, distance, vtime, name); + + if (n == NULL) { + puts("ERROR: add_olsr_node failed - out of memory"); + return; + } + + if (n->last_addr == NULL) { +#ifdef ENABLE_NAME + if (n->name == NULL && name != NULL) + n->name = strdup(name); +#endif + add_other_route(n, last_addr, vtime); + add_free_node(n); + + return; + } + + /* minimize MPR count */ + if (distance == 2 && distance == n->distance && netaddr_cmp(last_addr, n->last_addr) != 0) { + struct nhdp_node* cur_mpr = h1_deriv(get_node(n->last_addr)); + struct nhdp_node* new_mpr = h1_deriv(get_node(last_addr)); + + /* see if the new route is better, that means uses a neighbor that is alreay + used for reaching (more) 2-hop neighbors. */ + if (cur_mpr == NULL || (new_mpr != NULL && + new_mpr->mpr_neigh + 1 > cur_mpr->mpr_neigh)) { + DEBUG("switching MPR"); + _update_children(n->addr, NULL); + push_default_route(n); + add_free_node(n); + } + } + + if (distance >= n->distance) { + add_other_route(n, last_addr, vtime); + return; + } + + DEBUG("shorter route found (old: %d hops over %s new: %d hops over %s)", + n->distance, netaddr_to_str_s(&nbuf[0], n->last_addr), + distance, netaddr_to_str_s(&nbuf[1], last_addr)); + + n->distance = distance; + _update_children(n->addr, NULL); + push_default_route(n); + add_other_route(n, last_addr, vtime); + add_free_node(n); +} + +bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) { + struct olsr_node* node = get_node(addr); + if (!node) { + node = _new_olsr_node(addr, 255, vtime, NULL); + node->seq_no = seq_no; + return false; + } + + uint16_t tmp = node->seq_no; + node->seq_no = seq_no; + /* S1 > S2 AND S1 - S2 < MAXVALUE/2 OR + S2 > S1 AND S2 - S1 > MAXVALUE/2 */ + if ((seq_no > tmp && seq_no - tmp < (1 << 15)) || + (seq_no < tmp && tmp - seq_no > (1 << 15)) ) + return false; + + return true; +} + +#ifdef ENABLE_DEBUG_OLSR +void print_topology_set(void) { + DEBUG(); + DEBUG("---[ Topology Set ]--"); + DEBUG(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), local_name); + + struct olsr_node* node; + struct alt_route* route; + avl_for_each_element(get_olsr_head(), node, node) { + DEBUG("%s (%s)\t=> %s; %d hops, next: %s, %ld s [%d] %s %.2f [%d] %s", + netaddr_to_str_s(&nbuf[0], node->addr), + node->name, + netaddr_to_str_s(&nbuf[1], node->last_addr), + node->distance, + netaddr_to_str_s(&nbuf[2], node->next_addr), + node->expires - time_now(), + node->seq_no, + node->type != NODE_TYPE_NHDP ? "" : node->pending ? "pending" : "", + node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->link_quality, + node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->mpr_neigh, + node->type != NODE_TYPE_NHDP ? "" : node->mpr_selector ? "[S]" : "[ ]" + ); + simple_list_for_each (node->other_routes, route) { + DEBUG("\t\t\t=> %s; %ld s", + netaddr_to_str_s(&nbuf[0], route->last_addr), + route->expires - time_now()); + } + } + DEBUG("---------------------"); + DEBUG(); +} + +void print_routing_graph(void) { + puts("\n----BEGIN ROUTING GRAPH----\n"); + puts("subgraph routing {"); + puts("\tedge [ color = red ]"); + struct olsr_node* node, *tmp; + avl_for_each_element(get_olsr_head(), node, node) { + if (node->addr != NULL && node->last_addr != NULL) { + tmp = get_node(node->last_addr); + printf("\t%s -> %s\n", tmp ? tmp->name : local_name, node->name); + } + } + puts("}"); + + puts("subgraph mpr {"); + puts("\tedge [ color = blue ]"); + puts("// BEGIN MPR"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance == 1 && node->mpr_selector) { + printf("\t%s -> %s\n", node->name, local_name); + } + } + puts("// END MPR"); + puts("}"); + + puts("\n----END ROUTING GRAPH----\n"); + +} +#else +void print_topology_set(void) { + struct netaddr_str nbuf[3]; + + struct alt_route* route; + struct olsr_node* node; + + puts(""); + puts("---[ Topology Set ]--"); +#ifdef ENABLE_NAME + printf(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), local_name); +#else + printf(" [%s]\n", netaddr_to_str_s(&nbuf[0], get_local_addr())); +#endif + + avl_for_each_element(get_olsr_head(), node, node) { +#ifdef ENABLE_NAME + printf("%s (%s)\t=> %s; %d hops, next: %s, %ld s [%d] %s %.2f [%d] %s\n", +#else + printf("%s\t=> %s; %d hops, next: %s, %ld s [%d] %s %.2f [%d] %s\n", +#endif + netaddr_to_str_s(&nbuf[0], node->addr), +#ifdef ENABLE_NAME + node->name, +#endif + netaddr_to_str_s(&nbuf[1], node->last_addr), + node->distance, + netaddr_to_str_s(&nbuf[2], node->next_addr), + node->expires - time_now(), + node->seq_no, + node->type != NODE_TYPE_NHDP ? "" : node->pending ? "pending" : "", + node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->link_quality, + node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->mpr_neigh, + node->type != NODE_TYPE_NHDP ? "" : node->mpr_selector ? "[S]" : "[ ]" + ); + simple_list_for_each (node->other_routes, route) { + printf("\t\t\t=> %s; %ld s\n", + netaddr_to_str_s(&nbuf[0], route->last_addr), + route->expires - time_now()); + } + } + puts("---------------------"); + +} +void print_routing_graph(void) {} +#endif diff --git a/sys/net/routing/olsr2/olsr.h b/sys/net/routing/olsr2/olsr.h new file mode 100644 index 000000000000..fe666d10afcf --- /dev/null +++ b/sys/net/routing/olsr2/olsr.h @@ -0,0 +1,19 @@ +#ifndef OLSR_H_ +#define OLSR_H_ + +#include + +#include "common/avl.h" +#include "common/netaddr.h" + +#include "node.h" + +void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, char* name); +bool is_known_msg(struct netaddr* src, uint16_t seq_no, uint8_t vtime); +bool remove_expired(struct olsr_node* node); +void route_expired(struct olsr_node* node, struct netaddr* last_addr); + +void print_topology_set(void); +void print_routing_graph(void); + +#endif /* OLSR_H_ */ diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c new file mode 100644 index 000000000000..dfdea5e263ff --- /dev/null +++ b/sys/net/routing/olsr2/olsr_init.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/*************************************************************** + * This file is for initialisation of the olsr2 module on RIOT * + ***************************************************************/ + +#ifdef RIOT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rfc5444/rfc5444_writer.h" + +#include "constants.h" +#include "debug.h" +#include "node.h" +#include "olsr.h" +#include "reader.h" +#include "writer.h" + +#include + +static char receive_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; +static char sender_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; + +struct timer_msg { + vtimer_t timer; + timex_t interval; + void (*func) (void); +}; + +static struct timer_msg msg_hello = { .timer = {0}, .interval = { .seconds = HELLO_REFRESH_INTERVAL - 1, .microseconds = 0}, .func = writer_send_hello }; +static struct timer_msg msg_tc = { .timer = {0}, .interval = { .seconds = TC_REFRESH_INTERVAL - 1, .microseconds = 0}, .func = writer_send_tc }; + +static int sock; +static sockaddr6_t sa_bcast; +static mutex_t olsr_data; + +#if defined(BOARD_NATIVE) && defined(ENABLE_NAME) +static char _name[5]; +static char* gen_name(char* dest, const size_t len) { + for (int i = 0; i < len - 1; ++i) + dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); + dest[len - 1] = '\0'; + return dest; +} +#endif + +static void write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), + struct rfc5444_writer_target *iface __attribute__((unused)), + void *buffer, size_t length) { + +#ifdef ENABLE_LEDS + LED_GREEN_TOGGLE; +#endif + int bytes_send = destiny_socket_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); + + DEBUG("write_packet(%d bytes), %d bytes sent", length, bytes_send); +} + +static void olsr_receiver_thread(void) { + char buffer[256]; + + sockaddr6_t sa = {0}; + sa.sin6_family = AF_INET6; + sa.sin6_port = HTONS(MANET_PORT); + + if (destiny_socket_bind(sock, &sa, sizeof sa) < 0) { + printf("Error bind failed!\n"); + destiny_socket_close(sock); + } + + int32_t recsize; + uint32_t fromlen = sizeof sa; + + struct netaddr _src; + _src._type = AF_INET6; + _src._prefix_len = 128; + + while (1) { + recsize = destiny_socket_recvfrom(sock, &buffer, sizeof buffer, 0, &sa, &fromlen); +#ifdef ENABLE_LEDS + LED_RED_TOGGLE; +#endif + memcpy(&_src._addr, &sa.sin6_addr, sizeof _src._addr); + DEBUG("received %d bytes from %s", recsize, netaddr_to_str_s(&nbuf[0], &_src)); + + mutex_lock(&olsr_data); + reader_handle_packet(&buffer, recsize, &_src); + mutex_unlock(&olsr_data); + } +} + +static void olsr_sender_thread(void) { + DEBUG("olsr_sender_thread, pid %d\n", thread_getpid()); + + /* message queue, so messages don't get lost */ + msg_t msgq[2]; + msg_init_queue(msgq, sizeof msgq); + + while (1) { + msg_t m; + msg_receive(&m); + struct timer_msg* tmsg = (struct timer_msg*) m.content.ptr; + + mutex_lock(&olsr_data); + tmsg->func(); + mutex_unlock(&olsr_data); + + /* add jitter */ + tmsg->interval.microseconds = genrand_uint32() % MAX_JITTER; + + if (vtimer_set_msg(&tmsg->timer, tmsg->interval, thread_getpid(), tmsg) != 0) + DEBUG("vtimer_set_msg failed, stopped sending"); + } +} + +static ipv6_addr_t* get_next_hop(ipv6_addr_t* dest) { + struct olsr_node* node = get_node((struct netaddr*) dest); // get_node will only look at the first few bytes + if (node == NULL) + return NULL; + + return (ipv6_addr_t*) node->next_addr; +} + +#ifdef ENABLE_NAME +ipv6_addr_t* get_ip_by_name(char* name) { + struct olsr_node *node; + avl_for_each_element(get_olsr_head(), node, node) { + if (node->name != NULL && strcmp(node->name, name) == 0) + return (ipv6_addr_t*) node->addr; + } + + return NULL; +} +#endif + +void olsr_init(void) { + +#ifdef ENABLE_NAME +#ifdef BOARD_NATIVE + local_name = gen_name(_name, sizeof _name); +#else + local_name = sysconfig.name; +#endif +#endif + mutex_init(&olsr_data); + node_init(); + reader_init(); + writer_init(write_packet); + + /* we always send to the same broadcast address, prepare it once */ + sa_bcast.sin6_family = AF_INET6; + sa_bcast.sin6_port = HTONS(MANET_PORT); + ipv6_addr_set_all_nodes_addr(&sa_bcast.sin6_addr); + + /* enable receive */ + sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_receiver_thread, "olsr_rec"); + + /* set get_local_addr() */ + get_local_addr()->_type = AF_INET6; + get_local_addr()->_prefix_len = 128; + ipv6_net_if_get_best_src_addr((ipv6_addr_t*) get_local_addr(), &sa_bcast.sin6_addr); + + /* register olsr for routing */ + ipv6_iface_set_routing_provider(get_next_hop); + + DEBUG("This is node %s with IP %s", local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); + + /* enable sending */ + int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_sender_thread, "olsr_snd"); + + msg_t m; + DEBUG("setting up HELLO timer"); + m.content.ptr = (char*) &msg_hello; + msg_send(&m, pid, false); + + sleep_s(1); + DEBUG("setting up TC timer"); + m.content.ptr = (char*) &msg_tc; + msg_send(&m, pid, false); +} + +#endif /* RIOT */ diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c new file mode 100644 index 000000000000..02bb69956ec2 --- /dev/null +++ b/sys/net/routing/olsr2/reader.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include +#include + +#include "common/common_types.h" +#include "common/netaddr.h" +#include "rfc5444/rfc5444.h" +#include "rfc5444/rfc5444_iana.h" +#include "rfc5444/rfc5444_reader.h" + +#ifdef RIOT +#include "net_help.h" +#endif + +#include "debug.h" +#include "nhdp.h" +#include "olsr.h" +#include "reader.h" +#include "writer.h" +#include "constants.h" +#include "routing.h" + +static struct rfc5444_reader reader; +static struct netaddr* current_src; +static struct olsr_node* current_node; + +/* ughh… these variables are needed in the addr callback, but read in the packet callback */ +static uint8_t vtime; +static uint8_t hops; +static uint16_t _seq_no; + +static enum rfc5444_result _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont); +static enum rfc5444_result _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont); + +static enum rfc5444_result _cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont); +static enum rfc5444_result _cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont); + +/* HELLO message */ +static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_message_tlvs[] = { + [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, +#ifdef ENABLE_NAME + [IDX_TLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, +#endif +}; + +static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_address_tlvs[] = { + [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, +#ifdef ENABLE_NAME + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, +#endif +}; + +/* TC message */ +static struct rfc5444_reader_tlvblock_consumer_entry _olsr_message_tlvs[] = { + [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, +#ifdef ENABLE_NAME + [IDX_TLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, +#endif +}; + +static struct rfc5444_reader_tlvblock_consumer_entry _olsr_address_tlvs[] = { + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, +#ifdef ENABLE_NAME + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, +#endif +}; + +/* define callbacks for HELLO message */ +static struct rfc5444_reader_tlvblock_consumer _nhdp_consumer = { + .msg_id = RFC5444_MSGTYPE_HELLO, + .block_callback = _cb_nhdp_blocktlv_packet_okay, +}; + +static struct rfc5444_reader_tlvblock_consumer _nhdp_address_consumer = { + .msg_id = RFC5444_MSGTYPE_HELLO, + .addrblock_consumer = true, + .block_callback = _cb_nhdp_blocktlv_address_okay, +}; + +/* define callbacks for TC message */ +static struct rfc5444_reader_tlvblock_consumer _olsr_consumer = { + .msg_id = RFC5444_MSGTYPE_TC, + .block_callback = _cb_olsr_blocktlv_packet_okay, +}; + +static struct rfc5444_reader_tlvblock_consumer _olsr_address_consumer = { + .msg_id = RFC5444_MSGTYPE_TC, + .addrblock_consumer = true, + .block_callback = _cb_olsr_blocktlv_address_okay, +}; + +/* HELLO message */ +static enum rfc5444_result +_cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __attribute__((unused))) { + DEBUG("received HELLO message:"); + + if (netaddr_cmp(get_local_addr(), current_src) == 0) + return RFC5444_DROP_PACKET; + + /* VTIME is defined as mandatory */ + vtime = rfc5444_timetlv_decode(*_nhdp_message_tlvs[IDX_TLV_VTIME].tlv->single_value); + + char* name = NULL; +#ifdef ENABLE_NAME + if (_nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv) { + name = (char*) _nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv->single_value; + DEBUG("\tfrom: %s (%s)", name, netaddr_to_str_s(&nbuf[0], current_src)); + } +#endif + + current_node = add_neighbor(current_src, vtime, name); + + if (current_node == NULL) { + puts("ERROR: add_neighbor failed - out of memory"); + return RFC5444_DROP_PACKET; + } + + /* reset MPR selector state, will be set by _cb_nhdp_blocktlv_address_okay */ + current_node->mpr_selector = 0; + + if (current_node->pending) + return RFC5444_DROP_PACKET; + + return RFC5444_OKAY; +} + +/* HELLO announced addresses */ +static enum rfc5444_result +_cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { + struct rfc5444_reader_tlvblock_entry* tlv; + + char* name = NULL; +#ifdef ENABLE_NAME + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { + name = (char*) tlv->single_value; + DEBUG("\t2-hop neighbor: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); + } +#endif + + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { + switch (* (char*) tlv->single_value) { + struct olsr_node* lost; + case RFC5444_LINKSTATUS_LOST: + lost = get_node(&cont->addr); + DEBUG("\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); + + if (lost != NULL) + route_expired(lost, current_node->addr); + + return RFC5444_DROP_ADDRESS; + default: + DEBUG("\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + } + } + + /* node broadcasts us as it's neighbor */ + if (netaddr_cmp(&cont->addr, get_local_addr()) == 0) { + + /* node selected us as mpr */ + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_MPR].tlv)) + current_node->mpr_selector = 1; + + } else + add_olsr_node(&cont->addr, current_src, vtime, 2, name); + + return RFC5444_OKAY; +} + +/* TC message */ +static enum rfc5444_result +_cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont) { + DEBUG("received TC message:"); + + if (!cont->has_origaddr) + return RFC5444_DROP_PACKET; + + if (!cont->has_seqno) + return RFC5444_DROP_PACKET; + + if (!cont->has_hopcount || !cont->has_hoplimit) + return RFC5444_DROP_PACKET; + + if (!netaddr_cmp(get_local_addr(), current_src)) + return RFC5444_DROP_PACKET; + + if (!netaddr_cmp(get_local_addr(), &cont->orig_addr)) + return RFC5444_DROP_PACKET; + + vtime = rfc5444_timetlv_decode(*_olsr_message_tlvs[IDX_TLV_VTIME].tlv->single_value); + + if (is_known_msg(&cont->orig_addr, cont->seqno, vtime)) + return RFC5444_DROP_PACKET; + + DEBUG("\tfrom: %s", netaddr_to_str_s(&nbuf[0], &cont->orig_addr)); + DEBUG("\tsender: %s", netaddr_to_str_s(&nbuf[0], current_src)); + DEBUG("\tseqno: %d", cont->seqno); + DEBUG("\thops: %d", cont->hopcount); + + hops = cont->hopcount + 1; /* hopcount starts with 0 for A -> B */ + _seq_no = cont->seqno; + + return RFC5444_OKAY; +} + +/* TC announced addresses */ +static enum rfc5444_result +_cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { + struct rfc5444_reader_tlvblock_entry* tlv __attribute__((unused)); + char* name = NULL; + + if (netaddr_cmp(get_local_addr(), &cont->addr) == 0) + return RFC5444_DROP_ADDRESS; + +#ifdef ENABLE_NAME + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { + name = (char*) tlv->single_value; + DEBUG("\tannounces: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); + } +#endif + + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { + switch (* (char*) tlv->single_value) { + struct olsr_node* lost; + case RFC5444_LINKSTATUS_LOST: + lost = get_node(&cont->addr); + DEBUG("\texpired node reported, removing it (TC)%s", lost ? "" : " [not found]"); + + if (lost != NULL) + route_expired(lost, current_node->addr); + + return RFC5444_DROP_ADDRESS; + default: + DEBUG("\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + } + } + + /* hops is hopcount to orig_addr, addr is one more hop */ + add_olsr_node(&cont->addr, &cont->orig_addr, vtime, hops + 1, name); + + return RFC5444_OKAY; +} + +/* this is only called for messages with hopcount/hoplimit, that is only TC messages */ +static void +_cb_olsr_forward_message(struct rfc5444_reader_tlvblock_context *context __attribute__((unused)), + uint8_t *buffer, size_t length) { + struct olsr_node* node = get_node(current_src); + + /* only forward if node selected us as MPR */ + if (node == NULL || node->mpr_selector == 0) + return; + + if (RFC5444_OKAY == rfc5444_writer_forward_msg(&writer, buffer, length)) + rfc5444_writer_flush(&writer, &interface, true); + else + DEBUG("\tfailed forwarding package"); +} + +/** + * Initialize RFC5444 reader + */ +void reader_init(void) { + /* initialize reader */ + rfc5444_reader_init(&reader); + reader.forward_message = _cb_olsr_forward_message; + + /* register HELLO message consumer */ + rfc5444_reader_add_message_consumer(&reader, &_nhdp_consumer, _nhdp_message_tlvs, ARRAYSIZE(_nhdp_message_tlvs)); + rfc5444_reader_add_message_consumer(&reader, &_nhdp_address_consumer, _nhdp_address_tlvs, ARRAYSIZE(_nhdp_address_tlvs)); + + /* register TC message consumer */ + rfc5444_reader_add_message_consumer(&reader, &_olsr_consumer, _olsr_message_tlvs, ARRAYSIZE(_olsr_message_tlvs)); + rfc5444_reader_add_message_consumer(&reader, &_olsr_address_consumer, _olsr_address_tlvs, ARRAYSIZE(_olsr_address_tlvs)); +} + +/** + * Inject a package into the RFC5444 reader + */ +int reader_handle_packet(void* buffer, size_t length, struct netaddr* src) { + current_src = src; + return rfc5444_reader_handle_packet(&reader, buffer, length); +} + +/** + * Cleanup RFC5444 reader + */ +void reader_cleanup(void) { + rfc5444_reader_cleanup(&reader); +} diff --git a/sys/net/routing/olsr2/reader.h b/sys/net/routing/olsr2/reader.h new file mode 100644 index 000000000000..cac510f0f3d5 --- /dev/null +++ b/sys/net/routing/olsr2/reader.h @@ -0,0 +1,11 @@ +#ifndef READER_H_ +#define READER_H_ + +#include "common/common_types.h" +#include "rfc5444/rfc5444_reader.h" + +void reader_init(void); +int reader_handle_packet(void* buffer, size_t length, struct netaddr* src); +void reader_cleanup(void); + +#endif /* READER_H_ */ diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c new file mode 100644 index 000000000000..0820d3d5249e --- /dev/null +++ b/sys/net/routing/olsr2/routing.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include +#include + +#include "olsr.h" +#include "list.h" +#include "debug.h" +#include "util.h" +#include "routing.h" +#include "constants.h" + +/* sorted list, only for faster access + * Keeps yet unroutable nodes, so we don't have to traverse the entire list + */ +struct free_node { + struct free_node* next; + struct olsr_node* node; + uint8_t hops; // for sorting only +}; + +static struct free_node* _pending_head = 0; +static bool _update_pending = false; + +void add_free_node(struct olsr_node* node) { + struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); + if (n == NULL) { + uint8_t hops = node->distance; + n = simple_list_add_before(&_pending_head, hops); + } + + if (n == NULL) { + printf("ERROR: out of memory in %s\n", __FUNCTION__); + return; + } + + n->node = node; + + node->next_addr = netaddr_free(node->next_addr); /* empty next_addr marks route as pending */ + _update_pending = true; +} + +bool remove_free_node(struct olsr_node* node) { + struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); + if (n == NULL) + return false; + return simple_list_remove(&_pending_head, n); +} + +void fill_routing_table(void) { + struct free_node* head = _pending_head; + + if (_pending_head == NULL || !_update_pending) + return; + + _update_pending = false; + DEBUG("update routing table"); + + struct free_node* fn; + bool noop = false; /* when in an iteration there was nothing removed from free nodes */ + while (head && !noop) { + noop = true; /* if no nodes could be removed in an iteration, abort */ + struct free_node *prev; + char skipped; + simple_list_for_each_safe(head, fn, prev, skipped) { + /* chose shortest route from the set of availiable routes */ + uint8_t min_hops = 255; + struct olsr_node* node = NULL; + struct alt_route* route; + simple_list_for_each(fn->node->other_routes, route) { + + /* the node is actually a neighbor of ours */ + if (netaddr_cmp(route->last_addr, get_local_addr()) == 0) { + /* don't use pending nodes */ + if (fn->node->pending) + continue; + + min_hops = 1; + break; + } + + /* see if we can find a better route */ + struct olsr_node* _tmp = get_node(route->last_addr); + if (_tmp != NULL && _tmp->addr != NULL && + _tmp->distance + 1 <= min_hops && + _tmp->next_addr != NULL) { + + if (_tmp->next_addr == NULL) + continue; + /* ignore pending nodes */ + if (_tmp->distance == 1 && _tmp->pending) + continue; + + /* try to minimize MPR count */ + if (min_hops == 2) { + /* use the neighbor with the most 2-hop neighbors */ + if (h1_deriv(node)->mpr_neigh > h1_deriv(_tmp)->mpr_neigh + 1) + continue; + } + + node = _tmp; + min_hops = _tmp->distance + 1; + } + } + + /* We found a valid route */ + if (min_hops == 1) { + DEBUG("%s (%s) is a 1-hop neighbor", + netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name); + noop = false; + fn->node->next_addr = netaddr_use(fn->node->addr); + fn->node->distance = 1; + fn->node->lost = 0; + + pop_other_route(fn->node, get_local_addr()); + simple_list_for_each_remove(&head, fn, prev); + + } else if (node != NULL) { + DEBUG("%s (%s) -> %s (%s) -> […] -> %s", + netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name, + netaddr_to_str_s(&nbuf[1], node->addr), node->name, + netaddr_to_str_s(&nbuf[2], node->next_addr)); + DEBUG("%d = %d", fn->node->distance, node->distance + 1); + + noop = false; + + /* update MPR information */ + if (node->distance == 1) { + h1_deriv(node)->mpr_neigh++; + } + + fn->node->distance = node->distance + 1; + fn->node->next_addr = netaddr_use(node->next_addr); + + pop_other_route(fn->node, node->addr); + simple_list_for_each_remove(&head, fn, prev); + } else + DEBUG("don't yet know how to route %s", netaddr_to_str_s(&nbuf[0], fn->node->addr)); + } + } + + _pending_head = head; + +#ifdef DEBUG + while (head != NULL) { + DEBUG("Could not find next hop for %s (%s), should be %s (%d hops)", + netaddr_to_str_s(&nbuf[0], head->node->addr), head->node->name, + netaddr_to_str_s(&nbuf[1], head->node->last_addr), head->node->distance); + + head = head->next; + } +#endif +} diff --git a/sys/net/routing/olsr2/routing.h b/sys/net/routing/olsr2/routing.h new file mode 100644 index 000000000000..a68eaa2690e3 --- /dev/null +++ b/sys/net/routing/olsr2/routing.h @@ -0,0 +1,22 @@ +#ifndef ROUTING_H_ +#define ROUTING_H_ + +#include "node.h" + +/* + * add a node to the list of pending nodes + */ +void add_free_node(struct olsr_node* node); + +/* + * remove a node from the list of pending nodes + * returns true if node was found and removed + */ +bool remove_free_node(struct olsr_node* node); + +/* + * try to find a route for pending nodes + */ +void fill_routing_table(void); + +#endif /* ROUTING_H_ */ diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c new file mode 100644 index 000000000000..577448269853 --- /dev/null +++ b/sys/net/routing/olsr2/util.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include + +#ifdef RIOT +#include "vtimer.h" +#include "rtc.h" +#else +#include +#include +#endif + +#include "util.h" +#include "node.h" +#include "debug.h" + +const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src) { + return src ? netaddr_to_string(dst, src) : NULL; +} + +struct netaddr* netaddr_dup(struct netaddr* addr) { + struct netaddr_rc* addr_new = calloc(1, sizeof(struct netaddr_rc)); + + if (addr_new == NULL) + return NULL; + + addr_new->_refs = 1; + return memcpy(addr_new, addr, sizeof(struct netaddr)); +} + +struct netaddr* netaddr_use(struct netaddr* addr) { + ((struct netaddr_rc*) addr)->_refs++; + return addr; +} + +struct netaddr* netaddr_reuse(struct netaddr* addr) { + if (netaddr_cmp(addr, get_local_addr()) == 0) + return netaddr_use(get_local_addr()); + + struct olsr_node* n = get_node(addr); + if (!n) { + DEBUG("Address %s not found, this shouldn't happen", netaddr_to_str_s(&nbuf[0], addr)); + return netaddr_dup(addr); + } + return netaddr_use(n->addr); +} + +struct netaddr* netaddr_free(struct netaddr* addr) { + struct netaddr_rc* addr_rc = (struct netaddr_rc*) addr; + + if (addr) + DEBUG("netaddr_free(%s) - %d refs", netaddr_to_str_s(&nbuf[0], addr), addr_rc->_refs); + + if (addr != NULL && --addr_rc->_refs == 0) + free(addr_rc); + + return NULL; +} + +time_t time_now(void) { +#ifdef RIOT + struct timeval _tv; + return rtc_time(&_tv); +#else + return time(0); +#endif +} + +void sleep_s(int secs) { +#ifdef RIOT + vtimer_usleep(secs * 1000000); +#else + // process wakes up when a package arrives + // go back to sleep to prevent flooding + int remaining_sleep = secs; + while ((remaining_sleep = sleep(remaining_sleep))); +#endif +} diff --git a/sys/net/routing/olsr2/util.h b/sys/net/routing/olsr2/util.h new file mode 100644 index 000000000000..da5a7c1b0bf0 --- /dev/null +++ b/sys/net/routing/olsr2/util.h @@ -0,0 +1,21 @@ +#ifndef UTIL_H_ +#define UTIL_H_ + +#include "common/netaddr.h" + +struct netaddr_rc { + struct netaddr super; + uint8_t _refs; +}; + +const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src); + +struct netaddr* netaddr_dup(struct netaddr* addr); +struct netaddr* netaddr_use(struct netaddr* addr); +struct netaddr* netaddr_reuse(struct netaddr* addr); +struct netaddr* netaddr_free(struct netaddr* addr); + +time_t time_now(void); +void sleep_s(int secs); + +#endif diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c new file mode 100644 index 000000000000..d32437cc48fa --- /dev/null +++ b/sys/net/routing/olsr2/writer.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#ifdef RIOT +#include "net_help.h" +#endif + +#ifdef ENABLE_NAME +#include +#endif + +#include "common/avl.h" +#include "common/common_types.h" +#include "common/netaddr.h" +#include "rfc5444/rfc5444.h" +#include "rfc5444/rfc5444_iana.h" +#include "rfc5444/rfc5444_writer.h" + +#include "constants.h" +#include "writer.h" +#include "nhdp.h" +#include "olsr.h" +#include "debug.h" +#include "routing.h" + +uint8_t msg_buffer[256]; +uint8_t msg_addrtlvs[512]; +uint8_t packet_buffer[256]; + +uint16_t seq_no = 1; + +static bool send_tc_messages; + +static void _cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr); +static void _cb_add_nhdp_addresses(struct rfc5444_writer *wr); + +static void _cb_add_olsr_message_TLVs(struct rfc5444_writer *wr); +static void _cb_add_olsr_addresses(struct rfc5444_writer *wr); + +/* HELLO message */ +static struct rfc5444_writer_content_provider _nhdp_message_content_provider = { + .msg_type = RFC5444_MSGTYPE_HELLO, + .addMessageTLVs = _cb_add_nhdp_message_TLVs, + .addAddresses = _cb_add_nhdp_addresses, +}; + +static struct rfc5444_writer_tlvtype _nhdp_addrtlvs[] = { + [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, +#ifdef ENABLE_NAME + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, +#endif +}; + +/* TC message */ +static struct rfc5444_writer_content_provider _olsr_message_content_provider = { + .msg_type = RFC5444_MSGTYPE_TC, + .addMessageTLVs = _cb_add_olsr_message_TLVs, + .addAddresses = _cb_add_olsr_addresses, +}; + +static struct rfc5444_writer_tlvtype _olsr_addrtlvs[] = { + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, +#ifdef ENABLE_NAME + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, +#endif +}; + +/* add TLVs to HELLO message */ +static void +_cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr) { + uint8_t time_encoded = rfc5444_timetlv_encode(HELLO_REFRESH_INTERVAL); + rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); + +#ifdef ENABLE_NAME + rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); +#endif +} + +/* add addresses to HELLO message */ +static void +_cb_add_nhdp_addresses(struct rfc5444_writer *wr) { + struct olsr_node* node, *safe; + int value; + send_tc_messages = false; + + /* add all neighbors */ + avl_for_each_element_safe(get_olsr_head(), node, node, safe) { + + /* if the node was just removed entirely from the database, continue */ + if (remove_expired(node)) + continue; + + if (node->distance != 1 && !node->lost) + continue; + + if (node->pending && !node->lost) + continue; + + if (!node->pending && node->mpr_selector) + send_tc_messages = true; + + struct rfc5444_writer_address *address = rfc5444_writer_add_address(wr, + _nhdp_message_content_provider.creator, node->addr, false); + + /* node is a mpr */ + if (h1_deriv(node)->mpr_neigh > 0) + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_MPR], + &h1_deriv(node)->mpr_neigh, sizeof h1_deriv(node)->mpr_neigh, false); + + if (node->lost) { + DEBUG("LINKSTATUS: neighbor %s lost (HELLO) [%d]", node->name, node->lost); + value = RFC5444_LINKSTATUS_LOST; + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_LINK_STATUS], + &value, sizeof value, false); + + if (!send_tc_messages) + node->lost--; + } +#ifdef ENABLE_NAME + if (node->name) + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_NODE_NAME], + node->name, strlen(node->name) + 1, false); +#endif + } +} + +/* add TLVs to TC message */ +static void +_cb_add_olsr_message_TLVs(struct rfc5444_writer *wr) { + uint8_t time_encoded = rfc5444_timetlv_encode(TC_REFRESH_INTERVAL); + rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); + +#ifdef ENABLE_NAME + rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); +#endif +} + +/* add addresses to TC message */ +static void +_cb_add_olsr_addresses(struct rfc5444_writer *wr) { + struct olsr_node* node; + int value; + + /* add all neighbors */ + avl_for_each_element(get_olsr_head(), node, node) { + if (!node->mpr_selector) + continue; + + if (node->distance != 1 && !node->lost) + continue; + + if (node->pending && !node->lost) + continue; + + struct rfc5444_writer_address *address __attribute__((unused)); + address = rfc5444_writer_add_address(wr, _olsr_message_content_provider.creator, node->addr, false); + + if (node->lost) { + DEBUG("LINKSTATUS: neighbor %s lost (TC) [%d]", node->name, node->lost); + value = RFC5444_LINKSTATUS_LOST; + rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_LINK_STATUS], + &value, sizeof value, false); + + node->lost--; + } + +#ifdef ENABLE_NAME + if (node->name) + rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_NODE_NAME], + node->name, strlen(node->name) + 1, false); +#endif + } +} + +/* header for HELLO messages */ +static void +_cb_add_hello_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) { + /* no originator, no hopcount, no hoplimit, no sequence number */ + rfc5444_writer_set_msg_header(wr, message, false, false, false, false); +} + +/* header for TC messages */ +static void +_cb_add_tc_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) { + /* originator, hopcount, hoplimit, sequence number */ + rfc5444_writer_set_msg_header(wr, message, true, true, true, true); + rfc5444_writer_set_msg_seqno(wr, message, seq_no++); + rfc5444_writer_set_msg_originator(wr, message, netaddr_get_binptr(get_local_addr())); + + message->hoplimit = TC_HOP_LIMIT; +} + +/* reader has already decided whether to forward or not, just say ok to that */ +bool +olsr_message_forwarding_selector(struct rfc5444_writer_target *rfc5444_target __attribute__((unused))) { + return true; +} + +/** + * Initialize RFC5444 writer + * @param ptr pointer to "send_packet" function + */ +void +writer_init(write_packet_func_ptr ptr) { + struct rfc5444_writer_message *_hello_msg; + struct rfc5444_writer_message *_tc_msg; + + writer.msg_buffer = msg_buffer; + writer.msg_size = sizeof(msg_buffer); + writer.addrtlv_buffer = msg_addrtlvs; + writer.addrtlv_size = sizeof(msg_addrtlvs); + + interface.packet_buffer = packet_buffer; + interface.packet_size = sizeof(packet_buffer); + interface.sendPacket = ptr; + + /* initialize writer */ + rfc5444_writer_init(&writer); + + /* register a target (for sending messages to) in writer */ + rfc5444_writer_register_target(&writer, &interface); + + /* register a message content provider */ + rfc5444_writer_register_msgcontentprovider(&writer, &_nhdp_message_content_provider, _nhdp_addrtlvs, ARRAYSIZE(_nhdp_addrtlvs)); + rfc5444_writer_register_msgcontentprovider(&writer, &_olsr_message_content_provider, _olsr_addrtlvs, ARRAYSIZE(_olsr_addrtlvs)); + + /* register message type 1 with 16 byte addresses */ + _hello_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_HELLO, false, RFC5444_MAX_ADDRLEN); + _tc_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_TC, false, RFC5444_MAX_ADDRLEN); + + _hello_msg->addMessageHeader = _cb_add_hello_message_header; + _tc_msg->addMessageHeader = _cb_add_tc_message_header; + _tc_msg->forward_target_selector = olsr_message_forwarding_selector; +} + +void writer_send_hello(void) { + DEBUG("[HELLO]"); + + /* send message */ + rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_HELLO); + rfc5444_writer_flush(&writer, &interface, false); + + fill_routing_table(); +} + +void writer_send_tc(void) { + if (!send_tc_messages) + return; + + DEBUG("[TC]"); + + /* send message */ + rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_TC); + rfc5444_writer_flush(&writer, &interface, false); +} + +/** + * Cleanup RFC5444 writer + */ +void +writer_cleanup(void) { + rfc5444_writer_cleanup(&writer); +} diff --git a/sys/net/routing/olsr2/writer.h b/sys/net/routing/olsr2/writer.h new file mode 100644 index 000000000000..08ccd7fdea69 --- /dev/null +++ b/sys/net/routing/olsr2/writer.h @@ -0,0 +1,19 @@ +#ifndef WRITER_H_ +#define WRITER_H_ + +#include "common/common_types.h" +#include "rfc5444/rfc5444_writer.h" + +typedef void (*write_packet_func_ptr)( + struct rfc5444_writer *wr, struct rfc5444_writer_target *iface, void *buffer, size_t length); + +/* these are also used in reader.c, just acces them directly instead of passing a pointer */ +struct rfc5444_writer writer; +struct rfc5444_writer_target interface; + +void writer_init(write_packet_func_ptr ptr); +void writer_send_hello(void); +void writer_send_tc(void); +void writer_cleanup(void); + +#endif /* WRITER_H_ */ From 59b25c7337502ad22b3b5c45641f17114ef68e97 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 3 Apr 2014 16:45:57 +0200 Subject: [PATCH 02/48] add metrics Implement link metrics and differentiate between flooding and routing MPRs --- sys/net/routing/olsr2/constants.h | 2 +- sys/net/routing/olsr2/main.c | 182 ----------------------- sys/net/routing/olsr2/nhdp.c | 13 +- sys/net/routing/olsr2/nhdp.h | 2 +- sys/net/routing/olsr2/node.c | 66 ++++++++- sys/net/routing/olsr2/node.h | 28 +++- sys/net/routing/olsr2/olsr.c | 235 ++++++++++++++++++------------ sys/net/routing/olsr2/olsr.h | 2 +- sys/net/routing/olsr2/olsr_init.c | 2 +- sys/net/routing/olsr2/reader.c | 70 +++++++-- sys/net/routing/olsr2/reader.h | 2 +- sys/net/routing/olsr2/routing.c | 103 +++++++++---- sys/net/routing/olsr2/util.c | 5 + sys/net/routing/olsr2/util.h | 1 + sys/net/routing/olsr2/writer.c | 40 ++++- 15 files changed, 404 insertions(+), 349 deletions(-) delete mode 100644 sys/net/routing/olsr2/main.c diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index 7362f4136302..e6095ae0d1fa 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -35,8 +35,8 @@ enum { IDX_ADDRTLV_LOCAL_IF, /* is local if */ IDX_ADDRTLV_LINK_STATUS, /* link status TODO */ IDX_ADDRTLV_MPR, /* neighbor selected as mpr */ + IDX_ADDRTLV_METRIC, /* incomming link metric */ IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ - IDX_ADDRTLV_METRIC, }; #endif /* CONSTANTS_H_ */ diff --git a/sys/net/routing/olsr2/main.c b/sys/net/routing/olsr2/main.c deleted file mode 100644 index d40436410447..000000000000 --- a/sys/net/routing/olsr2/main.c +++ /dev/null @@ -1,182 +0,0 @@ -/*********************************************** - * This file is for easy testing on Linux only * - ***********************************************/ - -#ifndef RIOT -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include - -#include "rfc5444/rfc5444_writer.h" - -#include "constants.h" -#include "debug.h" -#include "node.h" -#include "olsr.h" -#include "reader.h" -#include "writer.h" - -int sockfd; -struct sockaddr_in servaddr; - -sigset_t block_io; - -struct ip_lite { - struct netaddr src; - size_t length; -}; - -void write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length) { - - DEBUG("write_packet(%zd bytes)", length); - - struct ip_lite* new_buffer = malloc(sizeof(struct ip_lite) + length); - memcpy(new_buffer + 1, buffer, length); - memcpy(&new_buffer->src, get_local_addr(), sizeof(struct netaddr)); - new_buffer->length = length; - - sendto(sockfd, new_buffer, sizeof(struct ip_lite) + new_buffer->length, 0, - (struct sockaddr*) &servaddr, sizeof(servaddr)); -} - -void enable_receive(void) { - sigprocmask (SIG_UNBLOCK, &block_io, NULL); -} - -void disable_receive(void) { - sigprocmask (SIG_BLOCK, &block_io, NULL); -} - -void sigio_handler(int sig __attribute__((unused))) { - char buffer[1500]; - struct sockaddr_storage sender; - socklen_t sendsize = sizeof(sender); - - disable_receive(); - - while (recvfrom(sockfd, &buffer, sizeof buffer, 0, (struct sockaddr*)&sender, &sendsize) > 0) { - struct ip_lite* header = (struct ip_lite*) &buffer; - - reader_handle_packet(header + 1, header->length, &header->src); - } - enable_receive(); -} - -void init_socket(in_addr_t addr, int port) { - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - - memset(&servaddr, 0, sizeof servaddr); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = addr; - servaddr.sin_port = htons(port); -} - -int enable_asynch(int sock) { - int flags; - struct sigaction sa; - - flags = fcntl(sock, F_GETFL); - fcntl(sock, F_SETFL, flags | O_ASYNC | O_NONBLOCK); - - sa.sa_flags = 0; - sa.sa_handler = sigio_handler; - sigemptyset(&sa.sa_mask); - - if (sigaction(SIGIO, &sa, NULL)) - return -1; - - if (fcntl(sock, F_SETOWN, getpid()) < 0) - return -1; - - if (fcntl(sock, F_SETSIG, SIGIO) < 0) - return -1; - - return 0; -} - -int main(int argc, char** argv) { - const char* this_ip; - - if (argc != 4) { - printf("usage: %s \n", argv[0]); - return -1; - } - - this_ip = argv[3]; - - init_socket(inet_addr(argv[1]), atoi(argv[2])); - - /* set timeout for name probing */ - struct timeval tv; - tv.tv_sec = 1; - tv.tv_usec = 0; - setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); - - DEBUG("probing for name…"); - /* send HELLO */ - sendto(sockfd, this_ip, strlen(this_ip), 0, (struct sockaddr*) &servaddr, sizeof(servaddr)); - /* get our name */ - char this_name[32]; - ssize_t size = recvfrom(sockfd, this_name, sizeof this_name, 0, 0, 0); - if (size < 0) { - strcpy(this_name, "(null)"); - } else - this_name[size] = 0; - -#ifdef ENABLE_NAME - local_name = strdup(this_name); -#endif - - node_init(); - - get_local_addr()->_type = AF_INET6; - get_local_addr()->_prefix_len = 128; - inet_pton(AF_INET6, this_ip, get_local_addr()->_addr); - - DEBUG("This is node %s with IP %s", - local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); - - reader_init(); - writer_init(write_packet); - - /* Initialize the signal mask. */ - sigemptyset (&block_io); - sigaddset (&block_io, SIGIO); - - enable_asynch(sockfd); - - bool dont_skip_tc = true; - while (1) { - /* TC messages have a longer interval */ - dont_skip_tc = !dont_skip_tc; - sleep_s(HELLO_REFRESH_INTERVAL); - - disable_receive(); - - // print_neighbors(); - print_topology_set(); - print_routing_graph(); - - writer_send_hello(); - if (dont_skip_tc) - writer_send_tc(); - - DEBUG_TICK; - enable_receive(); - } - - reader_cleanup(); - writer_cleanup(); - - return 0; -} - -#endif /* no RIOT */ diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index befd266cb6b4..a9bb0c7e3d66 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -39,10 +39,13 @@ static struct olsr_node* _node_replace(struct olsr_node* old_n) { if (_free_node) add_free_node(new_n); + new_n->pending = 1; + h1_deriv(new_n)->link_quality = HYST_SCALING; + return new_n; } -struct olsr_node* add_neighbor(struct netaddr* addr, uint8_t vtime, char* name) { +struct olsr_node* add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name) { struct olsr_node* n = get_node(addr); if (n == NULL) { @@ -61,6 +64,7 @@ struct olsr_node* add_neighbor(struct netaddr* addr, uint8_t vtime, char* name) n->type = NODE_TYPE_NHDP; n->distance = 1; + n->link_metric = metric; h1_deriv(n)->link_quality = HYST_SCALING; n->pending = 1; #ifdef ENABLE_NAME @@ -80,7 +84,7 @@ struct olsr_node* add_neighbor(struct netaddr* addr, uint8_t vtime, char* name) if (n->next_addr == NULL) n->expires = time_now() + vtime; - add_other_route(n, get_local_addr(), vtime); + add_other_route(n, get_local_addr(), 1, metric, vtime); return n; } @@ -92,10 +96,11 @@ void print_neighbors(void) { DEBUG("1-hop neighbors:"); avl_for_each_element(get_olsr_head(), node, node) { if (node->distance == 1 && node->type == NODE_TYPE_NHDP) - DEBUG("\tneighbor: %s (%s) (mpr for %d nodes)", + DEBUG("\tneighbor: %s (%s) (mpr for [%d|%d] nodes)", node->name, netaddr_to_str_s(&nbuf[0], node->addr), - h1_deriv(node)->mpr_neigh); + h1_deriv(node)->mpr_neigh_flood, + h1_deriv(node)->mpr_neigh_route); } DEBUG("2-hop neighbors:"); diff --git a/sys/net/routing/olsr2/nhdp.h b/sys/net/routing/olsr2/nhdp.h index 7e5dd33a7a20..b63a6761bdc0 100644 --- a/sys/net/routing/olsr2/nhdp.h +++ b/sys/net/routing/olsr2/nhdp.h @@ -6,7 +6,7 @@ #include "node.h" -struct olsr_node* add_neighbor(struct netaddr* addr, uint8_t vtime, char* name); +struct olsr_node* add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name); void print_neighbors(void); diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index b99473a5ab65..98ab7d401b8b 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -13,6 +13,7 @@ #include "debug.h" #include "common/netaddr.h" +#include "rfc5444/rfc5444.h" static struct netaddr_rc local_addr; static struct avl_tree olsr_head; @@ -22,12 +23,21 @@ char* local_name; #endif static void _decrease_mpr_neigh(struct olsr_node* node) { - /* update MPR information */ - if (node->distance == 2) { - struct nhdp_node* n1 = h1_deriv(get_node(node->last_addr)); - if (n1 != NULL && n1->mpr_neigh > 0) - n1->mpr_neigh--; - } + TRACE_FUN("%s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); + + /* only consider 2-hop nieghbors (only 2-hop neighbors have flood_mpr set) */ + if (node->flood_mpr == NULL) + return; + + /* update routing MPR information */ + struct nhdp_node* n1 = h1_deriv(get_node(node->next_addr)); + if (n1 != NULL && n1->mpr_neigh_route > 0) + n1->mpr_neigh_route--; + + /* update flooding MPR information */ + struct nhdp_node* n1_f = h1_deriv(get_node(node->flood_mpr)); + if (n1_f != NULL && n1_f->mpr_neigh_flood > 0) + n1_f->mpr_neigh_flood--; } static int _addr_cmp(const void* a, const void* b) { @@ -58,9 +68,26 @@ struct olsr_node* get_node(struct netaddr* addr) { return avl_find_element(get_olsr_head(), addr, n, node); } -void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t vtime) { +metric_t get_link_metric(struct olsr_node* node, struct netaddr* last_addr) { + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + return node->link_metric; + + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + + if (route == NULL) + return RFC5444_METRIC_INFINITE; + + return route->link_metric; +} + +void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t distance, metric_t metric, uint8_t vtime) { /* make sure the route is not already the default route */ if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { + if (node->next_addr != NULL) { + // TODO: a different route might be better now + node->path_metric -= node->link_metric - metric; + node->link_metric = metric; + } node->expires = time_now() + vtime; return; } @@ -68,6 +95,7 @@ void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); if (route != NULL) { route->expires = time_now() + vtime; + route->link_metric = metric; return; } @@ -80,11 +108,25 @@ void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t route->last_addr = netaddr_reuse(last_addr); route->expires = time_now() + vtime; + route->link_metric = metric; + + /* if we add a route for the first time, increment flood_neighbors */ + if (distance == 2 && node->type != NODE_TYPE_NHDP) { + struct nhdp_node* n1 = h1_deriv(get_node(last_addr)); + if (n1 != NULL) + n1->flood_neighbors++; + } + } void remove_default_node(struct olsr_node* node) { if (node->last_addr) { _decrease_mpr_neigh(node); + + struct nhdp_node* mpr = h1_deriv(get_node(node->last_addr)); + if (mpr != NULL) + mpr->flood_neighbors--; + node->last_addr = netaddr_free(node->last_addr); } @@ -103,6 +145,7 @@ void push_default_route(struct olsr_node* node) { _decrease_mpr_neigh(node); struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + /* don't add route if it already exists - this should never happen, right? */ if (route != NULL) { node->last_addr = netaddr_free(node->last_addr); return; @@ -117,6 +160,7 @@ void push_default_route(struct olsr_node* node) { route->expires = node->expires; route->last_addr = node->last_addr; + route->link_metric = node->link_metric; node->last_addr = NULL; } @@ -129,18 +173,26 @@ void pop_other_route(struct olsr_node* node, struct netaddr* last_addr) { node->last_addr = route->last_addr; node->expires = route->expires; + node->link_metric = route->link_metric; simple_list_for_each_remove(&node->other_routes, route, prev); break; } } void remove_other_route(struct olsr_node* node, struct netaddr* last_addr) { + TRACE_FUN("%s (%s), %s", netaddr_to_str_s(&nbuf[0], node->addr), node->name, + netaddr_to_str_s(&nbuf[1], last_addr)); + char skipped; struct alt_route *route, *prev; simple_list_for_each_safe(node->other_routes, route, prev, skipped) { if (netaddr_cmp(route->last_addr, last_addr)) continue; + struct nhdp_node* mpr = h1_deriv(get_node(route->last_addr)); + if (mpr != NULL) + mpr->flood_neighbors--; + netaddr_free(route->last_addr); simple_list_for_each_remove(&node->other_routes, route, prev); break; diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index a3ff9891c236..bdb592943d36 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -19,11 +19,14 @@ enum { NODE_TYPE_NHDP }; +typedef uint32_t metric_t; + /* simple list to store alternative routes */ struct alt_route { struct alt_route* next; struct netaddr* last_addr; + metric_t link_metric; time_t expires; }; @@ -38,10 +41,12 @@ struct olsr_node { time_t expires; /* time when this tuple is invalid */ uint16_t seq_no; /* last seq_no from last_addr */ uint8_t distance; /* hops between us and the node */ + metric_t link_metric; + metric_t path_metric; + struct netaddr* flood_mpr; /* flooding MPR to broadcast to this node (used for couting mpr_neigh_flood), 2-hop only */ uint8_t type : 1; /* node type */ - uint8_t mpr_selector: 2; /* whether the node selected us as a MPR - only 1-hop */ - uint8_t pending : 3; /* whether the link can already be used - only 1-hop */ + uint8_t pending : 1; /* whether the link can already be used - only 1-hop */ uint8_t lost : 4; /* [4 bit] if set, the node will be annouced as lost - only 1-hop */ #ifdef ENABLE_NAME @@ -52,14 +57,24 @@ struct olsr_node { struct nhdp_node { struct olsr_node super; - /* number of 2-hop neighbors reached through this node aka if this value is > 0, it's a MPR */ - uint8_t mpr_neigh; + uint8_t mpr_slctr_flood: 1; /* whether the node selected us as a flooding MPR */ + + uint8_t mpr_slctr_route: 1; /* whether the node selected us as a routing MPR */ + + /* number of --hop neighbors broadcast messages from this this node can reach */ + uint8_t flood_neighbors; + + /* number of 2-hop neighbors reached if this node is used as flooding MPR */ + uint8_t mpr_neigh_flood; + + /* number of 2-hop neighbors reached through this node aka if this value is > 0, it's a routing MPR */ + uint8_t mpr_neigh_route; /* average packet loss, decides if it should be used as 1-hop neigh */ float link_quality; }; -static inline struct olsr_node* h1_super(struct nhdp_node* n) { return (struct olsr_node*) n; } +static inline struct olsr_node* h1_super(struct nhdp_node* n) { return (struct olsr_node*) n; } static inline struct nhdp_node* h1_deriv(struct olsr_node* n) { if (n == NULL) return 0; @@ -75,8 +90,9 @@ struct netaddr* get_local_addr(void); struct avl_tree* get_olsr_head(void); int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b); struct olsr_node* get_node(struct netaddr* addr); +metric_t get_link_metric(struct olsr_node* node, struct netaddr* last_addr); -void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t vtime); +void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t distance, metric_t metric, uint8_t vtime); void remove_other_route(struct olsr_node* node, struct netaddr* last_addr); void remove_default_node(struct olsr_node* node); void push_default_route(struct olsr_node* node); diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index ee5525ac67f7..fc105e3b37de 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -14,6 +14,7 @@ #endif #include "common/netaddr.h" +#include "rfc5444/rfc5444.h" #include "olsr.h" #include "util.h" @@ -23,7 +24,7 @@ #include "list.h" static struct olsr_node* _new_olsr_node(struct netaddr* addr, - uint8_t distance, uint8_t vtime, char* name) { + uint8_t distance, metric_t metric, uint8_t vtime, char* name) { struct olsr_node* n = calloc(1, sizeof(struct olsr_node)); @@ -40,6 +41,7 @@ static struct olsr_node* _new_olsr_node(struct netaddr* addr, n->node.key = n->addr; n->type = NODE_TYPE_OLSR; n->distance = distance; + n->link_metric = metric; n->expires = time_now() + vtime; #ifdef ENABLE_NAME if (name) @@ -50,6 +52,39 @@ static struct olsr_node* _new_olsr_node(struct netaddr* addr, return n; } +static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) { + TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], old_flood_mpr)); + struct olsr_node *node; + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance != 2) + continue; + if (node->flood_mpr != NULL && netaddr_cmp(old_flood_mpr, node->flood_mpr) != 0) + continue; + + DEBUG("chosing new flood MPR for %s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); + + struct nhdp_node *mpr_b, *mpr_a = h1_deriv(get_node(node->last_addr)); + struct alt_route *route; + simple_list_for_each(node->other_routes, route) { + mpr_b = h1_deriv(get_node(route->last_addr)); + if (mpr_b == NULL || h1_super(mpr_b)->pending) + continue; + if (mpr_a == NULL || h1_super(mpr_a)->pending || mpr_a->flood_neighbors < mpr_b->flood_neighbors) + mpr_a = mpr_b; + } + + if (mpr_a != NULL) { + mpr_a->mpr_neigh_flood++; + + netaddr_switch(&node->flood_mpr, h1_super(mpr_a)->addr); + DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + } else + node->flood_mpr = netaddr_free(node->flood_mpr); + + DEBUG("\tnew flood MPR: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + } +} + /* * find a new route for nodes that use last_addr as their default route * if lost_node_addr is not null, all reference to it will be removed (aka lost node) @@ -61,8 +96,11 @@ static void _update_children(struct netaddr* last_addr, struct netaddr* lost_nod struct olsr_node *node; avl_for_each_element(get_olsr_head(), node, node) { - if (lost_node_addr != NULL) + if (lost_node_addr != NULL) { remove_other_route(node, lost_node_addr); + if (node->flood_mpr != NULL && netaddr_cmp(lost_node_addr, node->flood_mpr) == 0) + node->flood_mpr = netaddr_free(node->flood_mpr); + } if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { @@ -103,6 +141,8 @@ static void _remove_olsr_node(struct olsr_node* node) { simple_list_for_each_remove(&node->other_routes, route, prev); } + netaddr_free(node->flood_mpr); + remove_default_node(node); _update_children(node->addr, node->addr); @@ -139,7 +179,12 @@ static void _update_link_quality(struct nhdp_node* node) { if (!h1_super(node)->pending && node->link_quality < HYST_LOW) { h1_super(node)->pending = 1; h1_super(node)->lost = LOST_ITER_MAX; - node->mpr_neigh = 0; + + if (node->mpr_neigh_flood > 0) + _get_new_flood_mpr(h1_super(node)->addr); + + node->mpr_neigh_flood = 0; + node->mpr_neigh_route = 0; add_free_node(h1_super(node)); push_default_route(h1_super(node)); @@ -151,9 +196,7 @@ static void _update_link_quality(struct nhdp_node* node) { h1_super(node)->lost = 0; /* node may just have become a 1-hop node */ - if (h1_super(node)->last_addr != NULL) - push_default_route(h1_super(node)); - + push_default_route(h1_super(node)); add_free_node(h1_super(node)); } } @@ -196,124 +239,109 @@ void route_expired(struct olsr_node* node, struct netaddr* last_addr) { node->name, netaddr_to_str_s(&nbuf[0], node->addr), netaddr_to_str_s(&nbuf[1], last_addr)); - if (node->last_addr == NULL || netaddr_cmp(node->last_addr, last_addr) != 0) { + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + _olsr_node_expired(node); + else remove_other_route(node, last_addr); - if (node->other_routes == NULL) - _remove_olsr_node(node); - return; - } - if (node->other_routes == NULL) + if (node->last_addr == NULL && node->other_routes == NULL) _remove_olsr_node(node); - else - _olsr_node_expired(node); } -void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, char* name) { +void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char* name) { struct olsr_node* n = get_node(addr); if (n == NULL) - n = _new_olsr_node(addr, distance, vtime, name); + n = _new_olsr_node(addr, distance, metric, vtime, name); if (n == NULL) { puts("ERROR: add_olsr_node failed - out of memory"); return; } + /* we have added a new node */ if (n->last_addr == NULL) { #ifdef ENABLE_NAME if (n->name == NULL && name != NULL) n->name = strdup(name); #endif - add_other_route(n, last_addr, vtime); + add_other_route(n, last_addr, distance, metric, vtime); add_free_node(n); return; } + struct olsr_node* new_lh = get_node(last_addr); + /* minimize MPR count */ - if (distance == 2 && distance == n->distance && netaddr_cmp(last_addr, n->last_addr) != 0) { - struct nhdp_node* cur_mpr = h1_deriv(get_node(n->last_addr)); - struct nhdp_node* new_mpr = h1_deriv(get_node(last_addr)); - - /* see if the new route is better, that means uses a neighbor that is alreay - used for reaching (more) 2-hop neighbors. */ - if (cur_mpr == NULL || (new_mpr != NULL && - new_mpr->mpr_neigh + 1 > cur_mpr->mpr_neigh)) { - DEBUG("switching MPR"); - _update_children(n->addr, NULL); - push_default_route(n); - add_free_node(n); + if (new_lh->type == NODE_TYPE_NHDP) { + + /* see if a better flooding MPR is availiable */ + if (n->flood_mpr != NULL && netaddr_cmp(n->flood_mpr, last_addr) != 0) { + struct nhdp_node* old_flood_mpr = h1_deriv(get_node(n->flood_mpr)); + + if (old_flood_mpr != NULL && h1_deriv(new_lh)->flood_neighbors > old_flood_mpr->flood_neighbors) { + DEBUG("switching flooding MPR (%s -> %s)", h1_super(old_flood_mpr)->name, new_lh->name); + old_flood_mpr->mpr_neigh_flood--; + h1_deriv(new_lh)->mpr_neigh_flood++; + netaddr_switch(&n->flood_mpr, last_addr); + } + } + + /* see if a better routing MPR is availiable */ + if (new_lh->path_metric + metric == n->path_metric && netaddr_cmp(last_addr, n->last_addr) != 0) { + struct nhdp_node* cur_mpr = h1_deriv(get_node(n->next_addr)); + + /* see if the new route is better, that means uses a neighbor that is alreay + used for reaching (more) 2-hop neighbors. */ + if (cur_mpr != NULL && (new_lh != NULL && + h1_deriv(new_lh)->mpr_neigh_route + 1 > cur_mpr->mpr_neigh_route)) { + DEBUG("switching routing MPR (%s -> %s)", h1_super(cur_mpr)->name, new_lh->name); + _update_children(n->addr, NULL); + push_default_route(n); + add_free_node(n); + } } } - if (distance >= n->distance) { - add_other_route(n, last_addr, vtime); + /* worse or same route */ + if (new_lh->path_metric + metric >= n->path_metric || netaddr_cmp(last_addr, n->last_addr) == 0) { + add_other_route(n, last_addr, distance, metric, vtime); return; } - DEBUG("shorter route found (old: %d hops over %s new: %d hops over %s)", - n->distance, netaddr_to_str_s(&nbuf[0], n->last_addr), - distance, netaddr_to_str_s(&nbuf[1], last_addr)); + DEBUG("better route found (old: %d (%d) hops over %s new: %d (%d) hops over %s)", + n->distance, n->path_metric, netaddr_to_str_s(&nbuf[0], n->last_addr), + distance, new_lh->path_metric + metric, netaddr_to_str_s(&nbuf[1], last_addr)); - n->distance = distance; + n->distance = distance; // only to keep free_nodes sorted _update_children(n->addr, NULL); push_default_route(n); - add_other_route(n, last_addr, vtime); + add_other_route(n, last_addr, distance, metric, vtime); add_free_node(n); } bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) { struct olsr_node* node = get_node(addr); if (!node) { - node = _new_olsr_node(addr, 255, vtime, NULL); + node = _new_olsr_node(addr, 255, RFC5444_METRIC_INFINITE, vtime, NULL); node->seq_no = seq_no; return false; } uint16_t tmp = node->seq_no; - node->seq_no = seq_no; /* S1 > S2 AND S1 - S2 < MAXVALUE/2 OR S2 > S1 AND S2 - S1 > MAXVALUE/2 */ if ((seq_no > tmp && seq_no - tmp < (1 << 15)) || - (seq_no < tmp && tmp - seq_no > (1 << 15)) ) + (seq_no < tmp && tmp - seq_no > (1 << 15)) ) { + node->seq_no = seq_no; return false; + } return true; } -#ifdef ENABLE_DEBUG_OLSR -void print_topology_set(void) { - DEBUG(); - DEBUG("---[ Topology Set ]--"); - DEBUG(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), local_name); - - struct olsr_node* node; - struct alt_route* route; - avl_for_each_element(get_olsr_head(), node, node) { - DEBUG("%s (%s)\t=> %s; %d hops, next: %s, %ld s [%d] %s %.2f [%d] %s", - netaddr_to_str_s(&nbuf[0], node->addr), - node->name, - netaddr_to_str_s(&nbuf[1], node->last_addr), - node->distance, - netaddr_to_str_s(&nbuf[2], node->next_addr), - node->expires - time_now(), - node->seq_no, - node->type != NODE_TYPE_NHDP ? "" : node->pending ? "pending" : "", - node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->link_quality, - node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->mpr_neigh, - node->type != NODE_TYPE_NHDP ? "" : node->mpr_selector ? "[S]" : "[ ]" - ); - simple_list_for_each (node->other_routes, route) { - DEBUG("\t\t\t=> %s; %ld s", - netaddr_to_str_s(&nbuf[0], route->last_addr), - route->expires - time_now()); - } - } - DEBUG("---------------------"); - DEBUG(); -} - +#ifdef ENABLE_NAME void print_routing_graph(void) { puts("\n----BEGIN ROUTING GRAPH----\n"); puts("subgraph routing {"); @@ -327,23 +355,39 @@ void print_routing_graph(void) { } puts("}"); - puts("subgraph mpr {"); + puts("subgraph mpr_f {"); + puts("\tedge [ color = green ]"); + puts("// BEGIN FLOODING MPR"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->type == NODE_TYPE_NHDP && h1_deriv(node)->mpr_slctr_flood) { + printf("\t%s -> %s\n", node->name, local_name); + } + } + puts("// END FLOODING MPR"); + puts("}"); + + puts("subgraph mpr_r {"); puts("\tedge [ color = blue ]"); - puts("// BEGIN MPR"); + puts("// BEGIN ROUTING MPR"); avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance == 1 && node->mpr_selector) { + if (node->distance == 1 && h1_deriv(node)->mpr_slctr_route) { printf("\t%s -> %s\n", node->name, local_name); } } - puts("// END MPR"); + puts("// END ROUTING MPR"); puts("}"); puts("\n----END ROUTING GRAPH----\n"); } #else +void print_routing_graph(void) {} +#endif + void print_topology_set(void) { +#ifndef ENABLE_DEBUG_OLSR struct netaddr_str nbuf[3]; +#endif struct alt_route* route; struct olsr_node* node; @@ -357,33 +401,40 @@ void print_topology_set(void) { #endif avl_for_each_element(get_olsr_head(), node, node) { + + printf("%s ", netaddr_to_str_s(&nbuf[0], node->addr)); #ifdef ENABLE_NAME - printf("%s (%s)\t=> %s; %d hops, next: %s, %ld s [%d] %s %.2f [%d] %s\n", -#else - printf("%s\t=> %s; %d hops, next: %s, %ld s [%d] %s %.2f [%d] %s\n", -#endif - netaddr_to_str_s(&nbuf[0], node->addr), -#ifdef ENABLE_NAME - node->name, + printf("(%s)", node->name); #endif + printf("\t=> %s; %d hops, metric: %d, next: %s (%d), %lds ", netaddr_to_str_s(&nbuf[1], node->last_addr), node->distance, + node->path_metric, netaddr_to_str_s(&nbuf[2], node->next_addr), - node->expires - time_now(), - node->seq_no, - node->type != NODE_TYPE_NHDP ? "" : node->pending ? "pending" : "", - node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->link_quality, - node->type != NODE_TYPE_NHDP ? 0 : h1_deriv(node)->mpr_neigh, - node->type != NODE_TYPE_NHDP ? "" : node->mpr_selector ? "[S]" : "[ ]" + node->link_metric, + node->expires - time_now()); + if (node->type == NODE_TYPE_NHDP) { + printf("%s %.2f ", + node->pending ? "pending" : "", + h1_deriv(node)->link_quality); + printf("[%d/%d|%d] [%s%s]", + h1_deriv(node)->mpr_neigh_flood, + h1_deriv(node)->flood_neighbors, + h1_deriv(node)->mpr_neigh_route, + h1_deriv(node)->mpr_slctr_flood ? "F" : " ", + h1_deriv(node)->mpr_slctr_route ? "R" : " " ); + } + if (node->flood_mpr != NULL) + printf(" flood: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + puts(""); + simple_list_for_each (node->other_routes, route) { - printf("\t\t\t=> %s; %ld s\n", + printf("\t\t\t=> %s (%d); %ld s\n", netaddr_to_str_s(&nbuf[0], route->last_addr), + route->link_metric, route->expires - time_now()); } } puts("---------------------"); - } -void print_routing_graph(void) {} -#endif diff --git a/sys/net/routing/olsr2/olsr.h b/sys/net/routing/olsr2/olsr.h index fe666d10afcf..36a293f7b16b 100644 --- a/sys/net/routing/olsr2/olsr.h +++ b/sys/net/routing/olsr2/olsr.h @@ -8,7 +8,7 @@ #include "node.h" -void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, char* name); +void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char* name); bool is_known_msg(struct netaddr* src, uint16_t seq_no, uint8_t vtime); bool remove_expired(struct olsr_node* node); void route_expired(struct olsr_node* node, struct netaddr* last_addr); diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index dfdea5e263ff..ddaa02a34712 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -102,7 +102,7 @@ static void olsr_receiver_thread(void) { DEBUG("received %d bytes from %s", recsize, netaddr_to_str_s(&nbuf[0], &_src)); mutex_lock(&olsr_data); - reader_handle_packet(&buffer, recsize, &_src); + reader_handle_packet(&buffer, recsize, &_src, 1); // TODO: proper metric mutex_unlock(&olsr_data); } } diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 02bb69956ec2..72e8f8a76ebf 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -29,12 +29,13 @@ static struct rfc5444_reader reader; static struct netaddr* current_src; -static struct olsr_node* current_node; +static struct olsr_node* current_node; // only set by _cb_nhdp_blocktlv_packet_okay /* ughh… these variables are needed in the addr callback, but read in the packet callback */ static uint8_t vtime; static uint8_t hops; static uint16_t _seq_no; +static metric_t metric; static enum rfc5444_result _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont); static enum rfc5444_result _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont); @@ -42,6 +43,8 @@ static enum rfc5444_result _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_ static enum rfc5444_result _cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont); static enum rfc5444_result _cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont); +static enum rfc5444_result _cb_packet_end(struct rfc5444_reader_tlvblock_context *cont, bool dropped); + /* HELLO message */ static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_message_tlvs[] = { [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, @@ -53,6 +56,7 @@ static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_message_tlvs[] = { static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_address_tlvs[] = { [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif @@ -68,6 +72,7 @@ static struct rfc5444_reader_tlvblock_consumer_entry _olsr_message_tlvs[] = { static struct rfc5444_reader_tlvblock_consumer_entry _olsr_address_tlvs[] = { [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif @@ -77,6 +82,7 @@ static struct rfc5444_reader_tlvblock_consumer_entry _olsr_address_tlvs[] = { static struct rfc5444_reader_tlvblock_consumer _nhdp_consumer = { .msg_id = RFC5444_MSGTYPE_HELLO, .block_callback = _cb_nhdp_blocktlv_packet_okay, + .end_callback = _cb_packet_end, }; static struct rfc5444_reader_tlvblock_consumer _nhdp_address_consumer = { @@ -89,6 +95,7 @@ static struct rfc5444_reader_tlvblock_consumer _nhdp_address_consumer = { static struct rfc5444_reader_tlvblock_consumer _olsr_consumer = { .msg_id = RFC5444_MSGTYPE_TC, .block_callback = _cb_olsr_blocktlv_packet_okay, + .end_callback = _cb_packet_end, }; static struct rfc5444_reader_tlvblock_consumer _olsr_address_consumer = { @@ -116,7 +123,9 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att } #endif - current_node = add_neighbor(current_src, vtime, name); + DEBUG("\tmetric: %d", metric); + + current_node = add_neighbor(current_src, metric, vtime, name); if (current_node == NULL) { puts("ERROR: add_neighbor failed - out of memory"); @@ -124,7 +133,8 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att } /* reset MPR selector state, will be set by _cb_nhdp_blocktlv_address_okay */ - current_node->mpr_selector = 0; + h1_deriv(current_node)->mpr_slctr_route = 0; + h1_deriv(current_node)->mpr_slctr_flood = 0; if (current_node->pending) return RFC5444_DROP_PACKET; @@ -136,6 +146,7 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att static enum rfc5444_result _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { struct rfc5444_reader_tlvblock_entry* tlv; + metric_t link_metric = RFC5444_METRIC_MIN; char* name = NULL; #ifdef ENABLE_NAME @@ -145,19 +156,24 @@ _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { } #endif + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { + link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); + DEBUG("\t\tmetric: %d", link_metric); + } + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { switch (* (char*) tlv->single_value) { struct olsr_node* lost; case RFC5444_LINKSTATUS_LOST: lost = get_node(&cont->addr); - DEBUG("\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); + DEBUG("\t\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); if (lost != NULL) route_expired(lost, current_node->addr); return RFC5444_DROP_ADDRESS; default: - DEBUG("\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + DEBUG("\t\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); } } @@ -165,11 +181,15 @@ _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { if (netaddr_cmp(&cont->addr, get_local_addr()) == 0) { /* node selected us as mpr */ - if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_MPR].tlv)) - current_node->mpr_selector = 1; + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_MPR].tlv)) { + h1_deriv(current_node)->mpr_slctr_flood = (*tlv->single_value & RFC5444_MPR_FLOODING) > 0; + h1_deriv(current_node)->mpr_slctr_route = (*tlv->single_value & RFC5444_MPR_ROUTING) > 0; + + DEBUG("\tflood: %d, route: %d", h1_deriv(current_node)->mpr_slctr_flood, h1_deriv(current_node)->mpr_slctr_route); + } } else - add_olsr_node(&cont->addr, current_src, vtime, 2, name); + add_olsr_node(&cont->addr, current_src, vtime, 2, link_metric, name); return RFC5444_OKAY; } @@ -214,6 +234,7 @@ _cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont) { static enum rfc5444_result _cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { struct rfc5444_reader_tlvblock_entry* tlv __attribute__((unused)); + metric_t link_metric = RFC5444_METRIC_MIN; char* name = NULL; if (netaddr_cmp(get_local_addr(), &cont->addr) == 0) @@ -234,7 +255,12 @@ _cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { DEBUG("\texpired node reported, removing it (TC)%s", lost ? "" : " [not found]"); if (lost != NULL) - route_expired(lost, current_node->addr); + route_expired(lost, &cont->orig_addr); + + /* emergency flood */ + struct nhdp_node* node = h1_deriv(get_node(current_src)); + if (node != NULL) + node->mpr_slctr_flood = 1; return RFC5444_DROP_ADDRESS; default: @@ -242,8 +268,20 @@ _cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { } } + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { + link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); + DEBUG("\t\tmetric: %d", link_metric); + } + /* hops is hopcount to orig_addr, addr is one more hop */ - add_olsr_node(&cont->addr, &cont->orig_addr, vtime, hops + 1, name); + add_olsr_node(&cont->addr, &cont->orig_addr, vtime, hops + 1, link_metric, name); + + return RFC5444_OKAY; +} + +static enum rfc5444_result +_cb_packet_end(struct rfc5444_reader_tlvblock_context *cont __attribute__((unused)), bool dropped __attribute__((unused))) { + fill_routing_table(); return RFC5444_OKAY; } @@ -254,13 +292,14 @@ _cb_olsr_forward_message(struct rfc5444_reader_tlvblock_context *context __attri uint8_t *buffer, size_t length) { struct olsr_node* node = get_node(current_src); - /* only forward if node selected us as MPR */ - if (node == NULL || node->mpr_selector == 0) + /* only forward if node selected us as flooding MPR */ + if (node == NULL || h1_deriv(node)->mpr_slctr_flood == 0) return; - if (RFC5444_OKAY == rfc5444_writer_forward_msg(&writer, buffer, length)) + if (RFC5444_OKAY == rfc5444_writer_forward_msg(&writer, buffer, length)) { + DEBUG("\tforwarding"); rfc5444_writer_flush(&writer, &interface, true); - else + } else DEBUG("\tfailed forwarding package"); } @@ -284,8 +323,9 @@ void reader_init(void) { /** * Inject a package into the RFC5444 reader */ -int reader_handle_packet(void* buffer, size_t length, struct netaddr* src) { +int reader_handle_packet(void* buffer, size_t length, struct netaddr* src, uint8_t metric_in) { current_src = src; + metric = metric_in; return rfc5444_reader_handle_packet(&reader, buffer, length); } diff --git a/sys/net/routing/olsr2/reader.h b/sys/net/routing/olsr2/reader.h index cac510f0f3d5..02ba94a92c48 100644 --- a/sys/net/routing/olsr2/reader.h +++ b/sys/net/routing/olsr2/reader.h @@ -5,7 +5,7 @@ #include "rfc5444/rfc5444_reader.h" void reader_init(void); -int reader_handle_packet(void* buffer, size_t length, struct netaddr* src); +int reader_handle_packet(void* buffer, size_t length, struct netaddr* src, uint8_t metric_in); void reader_cleanup(void); #endif /* READER_H_ */ diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index 0820d3d5249e..a0dcb76b13b5 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -15,6 +15,7 @@ #include "util.h" #include "routing.h" #include "constants.h" +#include "rfc5444/rfc5444.h" /* sorted list, only for faster access * Keeps yet unroutable nodes, so we don't have to traverse the entire list @@ -69,52 +70,91 @@ void fill_routing_table(void) { struct free_node *prev; char skipped; simple_list_for_each_safe(head, fn, prev, skipped) { + DEBUG("trying to find a route to %s", fn->node->name); /* chose shortest route from the set of availiable routes */ - uint8_t min_hops = 255; - struct olsr_node* node = NULL; - struct alt_route* route; + metric_t min_mtrc = RFC5444_METRIC_INFINITE; + struct olsr_node* node = NULL; /* chosen route */ + struct nhdp_node* flood_mpr = NULL; + struct alt_route* route; /* current other_route */ simple_list_for_each(fn->node->other_routes, route) { + DEBUG("\tconsidering %s (%d)", netaddr_to_string(&nbuf[0], route->last_addr), route->link_metric); /* the node is actually a neighbor of ours */ if (netaddr_cmp(route->last_addr, get_local_addr()) == 0) { + DEBUG("\t\t1-hop neighbor"); + /* don't use pending nodes */ - if (fn->node->pending) + if (fn->node->pending) { + DEBUG("\t\tpending -> skipped"); continue; + } - min_hops = 1; - break; + if (route->link_metric > min_mtrc) + continue; + + min_mtrc = route->link_metric; + node = fn->node; + continue; } /* see if we can find a better route */ struct olsr_node* _tmp = get_node(route->last_addr); - if (_tmp != NULL && _tmp->addr != NULL && - _tmp->distance + 1 <= min_hops && - _tmp->next_addr != NULL) { + if (_tmp == NULL || _tmp->addr == NULL || _tmp->next_addr == NULL) { + DEBUG("\t\tnot routable"); + continue; + } - if (_tmp->next_addr == NULL) - continue; - /* ignore pending nodes */ - if (_tmp->distance == 1 && _tmp->pending) - continue; + /* ignore pending nodes */ + if (_tmp->distance == 1 && _tmp->pending) { + DEBUG("\t\tpending -> skipped"); + continue; + } - /* try to minimize MPR count */ - if (min_hops == 2) { - /* use the neighbor with the most 2-hop neighbors */ - if (h1_deriv(node)->mpr_neigh > h1_deriv(_tmp)->mpr_neigh + 1) - continue; - } + /* flooding MPR selection */ + if (_tmp->type == NODE_TYPE_NHDP && + (flood_mpr == NULL || flood_mpr->flood_neighbors < h1_deriv(_tmp)->flood_neighbors)) + flood_mpr = h1_deriv(_tmp); - node = _tmp; - min_hops = _tmp->distance + 1; + if (_tmp->path_metric + route->link_metric > min_mtrc) { + DEBUG("\t\tdoesn't offer a better route, %d + %d > %d", _tmp->path_metric, route->link_metric, min_mtrc); + continue; } - } + + /* try to minimize MPR count */ + if (_tmp->type == NODE_TYPE_NHDP && min_mtrc == _tmp->path_metric + route->link_metric) { + DEBUG("\t\tequaly good route found, try to optimize MPR seleciton"); + struct nhdp_node* old_mpr = h1_deriv(node); + + /* a direct neighbor might be reached over an additional hop, the true MPR */ + if (netaddr_cmp(_tmp->next_addr, _tmp->addr) != 0) + old_mpr = h1_deriv(get_node(_tmp->next_addr)); + + /* use the neighbor with the most 2-hop neighbors */ + if (old_mpr->mpr_neigh_route >= h1_deriv(_tmp)->mpr_neigh_route + 1) { + DEBUG("\t\told MPR (%d) is better (new: %d)", old_mpr->mpr_neigh_route, h1_deriv(_tmp)->mpr_neigh_route); + continue; + } + } + + DEBUG("\t\t[possible candidate]"); + node = _tmp; + min_mtrc = _tmp->path_metric + route->link_metric; + } /* for each other_route */ + + if (flood_mpr != NULL) { + netaddr_switch(&fn->node->flood_mpr, h1_super(flood_mpr)->addr); + DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], fn->node->flood_mpr)); + flood_mpr->mpr_neigh_flood++; + } else + fn->node->flood_mpr = netaddr_free(fn->node->flood_mpr); /* We found a valid route */ - if (min_hops == 1) { - DEBUG("%s (%s) is a 1-hop neighbor", + if (node == fn->node) { + DEBUG("\t%s (%s) is a 1-hop neighbor", netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name); noop = false; fn->node->next_addr = netaddr_use(fn->node->addr); + fn->node->path_metric = fn->node->link_metric; fn->node->distance = 1; fn->node->lost = 0; @@ -122,7 +162,7 @@ void fill_routing_table(void) { simple_list_for_each_remove(&head, fn, prev); } else if (node != NULL) { - DEBUG("%s (%s) -> %s (%s) -> […] -> %s", + DEBUG("\t%s (%s) -> %s (%s) -> […] -> %s", netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name, netaddr_to_str_s(&nbuf[1], node->addr), node->name, netaddr_to_str_s(&nbuf[2], node->next_addr)); @@ -130,18 +170,21 @@ void fill_routing_table(void) { noop = false; - /* update MPR information */ - if (node->distance == 1) { - h1_deriv(node)->mpr_neigh++; + /* update routing MPR information */ + if (node->type == NODE_TYPE_NHDP || fn->node->flood_mpr != NULL) { + struct nhdp_node* mpr = h1_deriv(get_node(node->next_addr)); + DEBUG("\tincrementing mpr_neigh_route for %s", h1_super(mpr)->name); + mpr->mpr_neigh_route++; } fn->node->distance = node->distance + 1; + fn->node->path_metric = min_mtrc; fn->node->next_addr = netaddr_use(node->next_addr); pop_other_route(fn->node, node->addr); simple_list_for_each_remove(&head, fn, prev); } else - DEBUG("don't yet know how to route %s", netaddr_to_str_s(&nbuf[0], fn->node->addr)); + DEBUG("\tdon't yet know how to route %s", netaddr_to_str_s(&nbuf[0], fn->node->addr)); } } diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 577448269853..0797042a8f72 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -63,6 +63,11 @@ struct netaddr* netaddr_free(struct netaddr* addr) { return NULL; } +void netaddr_switch(struct netaddr** old_addr, struct netaddr* new_addr) { + netaddr_free(*old_addr); + *old_addr = netaddr_reuse(new_addr); +} + time_t time_now(void) { #ifdef RIOT struct timeval _tv; diff --git a/sys/net/routing/olsr2/util.h b/sys/net/routing/olsr2/util.h index da5a7c1b0bf0..e238335a2c2d 100644 --- a/sys/net/routing/olsr2/util.h +++ b/sys/net/routing/olsr2/util.h @@ -14,6 +14,7 @@ struct netaddr* netaddr_dup(struct netaddr* addr); struct netaddr* netaddr_use(struct netaddr* addr); struct netaddr* netaddr_reuse(struct netaddr* addr); struct netaddr* netaddr_free(struct netaddr* addr); +void netaddr_switch(struct netaddr** old_addr, struct netaddr* new_addr); time_t time_now(void); void sleep_s(int secs); diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index d32437cc48fa..d296d0181fbb 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -52,6 +52,7 @@ static struct rfc5444_writer_content_provider _nhdp_message_content_provider = { static struct rfc5444_writer_tlvtype _nhdp_addrtlvs[] = { [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif @@ -66,6 +67,7 @@ static struct rfc5444_writer_content_provider _olsr_message_content_provider = { static struct rfc5444_writer_tlvtype _olsr_addrtlvs[] = { [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif @@ -87,6 +89,7 @@ static void _cb_add_nhdp_addresses(struct rfc5444_writer *wr) { struct olsr_node* node, *safe; int value; + uint8_t mpr; send_tc_messages = false; /* add all neighbors */ @@ -96,22 +99,35 @@ _cb_add_nhdp_addresses(struct rfc5444_writer *wr) { if (remove_expired(node)) continue; - if (node->distance != 1 && !node->lost) + if (node->type != NODE_TYPE_NHDP && !node->lost) continue; if (node->pending && !node->lost) continue; - if (!node->pending && node->mpr_selector) + if (!node->pending && h1_deriv(node)->mpr_slctr_route) send_tc_messages = true; struct rfc5444_writer_address *address = rfc5444_writer_add_address(wr, _nhdp_message_content_provider.creator, node->addr, false); + + mpr = 0; + if (h1_deriv(node)->mpr_neigh_flood > 0) + mpr |= RFC5444_MPR_FLOODING; + + if (h1_deriv(node)->mpr_neigh_route > 0) + mpr |= RFC5444_MPR_ROUTING; - /* node is a mpr */ - if (h1_deriv(node)->mpr_neigh > 0) + if (mpr > 0) rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_MPR], - &h1_deriv(node)->mpr_neigh, sizeof h1_deriv(node)->mpr_neigh, false); + &mpr, sizeof mpr, false); + + metric_t link_metric = get_link_metric(node, get_local_addr()); + if (link_metric > RFC5444_METRIC_MIN) { + uint16_t mtrc = rfc5444_metric_encode(link_metric); + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], + &mtrc, sizeof mtrc, false); + } if (node->lost) { DEBUG("LINKSTATUS: neighbor %s lost (HELLO) [%d]", node->name, node->lost); @@ -149,9 +165,13 @@ _cb_add_olsr_addresses(struct rfc5444_writer *wr) { /* add all neighbors */ avl_for_each_element(get_olsr_head(), node, node) { - if (!node->mpr_selector) + if (h1_deriv(node) == NULL) continue; + if (!h1_deriv(node)->mpr_slctr_route) + continue; + + /* don't advertise neighbors routed over another hop */ if (node->distance != 1 && !node->lost) continue; @@ -161,6 +181,12 @@ _cb_add_olsr_addresses(struct rfc5444_writer *wr) { struct rfc5444_writer_address *address __attribute__((unused)); address = rfc5444_writer_add_address(wr, _olsr_message_content_provider.creator, node->addr, false); + if (node->link_metric > RFC5444_METRIC_MIN) { + uint16_t mtrc = rfc5444_metric_encode(node->link_metric); + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], + &mtrc, sizeof mtrc, false); + } + if (node->lost) { DEBUG("LINKSTATUS: neighbor %s lost (TC) [%d]", node->name, node->lost); value = RFC5444_LINKSTATUS_LOST; @@ -245,8 +271,6 @@ void writer_send_hello(void) { /* send message */ rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_HELLO); rfc5444_writer_flush(&writer, &interface, false); - - fill_routing_table(); } void writer_send_tc(void) { From c5e39cf4212d55e9c45a3603f53a38fac8b59a07 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 12 May 2014 13:22:33 +0200 Subject: [PATCH 03/48] add olsr2 example application --- examples/olsr2/Makefile | 40 ++++++++++++ examples/olsr2/main.c | 133 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 examples/olsr2/Makefile create mode 100644 examples/olsr2/main.c diff --git a/examples/olsr2/Makefile b/examples/olsr2/Makefile new file mode 100644 index 000000000000..aacde7ee25a7 --- /dev/null +++ b/examples/olsr2/Makefile @@ -0,0 +1,40 @@ +#### +#### Sample Makefile for building apps with the RIOT OS +#### +#### The Sample Filesystem Layout is: +#### /this makefile +#### ../../RIOT +#### ../../boards for board definitions (if you have one or more) +#### + +# name of your application +export APPLICATION = olsr_node + +export BOARD ?= native +export RIOTBASE ?= $(CURDIR)/../.. + +USEPKG += oonf_api + +export CFLAGS = -DRIOT -DENABLE_NAME + +## Modules to include. + +USEMODULE += rtc +USEMODULE += uart0 +USEMODULE += posix +USEMODULE += ps +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += random +USEMODULE += config +USEMODULE += olsr2 +USEMODULE += defaulttransceiver + +ifeq ($(BOARD),native) + export CFLAGS += -DUSE_PID +endif +ifeq ($(BOARD),msba2) + export CFLAGS += -DENABLE_LEDS +endif + +include $(RIOTBASE)/Makefile.include diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c new file mode 100644 index 000000000000..26fc8ecffb6d --- /dev/null +++ b/examples/olsr2/main.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define IF_ID (0) + +#if defined(USE_PID) +#include +#include +static uint16_t get_node_id(void) { + return getpid(); +} +#else +#include + +static uint16_t get_node_id(void) { + return sysconfig.id; +} +#endif + +#ifdef ENABLE_NAME + +static void ping(int argc, char **argv) { + static uint16_t id = 0; + + if (argc < 2) { + puts("usage: ping [node]"); + return; + } + + id++; + int packets = 10; + + ipv6_addr_t* dest = get_ip_by_name(argv[1]); + if (dest == NULL) { + printf("Unknown node: %s\n", argv[1]); + return; + } + + char addr_str[IPV6_MAX_ADDR_STR_LEN]; + ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN, dest); + + uint8_t payload[] = "foobar"; + + for (int i = 0; i < packets; ++i) { + printf("sending %u bytes to %s\n", sizeof payload, addr_str); + icmpv6_send_echo_request(dest, id, i, payload, sizeof payload); + vtimer_usleep(1000000); + } +} +#endif /* ENABLE_NAME */ + +static void set_id(int argc, char **argv) { + if (argc < 2) { + puts("usage: set_id [id] [name]"); + return; + } + + uint16_t id = atoi(argv[1]); + sysconfig.id = id; + sysconfig.radio_address = (uint8_t) id; + +#ifdef ENABLE_NAME + if (argc > 2) + strncpy(sysconfig.name, argv[2], CONFIG_NAME_LEN); +#endif + config_save(); +} + +static void init(void) { + ipv6_addr_t tmp; + + rtc_enable(); + genrand_init(get_node_id()); + net_if_set_hardware_address(IF_ID, get_node_id()); + + ipv6_addr_set_link_local_prefix(&tmp); + ipv6_addr_set_by_eui64(&tmp, IF_ID, &tmp); + ipv6_net_if_add_addr(IF_ID, &tmp, NDP_ADDR_STATE_PREFERRED, + NDP_OPT_PI_VLIFETIME_INFINITE, + NDP_OPT_PI_PLIFETIME_INFINITE, 0); + + ipv6_addr_set_all_nodes_addr(&tmp); + ipv6_net_if_add_addr(IF_ID, &tmp, NDP_ADDR_STATE_PREFERRED, + NDP_OPT_PI_VLIFETIME_INFINITE, + NDP_OPT_PI_PLIFETIME_INFINITE, 0); + + olsr_init(); +} + +const shell_command_t shell_commands[] = { + {"routes", "print all known nodes and routes", print_topology_set}, + {"set_id", "set node ID and name", set_id}, +#ifdef ENABLE_NAME + {"ping", "send packets to a node", ping}, +#endif + {NULL, NULL, NULL} +}; + +int main(void) { + init(); + + posix_open(uart0_handler_pid, 0); + + shell_t shell; + shell_init(&shell, shell_commands, UART0_BUFSIZE, uart0_readc, uart0_putc); + + shell_run(&shell); + + return 0; +} From 6db53249858471092e263bcd0181e22c057b8755 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 8 Jul 2014 01:39:37 +0200 Subject: [PATCH 04/48] add BOARD_WHITELIST to olsr2 example other targets lack or have no radio --- examples/olsr2/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/olsr2/Makefile b/examples/olsr2/Makefile index aacde7ee25a7..68758c3d00dc 100644 --- a/examples/olsr2/Makefile +++ b/examples/olsr2/Makefile @@ -13,6 +13,9 @@ export APPLICATION = olsr_node export BOARD ?= native export RIOTBASE ?= $(CURDIR)/../.. +# other toolchains lack assert.h used by oonf_api +BOARD_WHITELIST := avsextrem msba2 native + USEPKG += oonf_api export CFLAGS = -DRIOT -DENABLE_NAME From 72f4ba55b8713e81d3f95d7e455b77769d934a36 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 18:34:32 +0200 Subject: [PATCH 05/48] remove unnecessary dependency tests --- Makefile.dep | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/Makefile.dep b/Makefile.dep index 23bafe87dc7c..064eb167ad43 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -3,21 +3,11 @@ ifneq (,$(filter libcoap,$(USEPKG))) endif ifneq (,$(filter olsr2,$(USEMODULE))) - ifeq (,$(filter vtimer,$(USEMODULE))) - USEMODULE += vtimer - endif - ifeq (,$(filter destiny,$(USEMODULE))) - USEMODULE += destiny - endif - ifeq (,$(filter sixlowpan,$(USEMODULE))) - USEMODULE += sixlowpan - endif - ifeq (,$(filter oonf_common,$(USEMODULE))) - USEMODULE += oonf_common - endif - ifeq (,$(filter oonf_rfc5444,$(USEMODULE))) - USEMODULE += oonf_rfc5444 - endif + USEMODULE += vtimer + USEMODULE += destiny + USEMODULE += sixlowpan + USEMODULE += oonf_common + USEMODULE += oonf_rfc5444 endif ifneq (,$(filter pnet,$(USEMODULE))) From 83cb9f599512bdb94ce4bb5052c9cc2c9eba4f5e Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 18:35:45 +0200 Subject: [PATCH 06/48] fix typo --- sys/net/include/olsr2/olsr2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/include/olsr2/olsr2.h b/sys/net/include/olsr2/olsr2.h index 8a3ca3558f60..6f7f1f3e8e34 100644 --- a/sys/net/include/olsr2/olsr2.h +++ b/sys/net/include/olsr2/olsr2.h @@ -15,7 +15,7 @@ void print_topology_set(void); #ifdef ENABLE_NAME /** - * @brief get the IP address of a MANET router from it's hostname + * @brief get the IP address of a MANET router from its hostname */ ipv6_addr_t* get_ip_by_name(char* name); #endif From 03114da273fbbb6e39afcd78ef778f1ad0a203fb Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 18:37:36 +0200 Subject: [PATCH 07/48] clean up example makefile --- examples/olsr2/Makefile | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/olsr2/Makefile b/examples/olsr2/Makefile index 68758c3d00dc..cc385e1b060d 100644 --- a/examples/olsr2/Makefile +++ b/examples/olsr2/Makefile @@ -1,13 +1,3 @@ -#### -#### Sample Makefile for building apps with the RIOT OS -#### -#### The Sample Filesystem Layout is: -#### /this makefile -#### ../../RIOT -#### ../../boards for board definitions (if you have one or more) -#### - -# name of your application export APPLICATION = olsr_node export BOARD ?= native @@ -20,8 +10,7 @@ USEPKG += oonf_api export CFLAGS = -DRIOT -DENABLE_NAME -## Modules to include. - +# Modules to include. USEMODULE += rtc USEMODULE += uart0 USEMODULE += posix @@ -33,6 +22,7 @@ USEMODULE += config USEMODULE += olsr2 USEMODULE += defaulttransceiver +# on native, use PID as node ID ifeq ($(BOARD),native) export CFLAGS += -DUSE_PID endif From f6336cb82f084beadab2274cd61f7b84ff88455f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 18:38:12 +0200 Subject: [PATCH 08/48] explicit module name is not needed anymore --- sys/net/routing/olsr2/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/net/routing/olsr2/Makefile b/sys/net/routing/olsr2/Makefile index b2513e8c285c..48422e909a47 100644 --- a/sys/net/routing/olsr2/Makefile +++ b/sys/net/routing/olsr2/Makefile @@ -1,3 +1 @@ -MODULE:= $(shell basename $(CURDIR)) - include $(RIOTBASE)/Makefile.base From 409473800d1e02cf253f0f71e552cf2094585f7a Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 21:19:39 +0200 Subject: [PATCH 09/48] comments in constants.h --- sys/net/routing/olsr2/constants.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index e6095ae0d1fa..ac62db477e08 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -1,7 +1,7 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ -/* RFC5498 */ +/* The well-known UDP port for MANET as defined in RFC 5498 */ #define MANET_PORT 269 /* in seconds */ @@ -15,7 +15,7 @@ #define HYST_LOW 0.3 #define HYST_HIGH 0.8 -/* 1s */ +/* in µs */ #define MAX_JITTER 1000000 #define FLOODING_MPR_SELECTOR 1 From e75d7f9330308f15954c3ad035b207ea03b9d016 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 21:26:43 +0200 Subject: [PATCH 10/48] prefix constants --- sys/net/routing/olsr2/constants.h | 20 ++++++++++---------- sys/net/routing/olsr2/nhdp.c | 4 ++-- sys/net/routing/olsr2/olsr.c | 12 ++++++------ sys/net/routing/olsr2/olsr_init.c | 6 +++--- sys/net/routing/olsr2/writer.c | 6 +++--- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index ac62db477e08..eefb3aef289c 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -5,21 +5,21 @@ #define MANET_PORT 269 /* in seconds */ -#define HELLO_REFRESH_INTERVAL 2 -#define TC_REFRESH_INTERVAL 5 -#define HOLD_TIME (3 * TC_REFRESH_INTERVAL) +#define OLSR2_HELLO_REFRESH_INTERVAL_SECONDS 2 +#define OLSR2_TC_REFRESH_INTERVAL_SECONDS 5 +#define OLSR2_HOLD_TIME_SECONDS (3 * OLSR2_TC_REFRESH_INTERVAL_SECONDS) -#define TC_HOP_LIMIT 16 +#define OLSR2_TC_HOP_LIMIT 16 -#define HYST_SCALING 0.4 -#define HYST_LOW 0.3 -#define HYST_HIGH 0.8 +#define OLSR2_HYST_SCALING 0.4 +#define OLSR2_HYST_LOW 0.3 +#define OLSR2_HYST_HIGH 0.8 /* in µs */ -#define MAX_JITTER 1000000 +#define OLSR2_MAX_JITTER_US 1000000 -#define FLOODING_MPR_SELECTOR 1 -#define ROUTING_MPR_SELECTOR 2 +#define OLSR2_FLOODING_MPR_SELECTOR 1 +#define OLSR2_ROUTING_MPR_SELECTOR 2 #define RFC5444_TLV_NODE_NAME 42 diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index a9bb0c7e3d66..10d4bfdb5586 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -40,7 +40,7 @@ static struct olsr_node* _node_replace(struct olsr_node* old_n) { add_free_node(new_n); new_n->pending = 1; - h1_deriv(new_n)->link_quality = HYST_SCALING; + h1_deriv(new_n)->link_quality = OLSR2_HYST_SCALING; return new_n; } @@ -65,7 +65,7 @@ struct olsr_node* add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vt n->type = NODE_TYPE_NHDP; n->distance = 1; n->link_metric = metric; - h1_deriv(n)->link_quality = HYST_SCALING; + h1_deriv(n)->link_quality = OLSR2_HYST_SCALING; n->pending = 1; #ifdef ENABLE_NAME if (name != NULL) diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index fc105e3b37de..9bddc1834102 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -172,11 +172,11 @@ static bool _route_expired(struct olsr_node* node, struct netaddr* last_addr) { static void _update_link_quality(struct nhdp_node* node) { TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); if (_route_expired(h1_super(node), get_local_addr())) - node->link_quality = node->link_quality * (1 - HYST_SCALING); + node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING); else - node->link_quality = node->link_quality * (1 - HYST_SCALING) + HYST_SCALING; + node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING) + OLSR2_HYST_SCALING; - if (!h1_super(node)->pending && node->link_quality < HYST_LOW) { + if (!h1_super(node)->pending && node->link_quality < OLSR2_HYST_LOW) { h1_super(node)->pending = 1; h1_super(node)->lost = LOST_ITER_MAX; @@ -191,7 +191,7 @@ static void _update_link_quality(struct nhdp_node* node) { _update_children(h1_super(node)->addr, NULL); } - if (h1_super(node)->pending && node->link_quality > HYST_HIGH) { + if (h1_super(node)->pending && node->link_quality > OLSR2_HYST_HIGH) { h1_super(node)->pending = 0; h1_super(node)->lost = 0; @@ -210,7 +210,7 @@ bool remove_expired(struct olsr_node* node) { char skipped; struct alt_route *route, *prev; simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (_now - route->expires < HOLD_TIME) + if (_now - route->expires < OLSR2_HOLD_TIME_SECONDS) continue; DEBUG("alternative route to %s (%s) via %s expired, removing it", @@ -219,7 +219,7 @@ bool remove_expired(struct olsr_node* node) { simple_list_for_each_remove(&node->other_routes, route, prev); } - if (_now - node->expires > HOLD_TIME) { + if (_now - node->expires > OLSR2_HOLD_TIME_SECONDS) { DEBUG("%s (%s) expired", node->name, netaddr_to_str_s(&nbuf[0], node->addr)); diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index ddaa02a34712..af9755dbb5c3 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -45,8 +45,8 @@ struct timer_msg { void (*func) (void); }; -static struct timer_msg msg_hello = { .timer = {0}, .interval = { .seconds = HELLO_REFRESH_INTERVAL - 1, .microseconds = 0}, .func = writer_send_hello }; -static struct timer_msg msg_tc = { .timer = {0}, .interval = { .seconds = TC_REFRESH_INTERVAL - 1, .microseconds = 0}, .func = writer_send_tc }; +static struct timer_msg msg_hello = { .timer = {0}, .interval = { .seconds = OLSR2_HELLO_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_hello }; +static struct timer_msg msg_tc = { .timer = {0}, .interval = { .seconds = OLSR2_TC_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_tc }; static int sock; static sockaddr6_t sa_bcast; @@ -124,7 +124,7 @@ static void olsr_sender_thread(void) { mutex_unlock(&olsr_data); /* add jitter */ - tmsg->interval.microseconds = genrand_uint32() % MAX_JITTER; + tmsg->interval.microseconds = genrand_uint32() % OLSR2_MAX_JITTER_US; if (vtimer_set_msg(&tmsg->timer, tmsg->interval, thread_getpid(), tmsg) != 0) DEBUG("vtimer_set_msg failed, stopped sending"); diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index d296d0181fbb..f2b18b43c935 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -76,7 +76,7 @@ static struct rfc5444_writer_tlvtype _olsr_addrtlvs[] = { /* add TLVs to HELLO message */ static void _cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr) { - uint8_t time_encoded = rfc5444_timetlv_encode(HELLO_REFRESH_INTERVAL); + uint8_t time_encoded = rfc5444_timetlv_encode(OLSR2_HELLO_REFRESH_INTERVAL_SECONDS); rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); #ifdef ENABLE_NAME @@ -149,7 +149,7 @@ _cb_add_nhdp_addresses(struct rfc5444_writer *wr) { /* add TLVs to TC message */ static void _cb_add_olsr_message_TLVs(struct rfc5444_writer *wr) { - uint8_t time_encoded = rfc5444_timetlv_encode(TC_REFRESH_INTERVAL); + uint8_t time_encoded = rfc5444_timetlv_encode(OLSR2_TC_REFRESH_INTERVAL_SECONDS); rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); #ifdef ENABLE_NAME @@ -219,7 +219,7 @@ _cb_add_tc_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_messa rfc5444_writer_set_msg_seqno(wr, message, seq_no++); rfc5444_writer_set_msg_originator(wr, message, netaddr_get_binptr(get_local_addr())); - message->hoplimit = TC_HOP_LIMIT; + message->hoplimit = OLSR2_TC_HOP_LIMIT; } /* reader has already decided whether to forward or not, just say ok to that */ From fef2f2375f6ec6a8abbb680a505543b42cb3d419 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 21:38:09 +0200 Subject: [PATCH 11/48] don't overwrite DEBUG_H_ --- sys/net/routing/olsr2/debug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net/routing/olsr2/debug.h b/sys/net/routing/olsr2/debug.h index 01e9273b036f..1c32ba3aad6d 100644 --- a/sys/net/routing/olsr2/debug.h +++ b/sys/net/routing/olsr2/debug.h @@ -1,5 +1,5 @@ -#ifndef DEBUG_H_ -#define DEBUG_H_ +#ifndef OLSR2_DEBUG_H_ +#define OLSR2_DEBUG_H_ #ifdef ENABLE_DEBUG_OLSR #ifndef RIOT From e00fcb3eb38bb222192d1a144042d7ea83c76803 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 9 Jul 2014 21:40:38 +0200 Subject: [PATCH 12/48] get rid of capital letter in simple_list --- sys/net/routing/olsr2/list.c | 14 ++++++------- sys/net/routing/olsr2/list.h | 38 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/sys/net/routing/olsr2/list.c b/sys/net/routing/olsr2/list.c index 98bf9c5d27d3..e65f4c035cc6 100644 --- a/sys/net/routing/olsr2/list.c +++ b/sys/net/routing/olsr2/list.c @@ -15,7 +15,7 @@ struct simple_list_elem { struct simple_list_elem* next; }; -void* __Simple_list_add_tail(struct simple_list_elem** head, void* mem) { +void* __simple_list_add_tail(struct simple_list_elem** head, void* mem) { struct simple_list_elem* _head = *head; /* check out-of-memory condition */ @@ -35,7 +35,7 @@ void* __Simple_list_add_tail(struct simple_list_elem** head, void* mem) { return _head; } -void* __Simple_list_add_head(struct simple_list_elem** head, void* mem) { +void* __simple_list_add_head(struct simple_list_elem** head, void* mem) { struct simple_list_elem* _head = *head; /* check out-of-memory condition */ @@ -48,7 +48,7 @@ void* __Simple_list_add_head(struct simple_list_elem** head, void* mem) { return *head; } -void* __Simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) { +void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) { struct simple_list_elem* _head = *head; struct simple_list_elem* prev = 0; @@ -83,7 +83,7 @@ void* __Simple_list_add_before(struct simple_list_elem** head, void* mem, int ne return _head; } -void* __Simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) { +void* __simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) { while (head) { void** buff = (void*) head + offset; @@ -97,7 +97,7 @@ void* __Simple_list_find(struct simple_list_elem* head, void* needle, int offset return 0; } -void* __Simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) { +void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) { while (head) { void** buff = (void*) head + offset; @@ -110,7 +110,7 @@ void* __Simple_list_find_cmp(struct simple_list_elem* head, void* needle, int of return 0; } -void* __Simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) { +void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) { struct simple_list_elem* _head = *head; struct simple_list_elem* prev = 0; @@ -136,7 +136,7 @@ void* __Simple_list_remove(struct simple_list_elem** head, struct simple_list_el return (void*) 1; } -void __Simple_list_clear(struct simple_list_elem** head) { +void __simple_list_clear(struct simple_list_elem** head) { struct simple_list_elem *tmp, *_head = *head; while (_head != NULL) { diff --git a/sys/net/routing/olsr2/list.h b/sys/net/routing/olsr2/list.h index e74efc460058..46c8bbc512eb 100644 --- a/sys/net/routing/olsr2/list.h +++ b/sys/net/routing/olsr2/list.h @@ -5,23 +5,23 @@ struct simple_list_elem; -#define simple_list_add_head(head) __Simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) -#define simple_list_set_head(head, node) __Simple_list_add_head((struct simple_list_elem**) head, node) -#define simple_list_add_tail(head) __Simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) -#define simple_list_set_tail(head, node) __Simple_list_add_tail((struct simple_list_elem**) (head), (node)) +#define simple_list_add_head(head) __simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) +#define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) head, node) +#define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) +#define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) #define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ - __Simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) + __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) #define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ - __Simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) + __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) #define simple_list_find(head, value) (head) == 0 ? NULL : \ - __Simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) + __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) #define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ - __Simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) + __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) #define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ - __Simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) -#define simple_list_remove(head, node) __Simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) -#define simple_list_extract(head, node) __Simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) -#define simple_list_clear(head) __Simple_list_clear((struct simple_list_elem**) (head)) + __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) +#define simple_list_remove(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) +#define simple_list_extract(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) +#define simple_list_clear(head) __simple_list_clear((struct simple_list_elem**) (head)) #define simple_list_for_each(head, node) for ((node) = (head); (node); (node) = (node)->next) #define simple_list_for_each_safe(head, node, prev, skipped) \ @@ -39,12 +39,12 @@ struct simple_list_elem; (node) = (prev) ? (prev) : *(head); \ } while (0) -void* __Simple_list_add_head(struct simple_list_elem** head, void* mem); -void* __Simple_list_add_tail(struct simple_list_elem** head, void* mem); -void* __Simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset); -void* __Simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size); -void* __Simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)); -void* __Simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep); -void __Simple_list_clear(struct simple_list_elem** head); +void* __simple_list_add_head(struct simple_list_elem** head, void* mem); +void* __simple_list_add_tail(struct simple_list_elem** head, void* mem); +void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset); +void* __simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size); +void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)); +void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep); +void __simple_list_clear(struct simple_list_elem** head); #endif /* SIMPLE_LIST_H_ */ From 800ca64964a9bdd4b8d78c40bbab45ae91e2f66c Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 23 Jul 2014 04:31:02 +0200 Subject: [PATCH 13/48] doxygen for list.h --- sys/net/routing/olsr2/list.h | 153 +++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/sys/net/routing/olsr2/list.h b/sys/net/routing/olsr2/list.h index 46c8bbc512eb..f9c6c372039a 100644 --- a/sys/net/routing/olsr2/list.h +++ b/sys/net/routing/olsr2/list.h @@ -1,3 +1,28 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @file list.h + * @brief simple single linked list implementation with iterators + * + * A list entry is a struct of an arbitrary type but with the only constraint that + * it's first entry is a pointer of the same type as the struct with the name next. + * + * A list is defined by it's first entry, called head. Since the first entry may + * change, a pointer to the first entry is used to refer to the list. + * + * The list automatically allocates and deallocates memory when list elements + * are added or removed + * + * @author Benjamin Valentin + */ + + #ifndef SIMPLE_LIST_H_ #define SIMPLE_LIST_H_ #include @@ -5,30 +30,158 @@ struct simple_list_elem; +/** + * @brief allocates memory for a new list entry and appends it before the head. The new entry is the new head. + * + * @param head pointer to the list + * @return the new list entry, NULL if no new list entry could be allocated + */ #define simple_list_add_head(head) __simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) + + +/** + * @brief appends a preallocated element to the top of the list. The new entry is the new head. + * + * @param head pointer to the list + * @param node preallocated list element + * @return the new list entry (node) + */ #define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) head, node) + + /** + * @brief allocates memory for a new list entry and appends it at the end of the list. + * + * @param head pointer to pointer to the first list element + * @param head pointer to the list + * @return the new list entry, NULL if no new list entry could be allocated + */ #define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) + +/** + * @brief appends a preallocated element to the end of the list. + * + * @param head pointer to the list + * @param node preallocated list element + * @return the new list entry (node) + */ #define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) + + /** + * @brief allocates memory for a new list entry and adds it before an existing entry. + * The new entry is added before the existing element where old_entry->value > value + * If no such entry could be found, the new entry will be added at the end of the list + * + * @param head pointer to the list + * @param value value to compare list entries + * has to be the same name as the element in the list entry structure that is be used for comparison + * @return pointer to the new element, NULL if no new list element could be allocated + */ #define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) + + /** + * @brief adds an preallocated list element before an existing one. + * The new entry is added before the existing element where old_entry->value > value + * If no such entry could be found, the new entry will be added at the end of the list * + * @param head pointer to the list + * @param value value to compare list entries + * has to be the same name as the element in the list entry structure that is be used for comparison + * @param node preallocated list element + * @return the new list entry (node) + */ #define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) + + /** + * @brief searches for a list element by simple comparison of a struct value + * + * @param head pointer to the list + * @param value the member value of a list entry that is to be found + * has to be the same name as the value in the list element struct + * @return pointer the list entry if found, otherwise NULL + */ #define simple_list_find(head, value) (head) == 0 ? NULL : \ __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) + + /** + * @brief searches for a list element by comparing a buffer in the list element struct + * + * @param head pointer to the list + * @param value pointer to the buffer that is to be found in the list + * has to be the same name as the value in the list element struct + * @return pointer the list entry if found, otherwise NULL + */ #define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) + + /** + * @brief searches for a list element by applying a comparator function to each list entry + * + * @param head pointer to the list + * @param value input to the comparator function + * @param comperator a function that takes (value, node) and returns 0 if they match + * @return pointer the list entry if found, otherwise NULL + */ #define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) + +/** + * @brief removes an entry from the list and frees it's memory + * + * @param head pointer to the list + * @param node entry to be removed + * @returns a non-zero value if the element was found and removed + */ #define simple_list_remove(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) + +/** + * @brief removes an entry from the list, doesn't free it's memory but returns the element + * + * @param head pointer to the list + * @param node entry to be extracted + * @returns pointer to the element, NULL if it couldn't be found + */ #define simple_list_extract(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) + +/** + * @brief removes all entries from the list and frees their memory + * + * @param head pointer to the list + */ #define simple_list_clear(head) __simple_list_clear((struct simple_list_elem**) (head)) +/** + * @brief starts a loop to iterate over all list entries. Read-only list access only. + * needs to be provided with a local loop variable + * + * @param head pointer to the list + * @param node to the current entry (loop variable) + */ #define simple_list_for_each(head, node) for ((node) = (head); (node); (node) = (node)->next) + +/** + * @brief starts a loop to iterate over all list elements with the possibility to remove elements + to remove an element, use simple_list_for_each_remove + needs to be provided with a local loop variable as well as two local auxiliary variables + * + * @param head pointer to the list + * @param node to the current entry (loop variable) + * @param prev internal variable, pointer to previous list entry - do not modify + * @param skipped internal variable, integer - do not modify + */ #define simple_list_for_each_safe(head, node, prev, skipped) \ for ((skipped) = 0, (prev) = 0, (node) = (head);\ (node); \ (prev) = ((skipped) ? (prev) : (node)), \ (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) + +/** + * @brief removes an element in a simple_list_for_each_safe context + * + * @param head pointer to the list + * @param node pointer to the current entry (loop variable) + * @param prev internal variable, provided by simple_list_for_each_safe + */ #define simple_list_for_each_remove(head, node, prev) do { \ if (!prev) { \ (skipped) = 1; \ From 0ccc9e1bec196b4d678bcb13182aea9636b958ad Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 24 Jul 2014 16:19:47 +0200 Subject: [PATCH 14/48] prefix add_neighbor --- sys/net/routing/olsr2/nhdp.c | 2 +- sys/net/routing/olsr2/nhdp.h | 2 +- sys/net/routing/olsr2/reader.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 10d4bfdb5586..98a0ccb7190b 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -45,7 +45,7 @@ static struct olsr_node* _node_replace(struct olsr_node* old_n) { return new_n; } -struct olsr_node* add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name) { +struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name) { struct olsr_node* n = get_node(addr); if (n == NULL) { diff --git a/sys/net/routing/olsr2/nhdp.h b/sys/net/routing/olsr2/nhdp.h index b63a6761bdc0..47afa45f8b70 100644 --- a/sys/net/routing/olsr2/nhdp.h +++ b/sys/net/routing/olsr2/nhdp.h @@ -6,7 +6,7 @@ #include "node.h" -struct olsr_node* add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name); +struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name); void print_neighbors(void); diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 72e8f8a76ebf..21ea93b12c0f 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -125,10 +125,10 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att DEBUG("\tmetric: %d", metric); - current_node = add_neighbor(current_src, metric, vtime, name); + current_node = olsr2_add_neighbor(current_src, metric, vtime, name); if (current_node == NULL) { - puts("ERROR: add_neighbor failed - out of memory"); + puts("ERROR: olsr2_add_neighbor failed - out of memory"); return RFC5444_DROP_PACKET; } From 84014e5436ebfad905098c3b23e0c5ebc398eaf5 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 24 Jul 2014 16:22:10 +0200 Subject: [PATCH 15/48] added more parens --- sys/net/routing/olsr2/olsr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 9bddc1834102..d774cdbc6f5f 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -332,8 +332,8 @@ bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) { uint16_t tmp = node->seq_no; /* S1 > S2 AND S1 - S2 < MAXVALUE/2 OR S2 > S1 AND S2 - S1 > MAXVALUE/2 */ - if ((seq_no > tmp && seq_no - tmp < (1 << 15)) || - (seq_no < tmp && tmp - seq_no > (1 << 15)) ) { + if (((seq_no > tmp) && (seq_no - tmp < (1 << 15))) || + ((seq_no < tmp) && (tmp - seq_no > (1 << 15))) ) { node->seq_no = seq_no; return false; } From 9a5f00589f409455ff69ed38d0ed9f5eea785eb8 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 24 Jul 2014 16:32:03 +0200 Subject: [PATCH 16/48] add @author --- sys/net/routing/olsr2/list.c | 5 +++++ sys/net/routing/olsr2/nhdp.c | 5 +++++ sys/net/routing/olsr2/node.c | 5 +++++ sys/net/routing/olsr2/olsr.c | 5 +++++ sys/net/routing/olsr2/olsr_init.c | 5 +++++ sys/net/routing/olsr2/reader.c | 5 +++++ sys/net/routing/olsr2/routing.c | 5 +++++ sys/net/routing/olsr2/util.c | 5 +++++ sys/net/routing/olsr2/writer.c | 5 +++++ 9 files changed, 45 insertions(+) diff --git a/sys/net/routing/olsr2/list.c b/sys/net/routing/olsr2/list.c index e65f4c035cc6..14c64dc5a193 100644 --- a/sys/net/routing/olsr2/list.c +++ b/sys/net/routing/olsr2/list.c @@ -6,6 +6,11 @@ * details. */ + /** + * @file list.c + * @author Benjamin Valentin + */ + #include #include diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 98a0ccb7190b..6aa764e4ee76 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #include diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index 98ab7d401b8b..b25943f40c24 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #include diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index d774cdbc6f5f..ab6391d786fa 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #include diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index af9755dbb5c3..8bd93f6c2528 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ /*************************************************************** diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 21ea93b12c0f..a08912436977 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #include diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index a0dcb76b13b5..863059f755ae 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #include diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 0797042a8f72..06f09928d425 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #include diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index f2b18b43c935..e38d5ed6edab 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -4,6 +4,11 @@ * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file LICENSE in the top level directory for more * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} */ #ifdef RIOT From f989a82db78de14220b25b1dc6aa1fd1b4a64587 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 24 Jul 2014 16:34:24 +0200 Subject: [PATCH 17/48] debug.h -> olsr_debug.h --- sys/net/routing/olsr2/nhdp.c | 2 +- sys/net/routing/olsr2/node.c | 2 +- sys/net/routing/olsr2/node.h | 2 +- sys/net/routing/olsr2/olsr.c | 2 +- sys/net/routing/olsr2/{debug.h => olsr_debug.h} | 0 sys/net/routing/olsr2/olsr_init.c | 2 +- sys/net/routing/olsr2/reader.c | 2 +- sys/net/routing/olsr2/routing.c | 2 +- sys/net/routing/olsr2/util.c | 2 +- sys/net/routing/olsr2/writer.c | 2 +- 10 files changed, 9 insertions(+), 9 deletions(-) rename sys/net/routing/olsr2/{debug.h => olsr_debug.h} (100%) diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 6aa764e4ee76..5dd767ec6552 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -15,7 +15,7 @@ #include "nhdp.h" #include "util.h" -#include "debug.h" +#include "olsr_debug.h" #include "node.h" #include "routing.h" #include "constants.h" diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index b25943f40c24..ea056f08c235 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -15,7 +15,7 @@ #include "node.h" #include "list.h" -#include "debug.h" +#include "olsr_debug.h" #include "common/netaddr.h" #include "rfc5444/rfc5444.h" diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index bdb592943d36..440750818ef6 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -5,7 +5,7 @@ #include "common/netaddr.h" #include "util.h" -#include "debug.h" +#include "olsr_debug.h" #ifdef ENABLE_NAME extern char* local_name; diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index ab6391d786fa..817116865de2 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -23,7 +23,7 @@ #include "olsr.h" #include "util.h" -#include "debug.h" +#include "olsr_debug.h" #include "routing.h" #include "constants.h" #include "list.h" diff --git a/sys/net/routing/olsr2/debug.h b/sys/net/routing/olsr2/olsr_debug.h similarity index 100% rename from sys/net/routing/olsr2/debug.h rename to sys/net/routing/olsr2/olsr_debug.h diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 8bd93f6c2528..0ec989e8cf62 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -33,7 +33,7 @@ #include "rfc5444/rfc5444_writer.h" #include "constants.h" -#include "debug.h" +#include "olsr_debug.h" #include "node.h" #include "olsr.h" #include "reader.h" diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index a08912436977..535a5b0ed493 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -24,7 +24,7 @@ #include "net_help.h" #endif -#include "debug.h" +#include "olsr_debug.h" #include "nhdp.h" #include "olsr.h" #include "reader.h" diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index 863059f755ae..733e08e438c1 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -16,7 +16,7 @@ #include "olsr.h" #include "list.h" -#include "debug.h" +#include "olsr_debug.h" #include "util.h" #include "routing.h" #include "constants.h" diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 06f09928d425..1d00e7b216df 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -23,7 +23,7 @@ #include "util.h" #include "node.h" -#include "debug.h" +#include "olsr_debug.h" const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src) { return src ? netaddr_to_string(dst, src) : NULL; diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index e38d5ed6edab..ed7d10d0dfe2 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -30,7 +30,7 @@ #include "writer.h" #include "nhdp.h" #include "olsr.h" -#include "debug.h" +#include "olsr_debug.h" #include "routing.h" uint8_t msg_buffer[256]; From 621a1f4b8dbe6c97123e0dfcbebbfce703adec73 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 24 Jul 2014 17:15:46 +0200 Subject: [PATCH 18/48] astyle --style=linux --- sys/net/routing/olsr2/constants.h | 16 +- sys/net/routing/olsr2/list.c | 217 +++++----- sys/net/routing/olsr2/list.h | 106 ++--- sys/net/routing/olsr2/nhdp.c | 145 ++++--- sys/net/routing/olsr2/node.c | 283 ++++++------ sys/net/routing/olsr2/node.h | 82 ++-- sys/net/routing/olsr2/olsr.c | 667 +++++++++++++++-------------- sys/net/routing/olsr2/olsr_debug.h | 23 +- sys/net/routing/olsr2/olsr_init.c | 217 +++++----- sys/net/routing/olsr2/reader.c | 351 +++++++-------- sys/net/routing/olsr2/routing.c | 327 +++++++------- sys/net/routing/olsr2/util.c | 90 ++-- sys/net/routing/olsr2/util.h | 4 +- sys/net/routing/olsr2/writer.c | 327 +++++++------- sys/net/routing/olsr2/writer.h | 2 +- 15 files changed, 1468 insertions(+), 1389 deletions(-) diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index eefb3aef289c..30019841a138 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -25,18 +25,18 @@ /* NHDP message TLV array index */ enum { - IDX_TLV_ITIME, /* Interval time */ - IDX_TLV_VTIME, /* validity time */ - IDX_TLV_NODE_NAME, /* name of the node */ + IDX_TLV_ITIME, /* Interval time */ + IDX_TLV_VTIME, /* validity time */ + IDX_TLV_NODE_NAME, /* name of the node */ }; /* NHDP address TLV array index */ enum { - IDX_ADDRTLV_LOCAL_IF, /* is local if */ - IDX_ADDRTLV_LINK_STATUS, /* link status TODO */ - IDX_ADDRTLV_MPR, /* neighbor selected as mpr */ - IDX_ADDRTLV_METRIC, /* incomming link metric */ - IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ + IDX_ADDRTLV_LOCAL_IF, /* is local if */ + IDX_ADDRTLV_LINK_STATUS, /* link status TODO */ + IDX_ADDRTLV_MPR, /* neighbor selected as mpr */ + IDX_ADDRTLV_METRIC, /* incomming link metric */ + IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ }; #endif /* CONSTANTS_H_ */ diff --git a/sys/net/routing/olsr2/list.c b/sys/net/routing/olsr2/list.c index 14c64dc5a193..86743f70f7a7 100644 --- a/sys/net/routing/olsr2/list.c +++ b/sys/net/routing/olsr2/list.c @@ -6,10 +6,10 @@ * details. */ - /** - * @file list.c - * @author Benjamin Valentin - */ +/** +* @file list.c +* @author Benjamin Valentin +*/ #include #include @@ -17,138 +17,145 @@ #include "list.h" struct simple_list_elem { - struct simple_list_elem* next; + struct simple_list_elem* next; }; -void* __simple_list_add_tail(struct simple_list_elem** head, void* mem) { - struct simple_list_elem* _head = *head; +void* __simple_list_add_tail(struct simple_list_elem** head, void* mem) +{ + struct simple_list_elem* _head = *head; - /* check out-of-memory condition */ - if (mem == NULL) - return NULL; + /* check out-of-memory condition */ + if (mem == NULL) + return NULL; - if (!_head) { - *head = mem; - return *head; - } + if (!_head) { + *head = mem; + return *head; + } - while (_head->next) { - _head = _head->next; - } + while (_head->next) { + _head = _head->next; + } - _head = _head->next = mem; - return _head; + _head = _head->next = mem; + return _head; } -void* __simple_list_add_head(struct simple_list_elem** head, void* mem) { - struct simple_list_elem* _head = *head; +void* __simple_list_add_head(struct simple_list_elem** head, void* mem) +{ + struct simple_list_elem* _head = *head; - /* check out-of-memory condition */ - if (mem == NULL) - return NULL; + /* check out-of-memory condition */ + if (mem == NULL) + return NULL; - *head = mem; - (*head)->next = _head; + *head = mem; + (*head)->next = _head; - return *head; + return *head; } -void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) { - struct simple_list_elem* _head = *head; - struct simple_list_elem* prev = 0; - - /* check out-of-memory condition */ - if (mem == NULL) - return NULL; - - if (!_head) { - *head = mem; - return *head; - } - - while(_head) { - int* buff = (void*) _head + offset; - if (*buff > needle) { - if (prev) { - prev->next = mem; - prev->next->next = _head; - return prev->next; - } - - prev = mem; - prev->next = _head; - *head = prev; - return prev; - } - prev = _head; - _head = _head->next; - } - - _head = prev->next = mem; - return _head; +void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) +{ + struct simple_list_elem* _head = *head; + struct simple_list_elem* prev = 0; + + /* check out-of-memory condition */ + if (mem == NULL) + return NULL; + + if (!_head) { + *head = mem; + return *head; + } + + while(_head) { + int* buff = (void*) _head + offset; + if (*buff > needle) { + if (prev) { + prev->next = mem; + prev->next->next = _head; + return prev->next; + } + + prev = mem; + prev->next = _head; + *head = prev; + return prev; + } + prev = _head; + _head = _head->next; + } + + _head = prev->next = mem; + return _head; } -void* __simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) { - while (head) { - void** buff = (void*) head + offset; +void* __simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) +{ + while (head) { + void** buff = (void*) head + offset; - if (size == 0 && *buff == needle) - return head; - if (size > 0 && memcmp(*buff, needle, size) == 0) - return head; - head = head->next; - } + if (size == 0 && *buff == needle) + return head; + if (size > 0 && memcmp(*buff, needle, size) == 0) + return head; + head = head->next; + } - return 0; + return 0; } -void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) { - while (head) { - void** buff = (void*) head + offset; +void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) +{ + while (head) { + void** buff = (void*) head + offset; - if (compare(*buff, needle) == 0) - return head; + if (compare(*buff, needle) == 0) + return head; - head = head->next; - } + head = head->next; + } - return 0; + return 0; } -void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) { - struct simple_list_elem* _head = *head; - struct simple_list_elem* prev = 0; +void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) +{ + struct simple_list_elem* _head = *head; + struct simple_list_elem* prev = 0; - while (_head && _head != node) { - prev = _head; - _head = _head->next; - } + while (_head && _head != node) { + prev = _head; + _head = _head->next; + } - /* not found */ - if (_head != node) - return NULL; + /* not found */ + if (_head != node) + return NULL; - /* remove head */ - if (!prev) - *head = _head->next; - else - prev->next = node->next; + /* remove head */ + if (!prev) + *head = _head->next; + else + prev->next = node->next; - if (keep) - return node; + if (keep) + return node; - free(node); - return (void*) 1; + free(node); + return (void*) 1; } -void __simple_list_clear(struct simple_list_elem** head) { - struct simple_list_elem *tmp, *_head = *head; +void __simple_list_clear(struct simple_list_elem** head) +{ + struct simple_list_elem *tmp, *_head = *head; - while (_head != NULL) { - tmp = _head; - _head = _head->next; - free(tmp); - } + while (_head != NULL) { + tmp = _head; + _head = _head->next; + free(tmp); + } - *head = NULL; + *head = NULL; } diff --git a/sys/net/routing/olsr2/list.h b/sys/net/routing/olsr2/list.h index f9c6c372039a..2e4dcf486738 100644 --- a/sys/net/routing/olsr2/list.h +++ b/sys/net/routing/olsr2/list.h @@ -48,13 +48,13 @@ struct simple_list_elem; */ #define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) head, node) - /** - * @brief allocates memory for a new list entry and appends it at the end of the list. - * - * @param head pointer to pointer to the first list element - * @param head pointer to the list - * @return the new list entry, NULL if no new list entry could be allocated - */ +/** +* @brief allocates memory for a new list entry and appends it at the end of the list. +* +* @param head pointer to pointer to the first list element +* @param head pointer to the list +* @return the new list entry, NULL if no new list entry could be allocated +*/ #define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) /** @@ -66,62 +66,62 @@ struct simple_list_elem; */ #define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) - /** - * @brief allocates memory for a new list entry and adds it before an existing entry. - * The new entry is added before the existing element where old_entry->value > value - * If no such entry could be found, the new entry will be added at the end of the list - * - * @param head pointer to the list - * @param value value to compare list entries - * has to be the same name as the element in the list entry structure that is be used for comparison - * @return pointer to the new element, NULL if no new list element could be allocated - */ +/** +* @brief allocates memory for a new list entry and adds it before an existing entry. +* The new entry is added before the existing element where old_entry->value > value +* If no such entry could be found, the new entry will be added at the end of the list +* +* @param head pointer to the list +* @param value value to compare list entries +* has to be the same name as the element in the list entry structure that is be used for comparison +* @return pointer to the new element, NULL if no new list element could be allocated +*/ #define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) - /** - * @brief adds an preallocated list element before an existing one. - * The new entry is added before the existing element where old_entry->value > value - * If no such entry could be found, the new entry will be added at the end of the list * - * @param head pointer to the list - * @param value value to compare list entries - * has to be the same name as the element in the list entry structure that is be used for comparison - * @param node preallocated list element - * @return the new list entry (node) - */ +/** +* @brief adds an preallocated list element before an existing one. +* The new entry is added before the existing element where old_entry->value > value +* If no such entry could be found, the new entry will be added at the end of the list * +* @param head pointer to the list +* @param value value to compare list entries +* has to be the same name as the element in the list entry structure that is be used for comparison +* @param node preallocated list element +* @return the new list entry (node) +*/ #define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) - /** - * @brief searches for a list element by simple comparison of a struct value - * - * @param head pointer to the list - * @param value the member value of a list entry that is to be found - * has to be the same name as the value in the list element struct - * @return pointer the list entry if found, otherwise NULL - */ +/** +* @brief searches for a list element by simple comparison of a struct value +* +* @param head pointer to the list +* @param value the member value of a list entry that is to be found +* has to be the same name as the value in the list element struct +* @return pointer the list entry if found, otherwise NULL +*/ #define simple_list_find(head, value) (head) == 0 ? NULL : \ __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) - /** - * @brief searches for a list element by comparing a buffer in the list element struct - * - * @param head pointer to the list - * @param value pointer to the buffer that is to be found in the list - * has to be the same name as the value in the list element struct - * @return pointer the list entry if found, otherwise NULL - */ +/** +* @brief searches for a list element by comparing a buffer in the list element struct +* +* @param head pointer to the list +* @param value pointer to the buffer that is to be found in the list +* has to be the same name as the value in the list element struct +* @return pointer the list entry if found, otherwise NULL +*/ #define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) - /** - * @brief searches for a list element by applying a comparator function to each list entry - * - * @param head pointer to the list - * @param value input to the comparator function - * @param comperator a function that takes (value, node) and returns 0 if they match - * @return pointer the list entry if found, otherwise NULL - */ +/** +* @brief searches for a list element by applying a comparator function to each list entry +* +* @param head pointer to the list +* @param value input to the comparator function +* @param comperator a function that takes (value, node) and returns 0 if they match +* @return pointer the list entry if found, otherwise NULL +*/ #define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) @@ -166,8 +166,8 @@ struct simple_list_elem; * * @param head pointer to the list * @param node to the current entry (loop variable) - * @param prev internal variable, pointer to previous list entry - do not modify - * @param skipped internal variable, integer - do not modify + * @param prev internal variable, pointer to previous list entry - do not modify + * @param skipped internal variable, integer - do not modify */ #define simple_list_for_each_safe(head, node, prev, skipped) \ for ((skipped) = 0, (prev) = 0, (node) = (head);\ diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 5dd767ec6552..27b4bb173a38 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -22,101 +22,104 @@ #include "common/avl.h" -static struct olsr_node* _node_replace(struct olsr_node* old_n) { - struct olsr_node* new_n = calloc(1, sizeof (struct nhdp_node)); +static struct olsr_node* _node_replace(struct olsr_node* old_n) +{ + struct olsr_node* new_n = calloc(1, sizeof (struct nhdp_node)); - if (new_n == NULL) - return old_n; + if (new_n == NULL) + return old_n; - /* remove things that held a pointer to this */ - avl_remove(get_olsr_head(), &old_n->node); - bool _free_node = remove_free_node(old_n); + /* remove things that held a pointer to this */ + avl_remove(get_olsr_head(), &old_n->node); + bool _free_node = remove_free_node(old_n); - memcpy(new_n, old_n, sizeof(struct olsr_node)); - memset(&new_n->node, 0, sizeof(new_n->node)); // just to be sure + memcpy(new_n, old_n, sizeof(struct olsr_node)); + memset(&new_n->node, 0, sizeof(new_n->node)); // just to be sure - new_n->type = NODE_TYPE_NHDP; - new_n->node.key = new_n->addr; - avl_insert(get_olsr_head(), &new_n->node); + new_n->type = NODE_TYPE_NHDP; + new_n->node.key = new_n->addr; + avl_insert(get_olsr_head(), &new_n->node); - free(old_n); + free(old_n); - if (_free_node) - add_free_node(new_n); + if (_free_node) + add_free_node(new_n); - new_n->pending = 1; - h1_deriv(new_n)->link_quality = OLSR2_HYST_SCALING; + new_n->pending = 1; + h1_deriv(new_n)->link_quality = OLSR2_HYST_SCALING; - return new_n; + return new_n; } -struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name) { - struct olsr_node* n = get_node(addr); +struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name) +{ + struct olsr_node* n = get_node(addr); - if (n == NULL) { - DEBUG("\tadding new neighbor: %s", netaddr_to_str_s(&nbuf[0], addr)); - n = calloc(1, sizeof(struct nhdp_node)); + if (n == NULL) { + DEBUG("\tadding new neighbor: %s", netaddr_to_str_s(&nbuf[0], addr)); + n = calloc(1, sizeof(struct nhdp_node)); - if (n == NULL) - return NULL; + if (n == NULL) + return NULL; - n->addr = netaddr_dup(addr); + n->addr = netaddr_dup(addr); - if (n->addr == NULL) { - free(n); - return NULL; - } + if (n->addr == NULL) { + free(n); + return NULL; + } - n->type = NODE_TYPE_NHDP; - n->distance = 1; - n->link_metric = metric; - h1_deriv(n)->link_quality = OLSR2_HYST_SCALING; - n->pending = 1; + n->type = NODE_TYPE_NHDP; + n->distance = 1; + n->link_metric = metric; + h1_deriv(n)->link_quality = OLSR2_HYST_SCALING; + n->pending = 1; #ifdef ENABLE_NAME - if (name != NULL) - n->name = strdup(name); + if (name != NULL) + n->name = strdup(name); #endif - n->node.key = n->addr; - avl_insert(get_olsr_head(), &n->node); - } else if (n->type != NODE_TYPE_NHDP) { - DEBUG("\tconverting olsr node %s to nhdp node", - netaddr_to_str_s(&nbuf[0], n->addr)); - n = _node_replace(n); - } + n->node.key = n->addr; + avl_insert(get_olsr_head(), &n->node); + } else if (n->type != NODE_TYPE_NHDP) { + DEBUG("\tconverting olsr node %s to nhdp node", + netaddr_to_str_s(&nbuf[0], n->addr)); + n = _node_replace(n); + } - /* add_other_route would otherwise not update expires */ - if (n->next_addr == NULL) - n->expires = time_now() + vtime; + /* add_other_route would otherwise not update expires */ + if (n->next_addr == NULL) + n->expires = time_now() + vtime; - add_other_route(n, get_local_addr(), 1, metric, vtime); + add_other_route(n, get_local_addr(), 1, metric, vtime); - return n; + return n; } #ifdef ENABLE_DEBUG_OLSR -void print_neighbors(void) { - struct olsr_node* node; - - DEBUG("1-hop neighbors:"); - avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance == 1 && node->type == NODE_TYPE_NHDP) - DEBUG("\tneighbor: %s (%s) (mpr for [%d|%d] nodes)", - node->name, - netaddr_to_str_s(&nbuf[0], node->addr), - h1_deriv(node)->mpr_neigh_flood, - h1_deriv(node)->mpr_neigh_route); - } - - DEBUG("2-hop neighbors:"); - avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance == 2) - DEBUG("\t%s (%s) -> %s -> %s (%s)", - node->name, netaddr_to_str_s(&nbuf[0], node->addr), - netaddr_to_str_s(&nbuf[1], node->next_addr), - local_name, - netaddr_to_str_s(&nbuf[2], get_local_addr())); - } +void print_neighbors(void) +{ + struct olsr_node* node; + + DEBUG("1-hop neighbors:"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance == 1 && node->type == NODE_TYPE_NHDP) + DEBUG("\tneighbor: %s (%s) (mpr for [%d|%d] nodes)", + node->name, + netaddr_to_str_s(&nbuf[0], node->addr), + h1_deriv(node)->mpr_neigh_flood, + h1_deriv(node)->mpr_neigh_route); + } + + DEBUG("2-hop neighbors:"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance == 2) + DEBUG("\t%s (%s) -> %s -> %s (%s)", + node->name, netaddr_to_str_s(&nbuf[0], node->addr), + netaddr_to_str_s(&nbuf[1], node->next_addr), + local_name, + netaddr_to_str_s(&nbuf[2], get_local_addr())); + } } #else void print_neighbors(void) {} diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index ea056f08c235..af68ea288c7b 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -27,179 +27,192 @@ static struct avl_tree olsr_head; char* local_name; #endif -static void _decrease_mpr_neigh(struct olsr_node* node) { - TRACE_FUN("%s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); - - /* only consider 2-hop nieghbors (only 2-hop neighbors have flood_mpr set) */ - if (node->flood_mpr == NULL) - return; - - /* update routing MPR information */ - struct nhdp_node* n1 = h1_deriv(get_node(node->next_addr)); - if (n1 != NULL && n1->mpr_neigh_route > 0) - n1->mpr_neigh_route--; - - /* update flooding MPR information */ - struct nhdp_node* n1_f = h1_deriv(get_node(node->flood_mpr)); - if (n1_f != NULL && n1_f->mpr_neigh_flood > 0) - n1_f->mpr_neigh_flood--; +static void _decrease_mpr_neigh(struct olsr_node* node) +{ + TRACE_FUN("%s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); + + /* only consider 2-hop nieghbors (only 2-hop neighbors have flood_mpr set) */ + if (node->flood_mpr == NULL) + return; + + /* update routing MPR information */ + struct nhdp_node* n1 = h1_deriv(get_node(node->next_addr)); + if (n1 != NULL && n1->mpr_neigh_route > 0) + n1->mpr_neigh_route--; + + /* update flooding MPR information */ + struct nhdp_node* n1_f = h1_deriv(get_node(node->flood_mpr)); + if (n1_f != NULL && n1_f->mpr_neigh_flood > 0) + n1_f->mpr_neigh_flood--; } -static int _addr_cmp(const void* a, const void* b) { - return memcmp(a, b, NETADDR_MAX_LENGTH); +static int _addr_cmp(const void* a, const void* b) +{ + return memcmp(a, b, NETADDR_MAX_LENGTH); } -int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b) { - return netaddr_cmp(a->addr, b->addr); +int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b) +{ + return netaddr_cmp(a->addr, b->addr); } -void node_init(void) { - local_addr._refs = 1; - avl_init(get_olsr_head(), _addr_cmp, false); +void node_init(void) +{ + local_addr._refs = 1; + avl_init(get_olsr_head(), _addr_cmp, false); } -struct netaddr* get_local_addr(void) { - return (struct netaddr*) &local_addr; +struct netaddr* get_local_addr(void) +{ + return (struct netaddr*) &local_addr; } -struct avl_tree* get_olsr_head(void) { - return &olsr_head; +struct avl_tree* get_olsr_head(void) +{ + return &olsr_head; } -struct olsr_node* get_node(struct netaddr* addr) { - struct olsr_node *n; // for typeof - if (addr == NULL) - return NULL; - return avl_find_element(get_olsr_head(), addr, n, node); +struct olsr_node* get_node(struct netaddr* addr) +{ + struct olsr_node *n; // for typeof + if (addr == NULL) + return NULL; + return avl_find_element(get_olsr_head(), addr, n, node); } -metric_t get_link_metric(struct olsr_node* node, struct netaddr* last_addr) { - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) - return node->link_metric; +metric_t get_link_metric(struct olsr_node* node, struct netaddr* last_addr) +{ + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + return node->link_metric; - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); - if (route == NULL) - return RFC5444_METRIC_INFINITE; + if (route == NULL) + return RFC5444_METRIC_INFINITE; - return route->link_metric; + return route->link_metric; } -void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t distance, metric_t metric, uint8_t vtime) { - /* make sure the route is not already the default route */ - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { - if (node->next_addr != NULL) { - // TODO: a different route might be better now - node->path_metric -= node->link_metric - metric; - node->link_metric = metric; - } - node->expires = time_now() + vtime; - return; - } - - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); - if (route != NULL) { - route->expires = time_now() + vtime; - route->link_metric = metric; - return; - } - - route = simple_list_add_head(&node->other_routes); - - if (route == NULL) { - printf("ERROR: out of memory in %s\n", __FUNCTION__); - return; - } - - route->last_addr = netaddr_reuse(last_addr); - route->expires = time_now() + vtime; - route->link_metric = metric; - - /* if we add a route for the first time, increment flood_neighbors */ - if (distance == 2 && node->type != NODE_TYPE_NHDP) { - struct nhdp_node* n1 = h1_deriv(get_node(last_addr)); - if (n1 != NULL) - n1->flood_neighbors++; - } +void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t distance, metric_t metric, uint8_t vtime) +{ + /* make sure the route is not already the default route */ + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { + if (node->next_addr != NULL) { + // TODO: a different route might be better now + node->path_metric -= node->link_metric - metric; + node->link_metric = metric; + } + node->expires = time_now() + vtime; + return; + } + + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + if (route != NULL) { + route->expires = time_now() + vtime; + route->link_metric = metric; + return; + } + + route = simple_list_add_head(&node->other_routes); + + if (route == NULL) { + printf("ERROR: out of memory in %s\n", __FUNCTION__); + return; + } + + route->last_addr = netaddr_reuse(last_addr); + route->expires = time_now() + vtime; + route->link_metric = metric; + + /* if we add a route for the first time, increment flood_neighbors */ + if (distance == 2 && node->type != NODE_TYPE_NHDP) { + struct nhdp_node* n1 = h1_deriv(get_node(last_addr)); + if (n1 != NULL) + n1->flood_neighbors++; + } } -void remove_default_node(struct olsr_node* node) { - if (node->last_addr) { - _decrease_mpr_neigh(node); +void remove_default_node(struct olsr_node* node) +{ + if (node->last_addr) { + _decrease_mpr_neigh(node); - struct nhdp_node* mpr = h1_deriv(get_node(node->last_addr)); - if (mpr != NULL) - mpr->flood_neighbors--; + struct nhdp_node* mpr = h1_deriv(get_node(node->last_addr)); + if (mpr != NULL) + mpr->flood_neighbors--; - node->last_addr = netaddr_free(node->last_addr); - } + node->last_addr = netaddr_free(node->last_addr); + } - node->next_addr = netaddr_free(node->next_addr); + node->next_addr = netaddr_free(node->next_addr); } /* * moves the default route of node to other_routes */ -void push_default_route(struct olsr_node* node) { - struct netaddr* last_addr = node->last_addr; +void push_default_route(struct olsr_node* node) +{ + struct netaddr* last_addr = node->last_addr; - if (node->last_addr == NULL) - return; + if (node->last_addr == NULL) + return; - _decrease_mpr_neigh(node); - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + _decrease_mpr_neigh(node); + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); - /* don't add route if it already exists - this should never happen, right? */ - if (route != NULL) { - node->last_addr = netaddr_free(node->last_addr); - return; - } + /* don't add route if it already exists - this should never happen, right? */ + if (route != NULL) { + node->last_addr = netaddr_free(node->last_addr); + return; + } - route = simple_list_add_head(&node->other_routes); + route = simple_list_add_head(&node->other_routes); - if (route == NULL) { - printf("ERROR: out of memory in %s\n", __FUNCTION__); - return; - } + if (route == NULL) { + printf("ERROR: out of memory in %s\n", __FUNCTION__); + return; + } - route->expires = node->expires; - route->last_addr = node->last_addr; - route->link_metric = node->link_metric; - node->last_addr = NULL; + route->expires = node->expires; + route->last_addr = node->last_addr; + route->link_metric = node->link_metric; + node->last_addr = NULL; } -void pop_other_route(struct olsr_node* node, struct netaddr* last_addr) { - char skipped; - struct alt_route *route, *prev; - simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (netaddr_cmp(route->last_addr, last_addr)) - continue; - - node->last_addr = route->last_addr; - node->expires = route->expires; - node->link_metric = route->link_metric; - simple_list_for_each_remove(&node->other_routes, route, prev); - break; - } +void pop_other_route(struct olsr_node* node, struct netaddr* last_addr) +{ + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + if (netaddr_cmp(route->last_addr, last_addr)) + continue; + + node->last_addr = route->last_addr; + node->expires = route->expires; + node->link_metric = route->link_metric; + simple_list_for_each_remove(&node->other_routes, route, prev); + break; + } } -void remove_other_route(struct olsr_node* node, struct netaddr* last_addr) { - TRACE_FUN("%s (%s), %s", netaddr_to_str_s(&nbuf[0], node->addr), node->name, - netaddr_to_str_s(&nbuf[1], last_addr)); - - char skipped; - struct alt_route *route, *prev; - simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (netaddr_cmp(route->last_addr, last_addr)) - continue; - - struct nhdp_node* mpr = h1_deriv(get_node(route->last_addr)); - if (mpr != NULL) - mpr->flood_neighbors--; - - netaddr_free(route->last_addr); - simple_list_for_each_remove(&node->other_routes, route, prev); - break; - } +void remove_other_route(struct olsr_node* node, struct netaddr* last_addr) +{ + TRACE_FUN("%s (%s), %s", netaddr_to_str_s(&nbuf[0], node->addr), node->name, + netaddr_to_str_s(&nbuf[1], last_addr)); + + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + if (netaddr_cmp(route->last_addr, last_addr)) + continue; + + struct nhdp_node* mpr = h1_deriv(get_node(route->last_addr)); + if (mpr != NULL) + mpr->flood_neighbors--; + + netaddr_free(route->last_addr); + simple_list_for_each_remove(&node->other_routes, route, prev); + break; + } } diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index 440750818ef6..5f1a08ef3bda 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -15,74 +15,78 @@ extern char* local_name; #define LOST_ITER_MAX (1 << 3) enum { - NODE_TYPE_OLSR, - NODE_TYPE_NHDP + NODE_TYPE_OLSR, + NODE_TYPE_NHDP }; typedef uint32_t metric_t; /* simple list to store alternative routes */ struct alt_route { - struct alt_route* next; + struct alt_route* next; - struct netaddr* last_addr; - metric_t link_metric; - time_t expires; + struct netaddr* last_addr; + metric_t link_metric; + time_t expires; }; struct olsr_node { - struct avl_node node; /* for routing table Information Base */ + struct avl_node node; /* for routing table Information Base */ - struct netaddr* addr; /* node address */ - struct netaddr* next_addr; /* neighbor addr to send packets to for this node*/ - struct netaddr* last_addr; /* node that announced this node */ - struct alt_route* other_routes; /* other possible last_addrs */ + struct netaddr* addr; /* node address */ + struct netaddr* next_addr; /* neighbor addr to send packets to for this node*/ + struct netaddr* last_addr; /* node that announced this node */ + struct alt_route* other_routes; /* other possible last_addrs */ - time_t expires; /* time when this tuple is invalid */ - uint16_t seq_no; /* last seq_no from last_addr */ - uint8_t distance; /* hops between us and the node */ - metric_t link_metric; - metric_t path_metric; - struct netaddr* flood_mpr; /* flooding MPR to broadcast to this node (used for couting mpr_neigh_flood), 2-hop only */ + time_t expires; /* time when this tuple is invalid */ + uint16_t seq_no; /* last seq_no from last_addr */ + uint8_t distance; /* hops between us and the node */ + metric_t link_metric; + metric_t path_metric; + struct netaddr* flood_mpr; /* flooding MPR to broadcast to this node (used for couting mpr_neigh_flood), 2-hop only */ - uint8_t type : 1; /* node type */ - uint8_t pending : 1; /* whether the link can already be used - only 1-hop */ - uint8_t lost : 4; /* [4 bit] if set, the node will be annouced as lost - only 1-hop */ + uint8_t type : 1; /* node type */ + uint8_t pending : 1; /* whether the link can already be used - only 1-hop */ + uint8_t lost : 4; /* [4 bit] if set, the node will be annouced as lost - only 1-hop */ #ifdef ENABLE_NAME - char* name; /* node name from graph.gv */ + char* name; /* node name from graph.gv */ #endif }; struct nhdp_node { - struct olsr_node super; + struct olsr_node super; - uint8_t mpr_slctr_flood: 1; /* whether the node selected us as a flooding MPR */ + uint8_t mpr_slctr_flood: 1; /* whether the node selected us as a flooding MPR */ - uint8_t mpr_slctr_route: 1; /* whether the node selected us as a routing MPR */ + uint8_t mpr_slctr_route: 1; /* whether the node selected us as a routing MPR */ - /* number of --hop neighbors broadcast messages from this this node can reach */ - uint8_t flood_neighbors; + /* number of --hop neighbors broadcast messages from this this node can reach */ + uint8_t flood_neighbors; - /* number of 2-hop neighbors reached if this node is used as flooding MPR */ - uint8_t mpr_neigh_flood; + /* number of 2-hop neighbors reached if this node is used as flooding MPR */ + uint8_t mpr_neigh_flood; - /* number of 2-hop neighbors reached through this node aka if this value is > 0, it's a routing MPR */ - uint8_t mpr_neigh_route; + /* number of 2-hop neighbors reached through this node aka if this value is > 0, it's a routing MPR */ + uint8_t mpr_neigh_route; - /* average packet loss, decides if it should be used as 1-hop neigh */ - float link_quality; + /* average packet loss, decides if it should be used as 1-hop neigh */ + float link_quality; }; -static inline struct olsr_node* h1_super(struct nhdp_node* n) { return (struct olsr_node*) n; } -static inline struct nhdp_node* h1_deriv(struct olsr_node* n) { - if (n == NULL) - return 0; +static inline struct olsr_node* h1_super(struct nhdp_node* n) +{ + return (struct olsr_node*) n; +} +static inline struct nhdp_node* h1_deriv(struct olsr_node* n) +{ + if (n == NULL) + return 0; - if (n->type != NODE_TYPE_NHDP) - return 0; + if (n->type != NODE_TYPE_NHDP) + return 0; - return (struct nhdp_node*) n; + return (struct nhdp_node*) n; } void node_init(void); diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 817116865de2..257807b132d3 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -29,417 +29,430 @@ #include "list.h" static struct olsr_node* _new_olsr_node(struct netaddr* addr, - uint8_t distance, metric_t metric, uint8_t vtime, char* name) { + uint8_t distance, metric_t metric, uint8_t vtime, char* name) +{ - struct olsr_node* n = calloc(1, sizeof(struct olsr_node)); + struct olsr_node* n = calloc(1, sizeof(struct olsr_node)); - if (n == NULL) - return NULL; + if (n == NULL) + return NULL; - n->addr = netaddr_dup(addr); + n->addr = netaddr_dup(addr); - if (n->addr == NULL) { - free(n); - return NULL; - } + if (n->addr == NULL) { + free(n); + return NULL; + } - n->node.key = n->addr; - n->type = NODE_TYPE_OLSR; - n->distance = distance; - n->link_metric = metric; - n->expires = time_now() + vtime; + n->node.key = n->addr; + n->type = NODE_TYPE_OLSR; + n->distance = distance; + n->link_metric = metric; + n->expires = time_now() + vtime; #ifdef ENABLE_NAME - if (name) - n->name = strdup(name); + if (name) + n->name = strdup(name); #endif - avl_insert(get_olsr_head(), &n->node); - return n; + avl_insert(get_olsr_head(), &n->node); + return n; } -static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) { - TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], old_flood_mpr)); - struct olsr_node *node; - avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance != 2) - continue; - if (node->flood_mpr != NULL && netaddr_cmp(old_flood_mpr, node->flood_mpr) != 0) - continue; - - DEBUG("chosing new flood MPR for %s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); - - struct nhdp_node *mpr_b, *mpr_a = h1_deriv(get_node(node->last_addr)); - struct alt_route *route; - simple_list_for_each(node->other_routes, route) { - mpr_b = h1_deriv(get_node(route->last_addr)); - if (mpr_b == NULL || h1_super(mpr_b)->pending) - continue; - if (mpr_a == NULL || h1_super(mpr_a)->pending || mpr_a->flood_neighbors < mpr_b->flood_neighbors) - mpr_a = mpr_b; - } - - if (mpr_a != NULL) { - mpr_a->mpr_neigh_flood++; - - netaddr_switch(&node->flood_mpr, h1_super(mpr_a)->addr); - DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], node->flood_mpr)); - } else - node->flood_mpr = netaddr_free(node->flood_mpr); - - DEBUG("\tnew flood MPR: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); - } +static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) +{ + TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], old_flood_mpr)); + struct olsr_node *node; + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance != 2) + continue; + if (node->flood_mpr != NULL && netaddr_cmp(old_flood_mpr, node->flood_mpr) != 0) + continue; + + DEBUG("chosing new flood MPR for %s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); + + struct nhdp_node *mpr_b, *mpr_a = h1_deriv(get_node(node->last_addr)); + struct alt_route *route; + simple_list_for_each(node->other_routes, route) { + mpr_b = h1_deriv(get_node(route->last_addr)); + if (mpr_b == NULL || h1_super(mpr_b)->pending) + continue; + if (mpr_a == NULL || h1_super(mpr_a)->pending || mpr_a->flood_neighbors < mpr_b->flood_neighbors) + mpr_a = mpr_b; + } + + if (mpr_a != NULL) { + mpr_a->mpr_neigh_flood++; + + netaddr_switch(&node->flood_mpr, h1_super(mpr_a)->addr); + DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + } else + node->flood_mpr = netaddr_free(node->flood_mpr); + + DEBUG("\tnew flood MPR: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + } } /* * find a new route for nodes that use last_addr as their default route * if lost_node_addr is not null, all reference to it will be removed (aka lost node) */ -static void _update_children(struct netaddr* last_addr, struct netaddr* lost_node_addr) { - TRACE_FUN("%s, %s", netaddr_to_str_s(&nbuf[0], last_addr), - netaddr_to_str_s(&nbuf[1], lost_node_addr)); +static void _update_children(struct netaddr* last_addr, struct netaddr* lost_node_addr) +{ + TRACE_FUN("%s, %s", netaddr_to_str_s(&nbuf[0], last_addr), + netaddr_to_str_s(&nbuf[1], lost_node_addr)); - struct olsr_node *node; - avl_for_each_element(get_olsr_head(), node, node) { + struct olsr_node *node; + avl_for_each_element(get_olsr_head(), node, node) { - if (lost_node_addr != NULL) { - remove_other_route(node, lost_node_addr); - if (node->flood_mpr != NULL && netaddr_cmp(lost_node_addr, node->flood_mpr) == 0) - node->flood_mpr = netaddr_free(node->flood_mpr); - } + if (lost_node_addr != NULL) { + remove_other_route(node, lost_node_addr); + if (node->flood_mpr != NULL && netaddr_cmp(lost_node_addr, node->flood_mpr) == 0) + node->flood_mpr = netaddr_free(node->flood_mpr); + } - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { - if (lost_node_addr != NULL) - remove_default_node(node); - else - push_default_route(node); + if (lost_node_addr != NULL) + remove_default_node(node); + else + push_default_route(node); - add_free_node(node); + add_free_node(node); - _update_children(node->addr, lost_node_addr); - } - } + _update_children(node->addr, lost_node_addr); + } + } } -static void _olsr_node_expired(struct olsr_node* node) { - TRACE_FUN(); +static void _olsr_node_expired(struct olsr_node* node) +{ + TRACE_FUN(); - remove_default_node(node); - _update_children(node->addr, NULL); + remove_default_node(node); + _update_children(node->addr, NULL); - add_free_node(node); + add_free_node(node); - // 1-hop neighbors will become normal olsr_nodes here, should we care? (possible waste of memory) + // 1-hop neighbors will become normal olsr_nodes here, should we care? (possible waste of memory) } -static void _remove_olsr_node(struct olsr_node* node) { - TRACE_FUN(); +static void _remove_olsr_node(struct olsr_node* node) +{ + TRACE_FUN(); - avl_remove(get_olsr_head(), &node->node); - remove_free_node(node); + avl_remove(get_olsr_head(), &node->node); + remove_free_node(node); - /* remove other routes from node that is about to be deleted */ - char skipped; - struct alt_route *route, *prev; - simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - netaddr_free(route->last_addr); - simple_list_for_each_remove(&node->other_routes, route, prev); - } + /* remove other routes from node that is about to be deleted */ + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + netaddr_free(route->last_addr); + simple_list_for_each_remove(&node->other_routes, route, prev); + } - netaddr_free(node->flood_mpr); + netaddr_free(node->flood_mpr); - remove_default_node(node); - _update_children(node->addr, node->addr); + remove_default_node(node); + _update_children(node->addr, node->addr); #ifdef ENABLE_NAME - if (node->name) - free(node->name); + if (node->name) + free(node->name); #endif - netaddr_free(node->addr); - free(node); + netaddr_free(node->addr); + free(node); } -static bool _route_expired(struct olsr_node* node, struct netaddr* last_addr) { - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) - return time_now() > node->expires; +static bool _route_expired(struct olsr_node* node, struct netaddr* last_addr) +{ + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + return time_now() > node->expires; - if (node->other_routes == NULL) - return true; + if (node->other_routes == NULL) + return true; - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); - if (route == NULL) - return true; + if (route == NULL) + return true; - return time_now() > route->expires; + return time_now() > route->expires; } -static void _update_link_quality(struct nhdp_node* node) { - TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); - if (_route_expired(h1_super(node), get_local_addr())) - node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING); - else - node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING) + OLSR2_HYST_SCALING; - - if (!h1_super(node)->pending && node->link_quality < OLSR2_HYST_LOW) { - h1_super(node)->pending = 1; - h1_super(node)->lost = LOST_ITER_MAX; - - if (node->mpr_neigh_flood > 0) - _get_new_flood_mpr(h1_super(node)->addr); - - node->mpr_neigh_flood = 0; - node->mpr_neigh_route = 0; - - add_free_node(h1_super(node)); - push_default_route(h1_super(node)); - _update_children(h1_super(node)->addr, NULL); - } - - if (h1_super(node)->pending && node->link_quality > OLSR2_HYST_HIGH) { - h1_super(node)->pending = 0; - h1_super(node)->lost = 0; - - /* node may just have become a 1-hop node */ - push_default_route(h1_super(node)); - add_free_node(h1_super(node)); - } +static void _update_link_quality(struct nhdp_node* node) +{ + TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); + if (_route_expired(h1_super(node), get_local_addr())) + node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING); + else + node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING) + OLSR2_HYST_SCALING; + + if (!h1_super(node)->pending && node->link_quality < OLSR2_HYST_LOW) { + h1_super(node)->pending = 1; + h1_super(node)->lost = LOST_ITER_MAX; + + if (node->mpr_neigh_flood > 0) + _get_new_flood_mpr(h1_super(node)->addr); + + node->mpr_neigh_flood = 0; + node->mpr_neigh_route = 0; + + add_free_node(h1_super(node)); + push_default_route(h1_super(node)); + _update_children(h1_super(node)->addr, NULL); + } + + if (h1_super(node)->pending && node->link_quality > OLSR2_HYST_HIGH) { + h1_super(node)->pending = 0; + h1_super(node)->lost = 0; + + /* node may just have become a 1-hop node */ + push_default_route(h1_super(node)); + add_free_node(h1_super(node)); + } } -bool remove_expired(struct olsr_node* node) { - time_t _now = time_now(); +bool remove_expired(struct olsr_node* node) +{ + time_t _now = time_now(); - if (node->type == NODE_TYPE_NHDP) - _update_link_quality(h1_deriv(node)); + if (node->type == NODE_TYPE_NHDP) + _update_link_quality(h1_deriv(node)); - char skipped; - struct alt_route *route, *prev; - simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (_now - route->expires < OLSR2_HOLD_TIME_SECONDS) - continue; + char skipped; + struct alt_route *route, *prev; + simple_list_for_each_safe(node->other_routes, route, prev, skipped) { + if (_now - route->expires < OLSR2_HOLD_TIME_SECONDS) + continue; - DEBUG("alternative route to %s (%s) via %s expired, removing it", - node->name, netaddr_to_str_s(&nbuf[0], node->addr), - netaddr_to_str_s(&nbuf[1], route->last_addr)); - simple_list_for_each_remove(&node->other_routes, route, prev); - } + DEBUG("alternative route to %s (%s) via %s expired, removing it", + node->name, netaddr_to_str_s(&nbuf[0], node->addr), + netaddr_to_str_s(&nbuf[1], route->last_addr)); + simple_list_for_each_remove(&node->other_routes, route, prev); + } - if (_now - node->expires > OLSR2_HOLD_TIME_SECONDS) { + if (_now - node->expires > OLSR2_HOLD_TIME_SECONDS) { - DEBUG("%s (%s) expired", - node->name, netaddr_to_str_s(&nbuf[0], node->addr)); + DEBUG("%s (%s) expired", + node->name, netaddr_to_str_s(&nbuf[0], node->addr)); - if (node->other_routes == NULL) { - _remove_olsr_node(node); - return true; - } else - _olsr_node_expired(node); - } + if (node->other_routes == NULL) { + _remove_olsr_node(node); + return true; + } else + _olsr_node_expired(node); + } - return false; + return false; } -void route_expired(struct olsr_node* node, struct netaddr* last_addr) { - DEBUG("%s (%s) over %s expired", - node->name, netaddr_to_str_s(&nbuf[0], node->addr), - netaddr_to_str_s(&nbuf[1], last_addr)); +void route_expired(struct olsr_node* node, struct netaddr* last_addr) +{ + DEBUG("%s (%s) over %s expired", + node->name, netaddr_to_str_s(&nbuf[0], node->addr), + netaddr_to_str_s(&nbuf[1], last_addr)); - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) - _olsr_node_expired(node); - else - remove_other_route(node, last_addr); + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + _olsr_node_expired(node); + else + remove_other_route(node, last_addr); - if (node->last_addr == NULL && node->other_routes == NULL) - _remove_olsr_node(node); + if (node->last_addr == NULL && node->other_routes == NULL) + _remove_olsr_node(node); } -void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char* name) { - struct olsr_node* n = get_node(addr); +void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char* name) +{ + struct olsr_node* n = get_node(addr); - if (n == NULL) - n = _new_olsr_node(addr, distance, metric, vtime, name); + if (n == NULL) + n = _new_olsr_node(addr, distance, metric, vtime, name); - if (n == NULL) { - puts("ERROR: add_olsr_node failed - out of memory"); - return; - } + if (n == NULL) { + puts("ERROR: add_olsr_node failed - out of memory"); + return; + } - /* we have added a new node */ - if (n->last_addr == NULL) { + /* we have added a new node */ + if (n->last_addr == NULL) { #ifdef ENABLE_NAME - if (n->name == NULL && name != NULL) - n->name = strdup(name); + if (n->name == NULL && name != NULL) + n->name = strdup(name); #endif - add_other_route(n, last_addr, distance, metric, vtime); - add_free_node(n); - - return; - } - - struct olsr_node* new_lh = get_node(last_addr); - - /* minimize MPR count */ - if (new_lh->type == NODE_TYPE_NHDP) { - - /* see if a better flooding MPR is availiable */ - if (n->flood_mpr != NULL && netaddr_cmp(n->flood_mpr, last_addr) != 0) { - struct nhdp_node* old_flood_mpr = h1_deriv(get_node(n->flood_mpr)); - - if (old_flood_mpr != NULL && h1_deriv(new_lh)->flood_neighbors > old_flood_mpr->flood_neighbors) { - DEBUG("switching flooding MPR (%s -> %s)", h1_super(old_flood_mpr)->name, new_lh->name); - old_flood_mpr->mpr_neigh_flood--; - h1_deriv(new_lh)->mpr_neigh_flood++; - netaddr_switch(&n->flood_mpr, last_addr); - } - } - - /* see if a better routing MPR is availiable */ - if (new_lh->path_metric + metric == n->path_metric && netaddr_cmp(last_addr, n->last_addr) != 0) { - struct nhdp_node* cur_mpr = h1_deriv(get_node(n->next_addr)); - - /* see if the new route is better, that means uses a neighbor that is alreay - used for reaching (more) 2-hop neighbors. */ - if (cur_mpr != NULL && (new_lh != NULL && - h1_deriv(new_lh)->mpr_neigh_route + 1 > cur_mpr->mpr_neigh_route)) { - DEBUG("switching routing MPR (%s -> %s)", h1_super(cur_mpr)->name, new_lh->name); - _update_children(n->addr, NULL); - push_default_route(n); - add_free_node(n); - } - } - } - - /* worse or same route */ - if (new_lh->path_metric + metric >= n->path_metric || netaddr_cmp(last_addr, n->last_addr) == 0) { - add_other_route(n, last_addr, distance, metric, vtime); - return; - } - - DEBUG("better route found (old: %d (%d) hops over %s new: %d (%d) hops over %s)", - n->distance, n->path_metric, netaddr_to_str_s(&nbuf[0], n->last_addr), - distance, new_lh->path_metric + metric, netaddr_to_str_s(&nbuf[1], last_addr)); - - n->distance = distance; // only to keep free_nodes sorted - _update_children(n->addr, NULL); - push_default_route(n); - add_other_route(n, last_addr, distance, metric, vtime); - add_free_node(n); + add_other_route(n, last_addr, distance, metric, vtime); + add_free_node(n); + + return; + } + + struct olsr_node* new_lh = get_node(last_addr); + + /* minimize MPR count */ + if (new_lh->type == NODE_TYPE_NHDP) { + + /* see if a better flooding MPR is availiable */ + if (n->flood_mpr != NULL && netaddr_cmp(n->flood_mpr, last_addr) != 0) { + struct nhdp_node* old_flood_mpr = h1_deriv(get_node(n->flood_mpr)); + + if (old_flood_mpr != NULL && h1_deriv(new_lh)->flood_neighbors > old_flood_mpr->flood_neighbors) { + DEBUG("switching flooding MPR (%s -> %s)", h1_super(old_flood_mpr)->name, new_lh->name); + old_flood_mpr->mpr_neigh_flood--; + h1_deriv(new_lh)->mpr_neigh_flood++; + netaddr_switch(&n->flood_mpr, last_addr); + } + } + + /* see if a better routing MPR is availiable */ + if (new_lh->path_metric + metric == n->path_metric && netaddr_cmp(last_addr, n->last_addr) != 0) { + struct nhdp_node* cur_mpr = h1_deriv(get_node(n->next_addr)); + + /* see if the new route is better, that means uses a neighbor that is alreay + used for reaching (more) 2-hop neighbors. */ + if (cur_mpr != NULL && (new_lh != NULL && + h1_deriv(new_lh)->mpr_neigh_route + 1 > cur_mpr->mpr_neigh_route)) { + DEBUG("switching routing MPR (%s -> %s)", h1_super(cur_mpr)->name, new_lh->name); + _update_children(n->addr, NULL); + push_default_route(n); + add_free_node(n); + } + } + } + + /* worse or same route */ + if (new_lh->path_metric + metric >= n->path_metric || netaddr_cmp(last_addr, n->last_addr) == 0) { + add_other_route(n, last_addr, distance, metric, vtime); + return; + } + + DEBUG("better route found (old: %d (%d) hops over %s new: %d (%d) hops over %s)", + n->distance, n->path_metric, netaddr_to_str_s(&nbuf[0], n->last_addr), + distance, new_lh->path_metric + metric, netaddr_to_str_s(&nbuf[1], last_addr)); + + n->distance = distance; // only to keep free_nodes sorted + _update_children(n->addr, NULL); + push_default_route(n); + add_other_route(n, last_addr, distance, metric, vtime); + add_free_node(n); } -bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) { - struct olsr_node* node = get_node(addr); - if (!node) { - node = _new_olsr_node(addr, 255, RFC5444_METRIC_INFINITE, vtime, NULL); - node->seq_no = seq_no; - return false; - } - - uint16_t tmp = node->seq_no; - /* S1 > S2 AND S1 - S2 < MAXVALUE/2 OR - S2 > S1 AND S2 - S1 > MAXVALUE/2 */ - if (((seq_no > tmp) && (seq_no - tmp < (1 << 15))) || - ((seq_no < tmp) && (tmp - seq_no > (1 << 15))) ) { - node->seq_no = seq_no; - return false; - } - - return true; +bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) +{ + struct olsr_node* node = get_node(addr); + if (!node) { + node = _new_olsr_node(addr, 255, RFC5444_METRIC_INFINITE, vtime, NULL); + node->seq_no = seq_no; + return false; + } + + uint16_t tmp = node->seq_no; + /* S1 > S2 AND S1 - S2 < MAXVALUE/2 OR + S2 > S1 AND S2 - S1 > MAXVALUE/2 */ + if (((seq_no > tmp) && (seq_no - tmp < (1 << 15))) || + ((seq_no < tmp) && (tmp - seq_no > (1 << 15))) ) { + node->seq_no = seq_no; + return false; + } + + return true; } #ifdef ENABLE_NAME -void print_routing_graph(void) { - puts("\n----BEGIN ROUTING GRAPH----\n"); - puts("subgraph routing {"); - puts("\tedge [ color = red ]"); - struct olsr_node* node, *tmp; - avl_for_each_element(get_olsr_head(), node, node) { - if (node->addr != NULL && node->last_addr != NULL) { - tmp = get_node(node->last_addr); - printf("\t%s -> %s\n", tmp ? tmp->name : local_name, node->name); - } - } - puts("}"); - - puts("subgraph mpr_f {"); - puts("\tedge [ color = green ]"); - puts("// BEGIN FLOODING MPR"); - avl_for_each_element(get_olsr_head(), node, node) { - if (node->type == NODE_TYPE_NHDP && h1_deriv(node)->mpr_slctr_flood) { - printf("\t%s -> %s\n", node->name, local_name); - } - } - puts("// END FLOODING MPR"); - puts("}"); - - puts("subgraph mpr_r {"); - puts("\tedge [ color = blue ]"); - puts("// BEGIN ROUTING MPR"); - avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance == 1 && h1_deriv(node)->mpr_slctr_route) { - printf("\t%s -> %s\n", node->name, local_name); - } - } - puts("// END ROUTING MPR"); - puts("}"); - - puts("\n----END ROUTING GRAPH----\n"); +void print_routing_graph(void) +{ + puts("\n----BEGIN ROUTING GRAPH----\n"); + puts("subgraph routing {"); + puts("\tedge [ color = red ]"); + struct olsr_node* node, *tmp; + avl_for_each_element(get_olsr_head(), node, node) { + if (node->addr != NULL && node->last_addr != NULL) { + tmp = get_node(node->last_addr); + printf("\t%s -> %s\n", tmp ? tmp->name : local_name, node->name); + } + } + puts("}"); + + puts("subgraph mpr_f {"); + puts("\tedge [ color = green ]"); + puts("// BEGIN FLOODING MPR"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->type == NODE_TYPE_NHDP && h1_deriv(node)->mpr_slctr_flood) { + printf("\t%s -> %s\n", node->name, local_name); + } + } + puts("// END FLOODING MPR"); + puts("}"); + + puts("subgraph mpr_r {"); + puts("\tedge [ color = blue ]"); + puts("// BEGIN ROUTING MPR"); + avl_for_each_element(get_olsr_head(), node, node) { + if (node->distance == 1 && h1_deriv(node)->mpr_slctr_route) { + printf("\t%s -> %s\n", node->name, local_name); + } + } + puts("// END ROUTING MPR"); + puts("}"); + + puts("\n----END ROUTING GRAPH----\n"); } #else void print_routing_graph(void) {} #endif -void print_topology_set(void) { +void print_topology_set(void) +{ #ifndef ENABLE_DEBUG_OLSR - struct netaddr_str nbuf[3]; + struct netaddr_str nbuf[3]; #endif - struct alt_route* route; - struct olsr_node* node; + struct alt_route* route; + struct olsr_node* node; - puts(""); - puts("---[ Topology Set ]--"); + puts(""); + puts("---[ Topology Set ]--"); #ifdef ENABLE_NAME - printf(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), local_name); + printf(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), local_name); #else - printf(" [%s]\n", netaddr_to_str_s(&nbuf[0], get_local_addr())); + printf(" [%s]\n", netaddr_to_str_s(&nbuf[0], get_local_addr())); #endif - avl_for_each_element(get_olsr_head(), node, node) { + avl_for_each_element(get_olsr_head(), node, node) { - printf("%s ", netaddr_to_str_s(&nbuf[0], node->addr)); + printf("%s ", netaddr_to_str_s(&nbuf[0], node->addr)); #ifdef ENABLE_NAME - printf("(%s)", node->name); + printf("(%s)", node->name); #endif - printf("\t=> %s; %d hops, metric: %d, next: %s (%d), %lds ", - netaddr_to_str_s(&nbuf[1], node->last_addr), - node->distance, - node->path_metric, - netaddr_to_str_s(&nbuf[2], node->next_addr), - node->link_metric, - node->expires - time_now()); - if (node->type == NODE_TYPE_NHDP) { - printf("%s %.2f ", - node->pending ? "pending" : "", - h1_deriv(node)->link_quality); - printf("[%d/%d|%d] [%s%s]", - h1_deriv(node)->mpr_neigh_flood, - h1_deriv(node)->flood_neighbors, - h1_deriv(node)->mpr_neigh_route, - h1_deriv(node)->mpr_slctr_flood ? "F" : " ", - h1_deriv(node)->mpr_slctr_route ? "R" : " " - ); - } - if (node->flood_mpr != NULL) - printf(" flood: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); - puts(""); - - simple_list_for_each (node->other_routes, route) { - printf("\t\t\t=> %s (%d); %ld s\n", - netaddr_to_str_s(&nbuf[0], route->last_addr), - route->link_metric, - route->expires - time_now()); - } - } - puts("---------------------"); + printf("\t=> %s; %d hops, metric: %d, next: %s (%d), %lds ", + netaddr_to_str_s(&nbuf[1], node->last_addr), + node->distance, + node->path_metric, + netaddr_to_str_s(&nbuf[2], node->next_addr), + node->link_metric, + node->expires - time_now()); + if (node->type == NODE_TYPE_NHDP) { + printf("%s %.2f ", + node->pending ? "pending" : "", + h1_deriv(node)->link_quality); + printf("[%d/%d|%d] [%s%s]", + h1_deriv(node)->mpr_neigh_flood, + h1_deriv(node)->flood_neighbors, + h1_deriv(node)->mpr_neigh_route, + h1_deriv(node)->mpr_slctr_flood ? "F" : " ", + h1_deriv(node)->mpr_slctr_route ? "R" : " " + ); + } + if (node->flood_mpr != NULL) + printf(" flood: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + puts(""); + + simple_list_for_each (node->other_routes, route) { + printf("\t\t\t=> %s (%d); %ld s\n", + netaddr_to_str_s(&nbuf[0], route->last_addr), + route->link_metric, + route->expires - time_now()); + } + } + puts("---------------------"); } diff --git a/sys/net/routing/olsr2/olsr_debug.h b/sys/net/routing/olsr2/olsr_debug.h index 1c32ba3aad6d..ce8ed29f3ca8 100644 --- a/sys/net/routing/olsr2/olsr_debug.h +++ b/sys/net/routing/olsr2/olsr_debug.h @@ -35,21 +35,22 @@ char _t_buf[9]; printf(("[%d, %s] %s(" fmt ")\n"), debug_ticks, _t_buf, __FUNCTION__, ##__VA_ARGS__); \ } -static inline void print_trace(void) { - void *array[10]; - size_t size; - char **strings; - size_t i; +static inline void print_trace(void) +{ + void *array[10]; + size_t size; + char **strings; + size_t i; - size = backtrace(array, 10); - strings = backtrace_symbols(array, size); + size = backtrace(array, 10); + strings = backtrace_symbols(array, size); - printf("Obtained %zd stack frames.\n", size); + printf("Obtained %zd stack frames.\n", size); - for (i = 0; i < size; i++) - printf ("%s\n", strings[i]); + for (i = 0; i < size; i++) + printf ("%s\n", strings[i]); - free(strings); + free(strings); } #endif /* not RIOT */ diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 0ec989e8cf62..de3fa7011953 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -45,9 +45,9 @@ static char receive_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; static char sender_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; struct timer_msg { - vtimer_t timer; - timex_t interval; - void (*func) (void); + vtimer_t timer; + timex_t interval; + void (*func) (void); }; static struct timer_msg msg_hello = { .timer = {0}, .interval = { .seconds = OLSR2_HELLO_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_hello }; @@ -59,148 +59,155 @@ static mutex_t olsr_data; #if defined(BOARD_NATIVE) && defined(ENABLE_NAME) static char _name[5]; -static char* gen_name(char* dest, const size_t len) { - for (int i = 0; i < len - 1; ++i) - dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); - dest[len - 1] = '\0'; - return dest; +static char* gen_name(char* dest, const size_t len) +{ + for (int i = 0; i < len - 1; ++i) + dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); + dest[len - 1] = '\0'; + return dest; } #endif static void write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), - struct rfc5444_writer_target *iface __attribute__((unused)), - void *buffer, size_t length) { + struct rfc5444_writer_target *iface __attribute__((unused)), + void *buffer, size_t length) +{ #ifdef ENABLE_LEDS - LED_GREEN_TOGGLE; + LED_GREEN_TOGGLE; #endif - int bytes_send = destiny_socket_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); + int bytes_send = destiny_socket_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); - DEBUG("write_packet(%d bytes), %d bytes sent", length, bytes_send); + DEBUG("write_packet(%d bytes), %d bytes sent", length, bytes_send); } -static void olsr_receiver_thread(void) { - char buffer[256]; +static void olsr_receiver_thread(void) +{ + char buffer[256]; - sockaddr6_t sa = {0}; - sa.sin6_family = AF_INET6; - sa.sin6_port = HTONS(MANET_PORT); + sockaddr6_t sa = {0}; + sa.sin6_family = AF_INET6; + sa.sin6_port = HTONS(MANET_PORT); - if (destiny_socket_bind(sock, &sa, sizeof sa) < 0) { - printf("Error bind failed!\n"); - destiny_socket_close(sock); - } + if (destiny_socket_bind(sock, &sa, sizeof sa) < 0) { + printf("Error bind failed!\n"); + destiny_socket_close(sock); + } - int32_t recsize; - uint32_t fromlen = sizeof sa; + int32_t recsize; + uint32_t fromlen = sizeof sa; - struct netaddr _src; - _src._type = AF_INET6; - _src._prefix_len = 128; + struct netaddr _src; + _src._type = AF_INET6; + _src._prefix_len = 128; - while (1) { - recsize = destiny_socket_recvfrom(sock, &buffer, sizeof buffer, 0, &sa, &fromlen); + while (1) { + recsize = destiny_socket_recvfrom(sock, &buffer, sizeof buffer, 0, &sa, &fromlen); #ifdef ENABLE_LEDS - LED_RED_TOGGLE; + LED_RED_TOGGLE; #endif - memcpy(&_src._addr, &sa.sin6_addr, sizeof _src._addr); - DEBUG("received %d bytes from %s", recsize, netaddr_to_str_s(&nbuf[0], &_src)); + memcpy(&_src._addr, &sa.sin6_addr, sizeof _src._addr); + DEBUG("received %d bytes from %s", recsize, netaddr_to_str_s(&nbuf[0], &_src)); - mutex_lock(&olsr_data); - reader_handle_packet(&buffer, recsize, &_src, 1); // TODO: proper metric - mutex_unlock(&olsr_data); - } + mutex_lock(&olsr_data); + reader_handle_packet(&buffer, recsize, &_src, 1); // TODO: proper metric + mutex_unlock(&olsr_data); + } } -static void olsr_sender_thread(void) { - DEBUG("olsr_sender_thread, pid %d\n", thread_getpid()); +static void olsr_sender_thread(void) +{ + DEBUG("olsr_sender_thread, pid %d\n", thread_getpid()); - /* message queue, so messages don't get lost */ - msg_t msgq[2]; - msg_init_queue(msgq, sizeof msgq); + /* message queue, so messages don't get lost */ + msg_t msgq[2]; + msg_init_queue(msgq, sizeof msgq); - while (1) { - msg_t m; - msg_receive(&m); - struct timer_msg* tmsg = (struct timer_msg*) m.content.ptr; + while (1) { + msg_t m; + msg_receive(&m); + struct timer_msg* tmsg = (struct timer_msg*) m.content.ptr; - mutex_lock(&olsr_data); - tmsg->func(); - mutex_unlock(&olsr_data); + mutex_lock(&olsr_data); + tmsg->func(); + mutex_unlock(&olsr_data); - /* add jitter */ - tmsg->interval.microseconds = genrand_uint32() % OLSR2_MAX_JITTER_US; + /* add jitter */ + tmsg->interval.microseconds = genrand_uint32() % OLSR2_MAX_JITTER_US; - if (vtimer_set_msg(&tmsg->timer, tmsg->interval, thread_getpid(), tmsg) != 0) - DEBUG("vtimer_set_msg failed, stopped sending"); - } + if (vtimer_set_msg(&tmsg->timer, tmsg->interval, thread_getpid(), tmsg) != 0) + DEBUG("vtimer_set_msg failed, stopped sending"); + } } -static ipv6_addr_t* get_next_hop(ipv6_addr_t* dest) { - struct olsr_node* node = get_node((struct netaddr*) dest); // get_node will only look at the first few bytes - if (node == NULL) - return NULL; +static ipv6_addr_t* get_next_hop(ipv6_addr_t* dest) +{ + struct olsr_node* node = get_node((struct netaddr*) dest); // get_node will only look at the first few bytes + if (node == NULL) + return NULL; - return (ipv6_addr_t*) node->next_addr; + return (ipv6_addr_t*) node->next_addr; } #ifdef ENABLE_NAME -ipv6_addr_t* get_ip_by_name(char* name) { - struct olsr_node *node; - avl_for_each_element(get_olsr_head(), node, node) { - if (node->name != NULL && strcmp(node->name, name) == 0) - return (ipv6_addr_t*) node->addr; - } - - return NULL; +ipv6_addr_t* get_ip_by_name(char* name) +{ + struct olsr_node *node; + avl_for_each_element(get_olsr_head(), node, node) { + if (node->name != NULL && strcmp(node->name, name) == 0) + return (ipv6_addr_t*) node->addr; + } + + return NULL; } #endif -void olsr_init(void) { +void olsr_init(void) +{ #ifdef ENABLE_NAME #ifdef BOARD_NATIVE - local_name = gen_name(_name, sizeof _name); + local_name = gen_name(_name, sizeof _name); #else - local_name = sysconfig.name; + local_name = sysconfig.name; #endif #endif - mutex_init(&olsr_data); - node_init(); - reader_init(); - writer_init(write_packet); - - /* we always send to the same broadcast address, prepare it once */ - sa_bcast.sin6_family = AF_INET6; - sa_bcast.sin6_port = HTONS(MANET_PORT); - ipv6_addr_set_all_nodes_addr(&sa_bcast.sin6_addr); - - /* enable receive */ - sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_receiver_thread, "olsr_rec"); - - /* set get_local_addr() */ - get_local_addr()->_type = AF_INET6; - get_local_addr()->_prefix_len = 128; - ipv6_net_if_get_best_src_addr((ipv6_addr_t*) get_local_addr(), &sa_bcast.sin6_addr); - - /* register olsr for routing */ - ipv6_iface_set_routing_provider(get_next_hop); - - DEBUG("This is node %s with IP %s", local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); - - /* enable sending */ - int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_sender_thread, "olsr_snd"); - - msg_t m; - DEBUG("setting up HELLO timer"); - m.content.ptr = (char*) &msg_hello; - msg_send(&m, pid, false); - - sleep_s(1); - DEBUG("setting up TC timer"); - m.content.ptr = (char*) &msg_tc; - msg_send(&m, pid, false); + mutex_init(&olsr_data); + node_init(); + reader_init(); + writer_init(write_packet); + + /* we always send to the same broadcast address, prepare it once */ + sa_bcast.sin6_family = AF_INET6; + sa_bcast.sin6_port = HTONS(MANET_PORT); + ipv6_addr_set_all_nodes_addr(&sa_bcast.sin6_addr); + + /* enable receive */ + sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_receiver_thread, "olsr_rec"); + + /* set get_local_addr() */ + get_local_addr()->_type = AF_INET6; + get_local_addr()->_prefix_len = 128; + ipv6_net_if_get_best_src_addr((ipv6_addr_t*) get_local_addr(), &sa_bcast.sin6_addr); + + /* register olsr for routing */ + ipv6_iface_set_routing_provider(get_next_hop); + + DEBUG("This is node %s with IP %s", local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); + + /* enable sending */ + int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_sender_thread, "olsr_snd"); + + msg_t m; + DEBUG("setting up HELLO timer"); + m.content.ptr = (char*) &msg_hello; + msg_send(&m, pid, false); + + sleep_s(1); + DEBUG("setting up TC timer"); + m.content.ptr = (char*) &msg_tc; + msg_send(&m, pid, false); } #endif /* RIOT */ diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 535a5b0ed493..757f60cbae72 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -52,291 +52,300 @@ static enum rfc5444_result _cb_packet_end(struct rfc5444_reader_tlvblock_context /* HELLO message */ static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_message_tlvs[] = { - [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, + [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, #ifdef ENABLE_NAME - [IDX_TLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, + [IDX_TLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif }; static struct rfc5444_reader_tlvblock_consumer_entry _nhdp_address_tlvs[] = { - [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, - [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, - [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, + [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME - [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif }; /* TC message */ static struct rfc5444_reader_tlvblock_consumer_entry _olsr_message_tlvs[] = { - [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, + [IDX_TLV_VTIME] = { .type = RFC5444_MSGTLV_VALIDITY_TIME, .mandatory = true }, #ifdef ENABLE_NAME - [IDX_TLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, + [IDX_TLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif }; static struct rfc5444_reader_tlvblock_consumer_entry _olsr_address_tlvs[] = { - [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, - [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME - [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif }; /* define callbacks for HELLO message */ static struct rfc5444_reader_tlvblock_consumer _nhdp_consumer = { - .msg_id = RFC5444_MSGTYPE_HELLO, - .block_callback = _cb_nhdp_blocktlv_packet_okay, - .end_callback = _cb_packet_end, + .msg_id = RFC5444_MSGTYPE_HELLO, + .block_callback = _cb_nhdp_blocktlv_packet_okay, + .end_callback = _cb_packet_end, }; static struct rfc5444_reader_tlvblock_consumer _nhdp_address_consumer = { - .msg_id = RFC5444_MSGTYPE_HELLO, - .addrblock_consumer = true, - .block_callback = _cb_nhdp_blocktlv_address_okay, + .msg_id = RFC5444_MSGTYPE_HELLO, + .addrblock_consumer = true, + .block_callback = _cb_nhdp_blocktlv_address_okay, }; /* define callbacks for TC message */ static struct rfc5444_reader_tlvblock_consumer _olsr_consumer = { - .msg_id = RFC5444_MSGTYPE_TC, - .block_callback = _cb_olsr_blocktlv_packet_okay, - .end_callback = _cb_packet_end, + .msg_id = RFC5444_MSGTYPE_TC, + .block_callback = _cb_olsr_blocktlv_packet_okay, + .end_callback = _cb_packet_end, }; static struct rfc5444_reader_tlvblock_consumer _olsr_address_consumer = { - .msg_id = RFC5444_MSGTYPE_TC, - .addrblock_consumer = true, - .block_callback = _cb_olsr_blocktlv_address_okay, + .msg_id = RFC5444_MSGTYPE_TC, + .addrblock_consumer = true, + .block_callback = _cb_olsr_blocktlv_address_okay, }; /* HELLO message */ static enum rfc5444_result -_cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __attribute__((unused))) { - DEBUG("received HELLO message:"); +_cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __attribute__((unused))) +{ + DEBUG("received HELLO message:"); - if (netaddr_cmp(get_local_addr(), current_src) == 0) - return RFC5444_DROP_PACKET; + if (netaddr_cmp(get_local_addr(), current_src) == 0) + return RFC5444_DROP_PACKET; - /* VTIME is defined as mandatory */ - vtime = rfc5444_timetlv_decode(*_nhdp_message_tlvs[IDX_TLV_VTIME].tlv->single_value); + /* VTIME is defined as mandatory */ + vtime = rfc5444_timetlv_decode(*_nhdp_message_tlvs[IDX_TLV_VTIME].tlv->single_value); - char* name = NULL; + char* name = NULL; #ifdef ENABLE_NAME - if (_nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv) { - name = (char*) _nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv->single_value; - DEBUG("\tfrom: %s (%s)", name, netaddr_to_str_s(&nbuf[0], current_src)); - } + if (_nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv) { + name = (char*) _nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv->single_value; + DEBUG("\tfrom: %s (%s)", name, netaddr_to_str_s(&nbuf[0], current_src)); + } #endif - DEBUG("\tmetric: %d", metric); + DEBUG("\tmetric: %d", metric); - current_node = olsr2_add_neighbor(current_src, metric, vtime, name); + current_node = olsr2_add_neighbor(current_src, metric, vtime, name); - if (current_node == NULL) { - puts("ERROR: olsr2_add_neighbor failed - out of memory"); - return RFC5444_DROP_PACKET; - } + if (current_node == NULL) { + puts("ERROR: olsr2_add_neighbor failed - out of memory"); + return RFC5444_DROP_PACKET; + } - /* reset MPR selector state, will be set by _cb_nhdp_blocktlv_address_okay */ - h1_deriv(current_node)->mpr_slctr_route = 0; - h1_deriv(current_node)->mpr_slctr_flood = 0; + /* reset MPR selector state, will be set by _cb_nhdp_blocktlv_address_okay */ + h1_deriv(current_node)->mpr_slctr_route = 0; + h1_deriv(current_node)->mpr_slctr_flood = 0; - if (current_node->pending) - return RFC5444_DROP_PACKET; + if (current_node->pending) + return RFC5444_DROP_PACKET; - return RFC5444_OKAY; + return RFC5444_OKAY; } /* HELLO announced addresses */ static enum rfc5444_result -_cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { - struct rfc5444_reader_tlvblock_entry* tlv; - metric_t link_metric = RFC5444_METRIC_MIN; +_cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) +{ + struct rfc5444_reader_tlvblock_entry* tlv; + metric_t link_metric = RFC5444_METRIC_MIN; - char* name = NULL; + char* name = NULL; #ifdef ENABLE_NAME - if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { - name = (char*) tlv->single_value; - DEBUG("\t2-hop neighbor: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); - } + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { + name = (char*) tlv->single_value; + DEBUG("\t2-hop neighbor: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); + } #endif - if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { - link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); - DEBUG("\t\tmetric: %d", link_metric); - } + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { + link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); + DEBUG("\t\tmetric: %d", link_metric); + } - if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { - switch (* (char*) tlv->single_value) { - struct olsr_node* lost; - case RFC5444_LINKSTATUS_LOST: - lost = get_node(&cont->addr); - DEBUG("\t\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { + switch (* (char*) tlv->single_value) { + struct olsr_node* lost; + case RFC5444_LINKSTATUS_LOST: + lost = get_node(&cont->addr); + DEBUG("\t\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); - if (lost != NULL) - route_expired(lost, current_node->addr); + if (lost != NULL) + route_expired(lost, current_node->addr); - return RFC5444_DROP_ADDRESS; - default: - DEBUG("\t\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); - } - } + return RFC5444_DROP_ADDRESS; + default: + DEBUG("\t\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + } + } - /* node broadcasts us as it's neighbor */ - if (netaddr_cmp(&cont->addr, get_local_addr()) == 0) { + /* node broadcasts us as it's neighbor */ + if (netaddr_cmp(&cont->addr, get_local_addr()) == 0) { - /* node selected us as mpr */ - if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_MPR].tlv)) { - h1_deriv(current_node)->mpr_slctr_flood = (*tlv->single_value & RFC5444_MPR_FLOODING) > 0; - h1_deriv(current_node)->mpr_slctr_route = (*tlv->single_value & RFC5444_MPR_ROUTING) > 0; + /* node selected us as mpr */ + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_MPR].tlv)) { + h1_deriv(current_node)->mpr_slctr_flood = (*tlv->single_value & RFC5444_MPR_FLOODING) > 0; + h1_deriv(current_node)->mpr_slctr_route = (*tlv->single_value & RFC5444_MPR_ROUTING) > 0; - DEBUG("\tflood: %d, route: %d", h1_deriv(current_node)->mpr_slctr_flood, h1_deriv(current_node)->mpr_slctr_route); - } + DEBUG("\tflood: %d, route: %d", h1_deriv(current_node)->mpr_slctr_flood, h1_deriv(current_node)->mpr_slctr_route); + } - } else - add_olsr_node(&cont->addr, current_src, vtime, 2, link_metric, name); + } else + add_olsr_node(&cont->addr, current_src, vtime, 2, link_metric, name); - return RFC5444_OKAY; + return RFC5444_OKAY; } /* TC message */ static enum rfc5444_result -_cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont) { - DEBUG("received TC message:"); +_cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont) +{ + DEBUG("received TC message:"); - if (!cont->has_origaddr) - return RFC5444_DROP_PACKET; + if (!cont->has_origaddr) + return RFC5444_DROP_PACKET; - if (!cont->has_seqno) - return RFC5444_DROP_PACKET; + if (!cont->has_seqno) + return RFC5444_DROP_PACKET; - if (!cont->has_hopcount || !cont->has_hoplimit) - return RFC5444_DROP_PACKET; + if (!cont->has_hopcount || !cont->has_hoplimit) + return RFC5444_DROP_PACKET; - if (!netaddr_cmp(get_local_addr(), current_src)) - return RFC5444_DROP_PACKET; + if (!netaddr_cmp(get_local_addr(), current_src)) + return RFC5444_DROP_PACKET; - if (!netaddr_cmp(get_local_addr(), &cont->orig_addr)) - return RFC5444_DROP_PACKET; + if (!netaddr_cmp(get_local_addr(), &cont->orig_addr)) + return RFC5444_DROP_PACKET; - vtime = rfc5444_timetlv_decode(*_olsr_message_tlvs[IDX_TLV_VTIME].tlv->single_value); + vtime = rfc5444_timetlv_decode(*_olsr_message_tlvs[IDX_TLV_VTIME].tlv->single_value); - if (is_known_msg(&cont->orig_addr, cont->seqno, vtime)) - return RFC5444_DROP_PACKET; + if (is_known_msg(&cont->orig_addr, cont->seqno, vtime)) + return RFC5444_DROP_PACKET; - DEBUG("\tfrom: %s", netaddr_to_str_s(&nbuf[0], &cont->orig_addr)); - DEBUG("\tsender: %s", netaddr_to_str_s(&nbuf[0], current_src)); - DEBUG("\tseqno: %d", cont->seqno); - DEBUG("\thops: %d", cont->hopcount); + DEBUG("\tfrom: %s", netaddr_to_str_s(&nbuf[0], &cont->orig_addr)); + DEBUG("\tsender: %s", netaddr_to_str_s(&nbuf[0], current_src)); + DEBUG("\tseqno: %d", cont->seqno); + DEBUG("\thops: %d", cont->hopcount); - hops = cont->hopcount + 1; /* hopcount starts with 0 for A -> B */ - _seq_no = cont->seqno; + hops = cont->hopcount + 1; /* hopcount starts with 0 for A -> B */ + _seq_no = cont->seqno; - return RFC5444_OKAY; + return RFC5444_OKAY; } /* TC announced addresses */ static enum rfc5444_result -_cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { - struct rfc5444_reader_tlvblock_entry* tlv __attribute__((unused)); - metric_t link_metric = RFC5444_METRIC_MIN; - char* name = NULL; +_cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) +{ + struct rfc5444_reader_tlvblock_entry* tlv __attribute__((unused)); + metric_t link_metric = RFC5444_METRIC_MIN; + char* name = NULL; - if (netaddr_cmp(get_local_addr(), &cont->addr) == 0) - return RFC5444_DROP_ADDRESS; + if (netaddr_cmp(get_local_addr(), &cont->addr) == 0) + return RFC5444_DROP_ADDRESS; #ifdef ENABLE_NAME - if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { - name = (char*) tlv->single_value; - DEBUG("\tannounces: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); - } + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { + name = (char*) tlv->single_value; + DEBUG("\tannounces: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); + } #endif - if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { - switch (* (char*) tlv->single_value) { - struct olsr_node* lost; - case RFC5444_LINKSTATUS_LOST: - lost = get_node(&cont->addr); - DEBUG("\texpired node reported, removing it (TC)%s", lost ? "" : " [not found]"); + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { + switch (* (char*) tlv->single_value) { + struct olsr_node* lost; + case RFC5444_LINKSTATUS_LOST: + lost = get_node(&cont->addr); + DEBUG("\texpired node reported, removing it (TC)%s", lost ? "" : " [not found]"); - if (lost != NULL) - route_expired(lost, &cont->orig_addr); + if (lost != NULL) + route_expired(lost, &cont->orig_addr); - /* emergency flood */ - struct nhdp_node* node = h1_deriv(get_node(current_src)); - if (node != NULL) - node->mpr_slctr_flood = 1; + /* emergency flood */ + struct nhdp_node* node = h1_deriv(get_node(current_src)); + if (node != NULL) + node->mpr_slctr_flood = 1; - return RFC5444_DROP_ADDRESS; - default: - DEBUG("\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); - } - } + return RFC5444_DROP_ADDRESS; + default: + DEBUG("\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + } + } - if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { - link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); - DEBUG("\t\tmetric: %d", link_metric); - } + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { + link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); + DEBUG("\t\tmetric: %d", link_metric); + } - /* hops is hopcount to orig_addr, addr is one more hop */ - add_olsr_node(&cont->addr, &cont->orig_addr, vtime, hops + 1, link_metric, name); + /* hops is hopcount to orig_addr, addr is one more hop */ + add_olsr_node(&cont->addr, &cont->orig_addr, vtime, hops + 1, link_metric, name); - return RFC5444_OKAY; + return RFC5444_OKAY; } static enum rfc5444_result -_cb_packet_end(struct rfc5444_reader_tlvblock_context *cont __attribute__((unused)), bool dropped __attribute__((unused))) { - fill_routing_table(); +_cb_packet_end(struct rfc5444_reader_tlvblock_context *cont __attribute__((unused)), bool dropped __attribute__((unused))) +{ + fill_routing_table(); - return RFC5444_OKAY; + return RFC5444_OKAY; } /* this is only called for messages with hopcount/hoplimit, that is only TC messages */ static void _cb_olsr_forward_message(struct rfc5444_reader_tlvblock_context *context __attribute__((unused)), - uint8_t *buffer, size_t length) { - struct olsr_node* node = get_node(current_src); - - /* only forward if node selected us as flooding MPR */ - if (node == NULL || h1_deriv(node)->mpr_slctr_flood == 0) - return; - - if (RFC5444_OKAY == rfc5444_writer_forward_msg(&writer, buffer, length)) { - DEBUG("\tforwarding"); - rfc5444_writer_flush(&writer, &interface, true); - } else - DEBUG("\tfailed forwarding package"); + uint8_t *buffer, size_t length) +{ + struct olsr_node* node = get_node(current_src); + + /* only forward if node selected us as flooding MPR */ + if (node == NULL || h1_deriv(node)->mpr_slctr_flood == 0) + return; + + if (RFC5444_OKAY == rfc5444_writer_forward_msg(&writer, buffer, length)) { + DEBUG("\tforwarding"); + rfc5444_writer_flush(&writer, &interface, true); + } else + DEBUG("\tfailed forwarding package"); } /** * Initialize RFC5444 reader */ -void reader_init(void) { - /* initialize reader */ - rfc5444_reader_init(&reader); - reader.forward_message = _cb_olsr_forward_message; - - /* register HELLO message consumer */ - rfc5444_reader_add_message_consumer(&reader, &_nhdp_consumer, _nhdp_message_tlvs, ARRAYSIZE(_nhdp_message_tlvs)); - rfc5444_reader_add_message_consumer(&reader, &_nhdp_address_consumer, _nhdp_address_tlvs, ARRAYSIZE(_nhdp_address_tlvs)); - - /* register TC message consumer */ - rfc5444_reader_add_message_consumer(&reader, &_olsr_consumer, _olsr_message_tlvs, ARRAYSIZE(_olsr_message_tlvs)); - rfc5444_reader_add_message_consumer(&reader, &_olsr_address_consumer, _olsr_address_tlvs, ARRAYSIZE(_olsr_address_tlvs)); +void reader_init(void) +{ + /* initialize reader */ + rfc5444_reader_init(&reader); + reader.forward_message = _cb_olsr_forward_message; + + /* register HELLO message consumer */ + rfc5444_reader_add_message_consumer(&reader, &_nhdp_consumer, _nhdp_message_tlvs, ARRAYSIZE(_nhdp_message_tlvs)); + rfc5444_reader_add_message_consumer(&reader, &_nhdp_address_consumer, _nhdp_address_tlvs, ARRAYSIZE(_nhdp_address_tlvs)); + + /* register TC message consumer */ + rfc5444_reader_add_message_consumer(&reader, &_olsr_consumer, _olsr_message_tlvs, ARRAYSIZE(_olsr_message_tlvs)); + rfc5444_reader_add_message_consumer(&reader, &_olsr_address_consumer, _olsr_address_tlvs, ARRAYSIZE(_olsr_address_tlvs)); } /** * Inject a package into the RFC5444 reader */ -int reader_handle_packet(void* buffer, size_t length, struct netaddr* src, uint8_t metric_in) { - current_src = src; - metric = metric_in; - return rfc5444_reader_handle_packet(&reader, buffer, length); +int reader_handle_packet(void* buffer, size_t length, struct netaddr* src, uint8_t metric_in) +{ + current_src = src; + metric = metric_in; + return rfc5444_reader_handle_packet(&reader, buffer, length); } /** * Cleanup RFC5444 reader */ -void reader_cleanup(void) { - rfc5444_reader_cleanup(&reader); +void reader_cleanup(void) +{ + rfc5444_reader_cleanup(&reader); } diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index 733e08e438c1..e11d5c69cabf 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -26,182 +26,185 @@ * Keeps yet unroutable nodes, so we don't have to traverse the entire list */ struct free_node { - struct free_node* next; - struct olsr_node* node; - uint8_t hops; // for sorting only + struct free_node* next; + struct olsr_node* node; + uint8_t hops; // for sorting only }; static struct free_node* _pending_head = 0; static bool _update_pending = false; -void add_free_node(struct olsr_node* node) { - struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); - if (n == NULL) { - uint8_t hops = node->distance; - n = simple_list_add_before(&_pending_head, hops); - } +void add_free_node(struct olsr_node* node) +{ + struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); + if (n == NULL) { + uint8_t hops = node->distance; + n = simple_list_add_before(&_pending_head, hops); + } - if (n == NULL) { - printf("ERROR: out of memory in %s\n", __FUNCTION__); - return; - } + if (n == NULL) { + printf("ERROR: out of memory in %s\n", __FUNCTION__); + return; + } - n->node = node; + n->node = node; - node->next_addr = netaddr_free(node->next_addr); /* empty next_addr marks route as pending */ - _update_pending = true; + node->next_addr = netaddr_free(node->next_addr); /* empty next_addr marks route as pending */ + _update_pending = true; } -bool remove_free_node(struct olsr_node* node) { - struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); - if (n == NULL) - return false; - return simple_list_remove(&_pending_head, n); +bool remove_free_node(struct olsr_node* node) +{ + struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); + if (n == NULL) + return false; + return simple_list_remove(&_pending_head, n); } -void fill_routing_table(void) { - struct free_node* head = _pending_head; - - if (_pending_head == NULL || !_update_pending) - return; - - _update_pending = false; - DEBUG("update routing table"); - - struct free_node* fn; - bool noop = false; /* when in an iteration there was nothing removed from free nodes */ - while (head && !noop) { - noop = true; /* if no nodes could be removed in an iteration, abort */ - struct free_node *prev; - char skipped; - simple_list_for_each_safe(head, fn, prev, skipped) { - DEBUG("trying to find a route to %s", fn->node->name); - /* chose shortest route from the set of availiable routes */ - metric_t min_mtrc = RFC5444_METRIC_INFINITE; - struct olsr_node* node = NULL; /* chosen route */ - struct nhdp_node* flood_mpr = NULL; - struct alt_route* route; /* current other_route */ - simple_list_for_each(fn->node->other_routes, route) { - DEBUG("\tconsidering %s (%d)", netaddr_to_string(&nbuf[0], route->last_addr), route->link_metric); - - /* the node is actually a neighbor of ours */ - if (netaddr_cmp(route->last_addr, get_local_addr()) == 0) { - DEBUG("\t\t1-hop neighbor"); - - /* don't use pending nodes */ - if (fn->node->pending) { - DEBUG("\t\tpending -> skipped"); - continue; - } - - if (route->link_metric > min_mtrc) - continue; - - min_mtrc = route->link_metric; - node = fn->node; - continue; - } - - /* see if we can find a better route */ - struct olsr_node* _tmp = get_node(route->last_addr); - if (_tmp == NULL || _tmp->addr == NULL || _tmp->next_addr == NULL) { - DEBUG("\t\tnot routable"); - continue; - } - - /* ignore pending nodes */ - if (_tmp->distance == 1 && _tmp->pending) { - DEBUG("\t\tpending -> skipped"); - continue; - } - - /* flooding MPR selection */ - if (_tmp->type == NODE_TYPE_NHDP && - (flood_mpr == NULL || flood_mpr->flood_neighbors < h1_deriv(_tmp)->flood_neighbors)) - flood_mpr = h1_deriv(_tmp); - - if (_tmp->path_metric + route->link_metric > min_mtrc) { - DEBUG("\t\tdoesn't offer a better route, %d + %d > %d", _tmp->path_metric, route->link_metric, min_mtrc); - continue; - } - - /* try to minimize MPR count */ - if (_tmp->type == NODE_TYPE_NHDP && min_mtrc == _tmp->path_metric + route->link_metric) { - DEBUG("\t\tequaly good route found, try to optimize MPR seleciton"); - struct nhdp_node* old_mpr = h1_deriv(node); - - /* a direct neighbor might be reached over an additional hop, the true MPR */ - if (netaddr_cmp(_tmp->next_addr, _tmp->addr) != 0) - old_mpr = h1_deriv(get_node(_tmp->next_addr)); - - /* use the neighbor with the most 2-hop neighbors */ - if (old_mpr->mpr_neigh_route >= h1_deriv(_tmp)->mpr_neigh_route + 1) { - DEBUG("\t\told MPR (%d) is better (new: %d)", old_mpr->mpr_neigh_route, h1_deriv(_tmp)->mpr_neigh_route); - continue; - } - } - - DEBUG("\t\t[possible candidate]"); - node = _tmp; - min_mtrc = _tmp->path_metric + route->link_metric; - } /* for each other_route */ - - if (flood_mpr != NULL) { - netaddr_switch(&fn->node->flood_mpr, h1_super(flood_mpr)->addr); - DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], fn->node->flood_mpr)); - flood_mpr->mpr_neigh_flood++; - } else - fn->node->flood_mpr = netaddr_free(fn->node->flood_mpr); - - /* We found a valid route */ - if (node == fn->node) { - DEBUG("\t%s (%s) is a 1-hop neighbor", - netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name); - noop = false; - fn->node->next_addr = netaddr_use(fn->node->addr); - fn->node->path_metric = fn->node->link_metric; - fn->node->distance = 1; - fn->node->lost = 0; - - pop_other_route(fn->node, get_local_addr()); - simple_list_for_each_remove(&head, fn, prev); - - } else if (node != NULL) { - DEBUG("\t%s (%s) -> %s (%s) -> […] -> %s", - netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name, - netaddr_to_str_s(&nbuf[1], node->addr), node->name, - netaddr_to_str_s(&nbuf[2], node->next_addr)); - DEBUG("%d = %d", fn->node->distance, node->distance + 1); - - noop = false; - - /* update routing MPR information */ - if (node->type == NODE_TYPE_NHDP || fn->node->flood_mpr != NULL) { - struct nhdp_node* mpr = h1_deriv(get_node(node->next_addr)); - DEBUG("\tincrementing mpr_neigh_route for %s", h1_super(mpr)->name); - mpr->mpr_neigh_route++; - } - - fn->node->distance = node->distance + 1; - fn->node->path_metric = min_mtrc; - fn->node->next_addr = netaddr_use(node->next_addr); - - pop_other_route(fn->node, node->addr); - simple_list_for_each_remove(&head, fn, prev); - } else - DEBUG("\tdon't yet know how to route %s", netaddr_to_str_s(&nbuf[0], fn->node->addr)); - } - } - - _pending_head = head; +void fill_routing_table(void) +{ + struct free_node* head = _pending_head; + + if (_pending_head == NULL || !_update_pending) + return; + + _update_pending = false; + DEBUG("update routing table"); + + struct free_node* fn; + bool noop = false; /* when in an iteration there was nothing removed from free nodes */ + while (head && !noop) { + noop = true; /* if no nodes could be removed in an iteration, abort */ + struct free_node *prev; + char skipped; + simple_list_for_each_safe(head, fn, prev, skipped) { + DEBUG("trying to find a route to %s", fn->node->name); + /* chose shortest route from the set of availiable routes */ + metric_t min_mtrc = RFC5444_METRIC_INFINITE; + struct olsr_node* node = NULL; /* chosen route */ + struct nhdp_node* flood_mpr = NULL; + struct alt_route* route; /* current other_route */ + simple_list_for_each(fn->node->other_routes, route) { + DEBUG("\tconsidering %s (%d)", netaddr_to_string(&nbuf[0], route->last_addr), route->link_metric); + + /* the node is actually a neighbor of ours */ + if (netaddr_cmp(route->last_addr, get_local_addr()) == 0) { + DEBUG("\t\t1-hop neighbor"); + + /* don't use pending nodes */ + if (fn->node->pending) { + DEBUG("\t\tpending -> skipped"); + continue; + } + + if (route->link_metric > min_mtrc) + continue; + + min_mtrc = route->link_metric; + node = fn->node; + continue; + } + + /* see if we can find a better route */ + struct olsr_node* _tmp = get_node(route->last_addr); + if (_tmp == NULL || _tmp->addr == NULL || _tmp->next_addr == NULL) { + DEBUG("\t\tnot routable"); + continue; + } + + /* ignore pending nodes */ + if (_tmp->distance == 1 && _tmp->pending) { + DEBUG("\t\tpending -> skipped"); + continue; + } + + /* flooding MPR selection */ + if (_tmp->type == NODE_TYPE_NHDP && + (flood_mpr == NULL || flood_mpr->flood_neighbors < h1_deriv(_tmp)->flood_neighbors)) + flood_mpr = h1_deriv(_tmp); + + if (_tmp->path_metric + route->link_metric > min_mtrc) { + DEBUG("\t\tdoesn't offer a better route, %d + %d > %d", _tmp->path_metric, route->link_metric, min_mtrc); + continue; + } + + /* try to minimize MPR count */ + if (_tmp->type == NODE_TYPE_NHDP && min_mtrc == _tmp->path_metric + route->link_metric) { + DEBUG("\t\tequaly good route found, try to optimize MPR seleciton"); + struct nhdp_node* old_mpr = h1_deriv(node); + + /* a direct neighbor might be reached over an additional hop, the true MPR */ + if (netaddr_cmp(_tmp->next_addr, _tmp->addr) != 0) + old_mpr = h1_deriv(get_node(_tmp->next_addr)); + + /* use the neighbor with the most 2-hop neighbors */ + if (old_mpr->mpr_neigh_route >= h1_deriv(_tmp)->mpr_neigh_route + 1) { + DEBUG("\t\told MPR (%d) is better (new: %d)", old_mpr->mpr_neigh_route, h1_deriv(_tmp)->mpr_neigh_route); + continue; + } + } + + DEBUG("\t\t[possible candidate]"); + node = _tmp; + min_mtrc = _tmp->path_metric + route->link_metric; + } /* for each other_route */ + + if (flood_mpr != NULL) { + netaddr_switch(&fn->node->flood_mpr, h1_super(flood_mpr)->addr); + DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], fn->node->flood_mpr)); + flood_mpr->mpr_neigh_flood++; + } else + fn->node->flood_mpr = netaddr_free(fn->node->flood_mpr); + + /* We found a valid route */ + if (node == fn->node) { + DEBUG("\t%s (%s) is a 1-hop neighbor", + netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name); + noop = false; + fn->node->next_addr = netaddr_use(fn->node->addr); + fn->node->path_metric = fn->node->link_metric; + fn->node->distance = 1; + fn->node->lost = 0; + + pop_other_route(fn->node, get_local_addr()); + simple_list_for_each_remove(&head, fn, prev); + + } else if (node != NULL) { + DEBUG("\t%s (%s) -> %s (%s) -> […] -> %s", + netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name, + netaddr_to_str_s(&nbuf[1], node->addr), node->name, + netaddr_to_str_s(&nbuf[2], node->next_addr)); + DEBUG("%d = %d", fn->node->distance, node->distance + 1); + + noop = false; + + /* update routing MPR information */ + if (node->type == NODE_TYPE_NHDP || fn->node->flood_mpr != NULL) { + struct nhdp_node* mpr = h1_deriv(get_node(node->next_addr)); + DEBUG("\tincrementing mpr_neigh_route for %s", h1_super(mpr)->name); + mpr->mpr_neigh_route++; + } + + fn->node->distance = node->distance + 1; + fn->node->path_metric = min_mtrc; + fn->node->next_addr = netaddr_use(node->next_addr); + + pop_other_route(fn->node, node->addr); + simple_list_for_each_remove(&head, fn, prev); + } else + DEBUG("\tdon't yet know how to route %s", netaddr_to_str_s(&nbuf[0], fn->node->addr)); + } + } + + _pending_head = head; #ifdef DEBUG - while (head != NULL) { - DEBUG("Could not find next hop for %s (%s), should be %s (%d hops)", - netaddr_to_str_s(&nbuf[0], head->node->addr), head->node->name, - netaddr_to_str_s(&nbuf[1], head->node->last_addr), head->node->distance); + while (head != NULL) { + DEBUG("Could not find next hop for %s (%s), should be %s (%d hops)", + netaddr_to_str_s(&nbuf[0], head->node->addr), head->node->name, + netaddr_to_str_s(&nbuf[1], head->node->last_addr), head->node->distance); - head = head->next; - } + head = head->next; + } #endif } diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 1d00e7b216df..08da7fa63cb7 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -25,70 +25,78 @@ #include "node.h" #include "olsr_debug.h" -const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src) { - return src ? netaddr_to_string(dst, src) : NULL; +const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src) +{ + return src ? netaddr_to_string(dst, src) : NULL; } -struct netaddr* netaddr_dup(struct netaddr* addr) { - struct netaddr_rc* addr_new = calloc(1, sizeof(struct netaddr_rc)); +struct netaddr* netaddr_dup(struct netaddr* addr) +{ + struct netaddr_rc* addr_new = calloc(1, sizeof(struct netaddr_rc)); - if (addr_new == NULL) - return NULL; + if (addr_new == NULL) + return NULL; - addr_new->_refs = 1; - return memcpy(addr_new, addr, sizeof(struct netaddr)); + addr_new->_refs = 1; + return memcpy(addr_new, addr, sizeof(struct netaddr)); } -struct netaddr* netaddr_use(struct netaddr* addr) { - ((struct netaddr_rc*) addr)->_refs++; - return addr; +struct netaddr* netaddr_use(struct netaddr* addr) +{ + ((struct netaddr_rc*) addr)->_refs++; + return addr; } -struct netaddr* netaddr_reuse(struct netaddr* addr) { - if (netaddr_cmp(addr, get_local_addr()) == 0) - return netaddr_use(get_local_addr()); - - struct olsr_node* n = get_node(addr); - if (!n) { - DEBUG("Address %s not found, this shouldn't happen", netaddr_to_str_s(&nbuf[0], addr)); - return netaddr_dup(addr); - } - return netaddr_use(n->addr); +struct netaddr* netaddr_reuse(struct netaddr* addr) +{ + if (netaddr_cmp(addr, get_local_addr()) == 0) + return netaddr_use(get_local_addr()); + + struct olsr_node* n = get_node(addr); + if (!n) { + DEBUG("Address %s not found, this shouldn't happen", netaddr_to_str_s(&nbuf[0], addr)); + return netaddr_dup(addr); + } + return netaddr_use(n->addr); } -struct netaddr* netaddr_free(struct netaddr* addr) { - struct netaddr_rc* addr_rc = (struct netaddr_rc*) addr; +struct netaddr* netaddr_free(struct netaddr* addr) +{ + struct netaddr_rc* addr_rc = (struct netaddr_rc*) addr; - if (addr) - DEBUG("netaddr_free(%s) - %d refs", netaddr_to_str_s(&nbuf[0], addr), addr_rc->_refs); + if (addr) + DEBUG("netaddr_free(%s) - %d refs", netaddr_to_str_s(&nbuf[0], addr), addr_rc->_refs); - if (addr != NULL && --addr_rc->_refs == 0) - free(addr_rc); + if (addr != NULL && --addr_rc->_refs == 0) + free(addr_rc); - return NULL; + return NULL; } -void netaddr_switch(struct netaddr** old_addr, struct netaddr* new_addr) { - netaddr_free(*old_addr); - *old_addr = netaddr_reuse(new_addr); +void netaddr_switch(struct netaddr** old_addr, struct netaddr* new_addr) +{ + netaddr_free(*old_addr); + *old_addr = netaddr_reuse(new_addr); } -time_t time_now(void) { +time_t time_now(void) +{ #ifdef RIOT - struct timeval _tv; - return rtc_time(&_tv); + struct timeval _tv; + return rtc_time(&_tv); #else - return time(0); + return time(0); #endif } -void sleep_s(int secs) { +void sleep_s(int secs) +{ #ifdef RIOT - vtimer_usleep(secs * 1000000); + vtimer_usleep(secs * 1000000); #else - // process wakes up when a package arrives - // go back to sleep to prevent flooding - int remaining_sleep = secs; - while ((remaining_sleep = sleep(remaining_sleep))); + // process wakes up when a package arrives + // go back to sleep to prevent flooding + int remaining_sleep = secs; + while ((remaining_sleep = sleep(remaining_sleep))); #endif } diff --git a/sys/net/routing/olsr2/util.h b/sys/net/routing/olsr2/util.h index e238335a2c2d..bacf8e4a96c6 100644 --- a/sys/net/routing/olsr2/util.h +++ b/sys/net/routing/olsr2/util.h @@ -4,8 +4,8 @@ #include "common/netaddr.h" struct netaddr_rc { - struct netaddr super; - uint8_t _refs; + struct netaddr super; + uint8_t _refs; }; const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src); diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index ed7d10d0dfe2..a93474941770 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -49,188 +49,195 @@ static void _cb_add_olsr_addresses(struct rfc5444_writer *wr); /* HELLO message */ static struct rfc5444_writer_content_provider _nhdp_message_content_provider = { - .msg_type = RFC5444_MSGTYPE_HELLO, - .addMessageTLVs = _cb_add_nhdp_message_TLVs, - .addAddresses = _cb_add_nhdp_addresses, + .msg_type = RFC5444_MSGTYPE_HELLO, + .addMessageTLVs = _cb_add_nhdp_message_TLVs, + .addAddresses = _cb_add_nhdp_addresses, }; static struct rfc5444_writer_tlvtype _nhdp_addrtlvs[] = { - [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, - [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, - [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, + [IDX_ADDRTLV_MPR] = { .type = RFC5444_ADDRTLV_MPR }, + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME - [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif }; /* TC message */ static struct rfc5444_writer_content_provider _olsr_message_content_provider = { - .msg_type = RFC5444_MSGTYPE_TC, - .addMessageTLVs = _cb_add_olsr_message_TLVs, - .addAddresses = _cb_add_olsr_addresses, + .msg_type = RFC5444_MSGTYPE_TC, + .addMessageTLVs = _cb_add_olsr_message_TLVs, + .addAddresses = _cb_add_olsr_addresses, }; static struct rfc5444_writer_tlvtype _olsr_addrtlvs[] = { - [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, - [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, + [IDX_ADDRTLV_LINK_STATUS] = { .type = RFC5444_ADDRTLV_LINK_STATUS }, + [IDX_ADDRTLV_METRIC] = { .type = RFC5444_ADDRTLV_LINK_METRIC}, #ifdef ENABLE_NAME - [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, + [IDX_ADDRTLV_NODE_NAME] = { .type = RFC5444_TLV_NODE_NAME }, #endif }; /* add TLVs to HELLO message */ static void -_cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr) { - uint8_t time_encoded = rfc5444_timetlv_encode(OLSR2_HELLO_REFRESH_INTERVAL_SECONDS); - rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); +_cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr) +{ + uint8_t time_encoded = rfc5444_timetlv_encode(OLSR2_HELLO_REFRESH_INTERVAL_SECONDS); + rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); #ifdef ENABLE_NAME - rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); + rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); #endif } /* add addresses to HELLO message */ static void -_cb_add_nhdp_addresses(struct rfc5444_writer *wr) { - struct olsr_node* node, *safe; - int value; - uint8_t mpr; - send_tc_messages = false; - - /* add all neighbors */ - avl_for_each_element_safe(get_olsr_head(), node, node, safe) { - - /* if the node was just removed entirely from the database, continue */ - if (remove_expired(node)) - continue; - - if (node->type != NODE_TYPE_NHDP && !node->lost) - continue; - - if (node->pending && !node->lost) - continue; - - if (!node->pending && h1_deriv(node)->mpr_slctr_route) - send_tc_messages = true; - - struct rfc5444_writer_address *address = rfc5444_writer_add_address(wr, - _nhdp_message_content_provider.creator, node->addr, false); - - mpr = 0; - if (h1_deriv(node)->mpr_neigh_flood > 0) - mpr |= RFC5444_MPR_FLOODING; - - if (h1_deriv(node)->mpr_neigh_route > 0) - mpr |= RFC5444_MPR_ROUTING; - - if (mpr > 0) - rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_MPR], - &mpr, sizeof mpr, false); - - metric_t link_metric = get_link_metric(node, get_local_addr()); - if (link_metric > RFC5444_METRIC_MIN) { - uint16_t mtrc = rfc5444_metric_encode(link_metric); - rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], - &mtrc, sizeof mtrc, false); - } - - if (node->lost) { - DEBUG("LINKSTATUS: neighbor %s lost (HELLO) [%d]", node->name, node->lost); - value = RFC5444_LINKSTATUS_LOST; - rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_LINK_STATUS], - &value, sizeof value, false); - - if (!send_tc_messages) - node->lost--; - } +_cb_add_nhdp_addresses(struct rfc5444_writer *wr) +{ + struct olsr_node* node, *safe; + int value; + uint8_t mpr; + send_tc_messages = false; + + /* add all neighbors */ + avl_for_each_element_safe(get_olsr_head(), node, node, safe) { + + /* if the node was just removed entirely from the database, continue */ + if (remove_expired(node)) + continue; + + if (node->type != NODE_TYPE_NHDP && !node->lost) + continue; + + if (node->pending && !node->lost) + continue; + + if (!node->pending && h1_deriv(node)->mpr_slctr_route) + send_tc_messages = true; + + struct rfc5444_writer_address *address = rfc5444_writer_add_address(wr, + _nhdp_message_content_provider.creator, node->addr, false); + + mpr = 0; + if (h1_deriv(node)->mpr_neigh_flood > 0) + mpr |= RFC5444_MPR_FLOODING; + + if (h1_deriv(node)->mpr_neigh_route > 0) + mpr |= RFC5444_MPR_ROUTING; + + if (mpr > 0) + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_MPR], + &mpr, sizeof mpr, false); + + metric_t link_metric = get_link_metric(node, get_local_addr()); + if (link_metric > RFC5444_METRIC_MIN) { + uint16_t mtrc = rfc5444_metric_encode(link_metric); + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], + &mtrc, sizeof mtrc, false); + } + + if (node->lost) { + DEBUG("LINKSTATUS: neighbor %s lost (HELLO) [%d]", node->name, node->lost); + value = RFC5444_LINKSTATUS_LOST; + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_LINK_STATUS], + &value, sizeof value, false); + + if (!send_tc_messages) + node->lost--; + } #ifdef ENABLE_NAME - if (node->name) - rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_NODE_NAME], - node->name, strlen(node->name) + 1, false); + if (node->name) + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_NODE_NAME], + node->name, strlen(node->name) + 1, false); #endif - } + } } /* add TLVs to TC message */ static void -_cb_add_olsr_message_TLVs(struct rfc5444_writer *wr) { - uint8_t time_encoded = rfc5444_timetlv_encode(OLSR2_TC_REFRESH_INTERVAL_SECONDS); - rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); +_cb_add_olsr_message_TLVs(struct rfc5444_writer *wr) +{ + uint8_t time_encoded = rfc5444_timetlv_encode(OLSR2_TC_REFRESH_INTERVAL_SECONDS); + rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); #ifdef ENABLE_NAME - rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); + rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); #endif } /* add addresses to TC message */ static void -_cb_add_olsr_addresses(struct rfc5444_writer *wr) { - struct olsr_node* node; - int value; +_cb_add_olsr_addresses(struct rfc5444_writer *wr) +{ + struct olsr_node* node; + int value; - /* add all neighbors */ - avl_for_each_element(get_olsr_head(), node, node) { - if (h1_deriv(node) == NULL) - continue; + /* add all neighbors */ + avl_for_each_element(get_olsr_head(), node, node) { + if (h1_deriv(node) == NULL) + continue; - if (!h1_deriv(node)->mpr_slctr_route) - continue; + if (!h1_deriv(node)->mpr_slctr_route) + continue; - /* don't advertise neighbors routed over another hop */ - if (node->distance != 1 && !node->lost) - continue; + /* don't advertise neighbors routed over another hop */ + if (node->distance != 1 && !node->lost) + continue; - if (node->pending && !node->lost) - continue; + if (node->pending && !node->lost) + continue; - struct rfc5444_writer_address *address __attribute__((unused)); - address = rfc5444_writer_add_address(wr, _olsr_message_content_provider.creator, node->addr, false); + struct rfc5444_writer_address *address __attribute__((unused)); + address = rfc5444_writer_add_address(wr, _olsr_message_content_provider.creator, node->addr, false); - if (node->link_metric > RFC5444_METRIC_MIN) { - uint16_t mtrc = rfc5444_metric_encode(node->link_metric); - rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], - &mtrc, sizeof mtrc, false); - } + if (node->link_metric > RFC5444_METRIC_MIN) { + uint16_t mtrc = rfc5444_metric_encode(node->link_metric); + rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], + &mtrc, sizeof mtrc, false); + } - if (node->lost) { - DEBUG("LINKSTATUS: neighbor %s lost (TC) [%d]", node->name, node->lost); - value = RFC5444_LINKSTATUS_LOST; - rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_LINK_STATUS], - &value, sizeof value, false); + if (node->lost) { + DEBUG("LINKSTATUS: neighbor %s lost (TC) [%d]", node->name, node->lost); + value = RFC5444_LINKSTATUS_LOST; + rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_LINK_STATUS], + &value, sizeof value, false); - node->lost--; - } + node->lost--; + } #ifdef ENABLE_NAME - if (node->name) - rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_NODE_NAME], - node->name, strlen(node->name) + 1, false); + if (node->name) + rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_NODE_NAME], + node->name, strlen(node->name) + 1, false); #endif - } + } } /* header for HELLO messages */ static void -_cb_add_hello_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) { - /* no originator, no hopcount, no hoplimit, no sequence number */ - rfc5444_writer_set_msg_header(wr, message, false, false, false, false); +_cb_add_hello_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) +{ + /* no originator, no hopcount, no hoplimit, no sequence number */ + rfc5444_writer_set_msg_header(wr, message, false, false, false, false); } /* header for TC messages */ static void -_cb_add_tc_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) { - /* originator, hopcount, hoplimit, sequence number */ - rfc5444_writer_set_msg_header(wr, message, true, true, true, true); - rfc5444_writer_set_msg_seqno(wr, message, seq_no++); - rfc5444_writer_set_msg_originator(wr, message, netaddr_get_binptr(get_local_addr())); - - message->hoplimit = OLSR2_TC_HOP_LIMIT; +_cb_add_tc_message_header(struct rfc5444_writer *wr, struct rfc5444_writer_message *message) +{ + /* originator, hopcount, hoplimit, sequence number */ + rfc5444_writer_set_msg_header(wr, message, true, true, true, true); + rfc5444_writer_set_msg_seqno(wr, message, seq_no++); + rfc5444_writer_set_msg_originator(wr, message, netaddr_get_binptr(get_local_addr())); + + message->hoplimit = OLSR2_TC_HOP_LIMIT; } /* reader has already decided whether to forward or not, just say ok to that */ bool -olsr_message_forwarding_selector(struct rfc5444_writer_target *rfc5444_target __attribute__((unused))) { - return true; +olsr_message_forwarding_selector(struct rfc5444_writer_target *rfc5444_target __attribute__((unused))) +{ + return true; } /** @@ -238,61 +245,65 @@ olsr_message_forwarding_selector(struct rfc5444_writer_target *rfc5444_target __ * @param ptr pointer to "send_packet" function */ void -writer_init(write_packet_func_ptr ptr) { - struct rfc5444_writer_message *_hello_msg; - struct rfc5444_writer_message *_tc_msg; +writer_init(write_packet_func_ptr ptr) +{ + struct rfc5444_writer_message *_hello_msg; + struct rfc5444_writer_message *_tc_msg; - writer.msg_buffer = msg_buffer; - writer.msg_size = sizeof(msg_buffer); - writer.addrtlv_buffer = msg_addrtlvs; - writer.addrtlv_size = sizeof(msg_addrtlvs); + writer.msg_buffer = msg_buffer; + writer.msg_size = sizeof(msg_buffer); + writer.addrtlv_buffer = msg_addrtlvs; + writer.addrtlv_size = sizeof(msg_addrtlvs); - interface.packet_buffer = packet_buffer; - interface.packet_size = sizeof(packet_buffer); - interface.sendPacket = ptr; + interface.packet_buffer = packet_buffer; + interface.packet_size = sizeof(packet_buffer); + interface.sendPacket = ptr; - /* initialize writer */ - rfc5444_writer_init(&writer); + /* initialize writer */ + rfc5444_writer_init(&writer); - /* register a target (for sending messages to) in writer */ - rfc5444_writer_register_target(&writer, &interface); + /* register a target (for sending messages to) in writer */ + rfc5444_writer_register_target(&writer, &interface); - /* register a message content provider */ - rfc5444_writer_register_msgcontentprovider(&writer, &_nhdp_message_content_provider, _nhdp_addrtlvs, ARRAYSIZE(_nhdp_addrtlvs)); - rfc5444_writer_register_msgcontentprovider(&writer, &_olsr_message_content_provider, _olsr_addrtlvs, ARRAYSIZE(_olsr_addrtlvs)); + /* register a message content provider */ + rfc5444_writer_register_msgcontentprovider(&writer, &_nhdp_message_content_provider, _nhdp_addrtlvs, ARRAYSIZE(_nhdp_addrtlvs)); + rfc5444_writer_register_msgcontentprovider(&writer, &_olsr_message_content_provider, _olsr_addrtlvs, ARRAYSIZE(_olsr_addrtlvs)); - /* register message type 1 with 16 byte addresses */ - _hello_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_HELLO, false, RFC5444_MAX_ADDRLEN); - _tc_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_TC, false, RFC5444_MAX_ADDRLEN); + /* register message type 1 with 16 byte addresses */ + _hello_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_HELLO, false, RFC5444_MAX_ADDRLEN); + _tc_msg = rfc5444_writer_register_message(&writer, RFC5444_MSGTYPE_TC, false, RFC5444_MAX_ADDRLEN); - _hello_msg->addMessageHeader = _cb_add_hello_message_header; - _tc_msg->addMessageHeader = _cb_add_tc_message_header; - _tc_msg->forward_target_selector = olsr_message_forwarding_selector; + _hello_msg->addMessageHeader = _cb_add_hello_message_header; + _tc_msg->addMessageHeader = _cb_add_tc_message_header; + _tc_msg->forward_target_selector = olsr_message_forwarding_selector; } -void writer_send_hello(void) { - DEBUG("[HELLO]"); +void writer_send_hello(void) +{ + DEBUG("[HELLO]"); - /* send message */ - rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_HELLO); - rfc5444_writer_flush(&writer, &interface, false); + /* send message */ + rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_HELLO); + rfc5444_writer_flush(&writer, &interface, false); } -void writer_send_tc(void) { - if (!send_tc_messages) - return; +void writer_send_tc(void) +{ + if (!send_tc_messages) + return; - DEBUG("[TC]"); + DEBUG("[TC]"); - /* send message */ - rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_TC); - rfc5444_writer_flush(&writer, &interface, false); + /* send message */ + rfc5444_writer_create_message_alltarget(&writer, RFC5444_MSGTYPE_TC); + rfc5444_writer_flush(&writer, &interface, false); } /** * Cleanup RFC5444 writer */ void -writer_cleanup(void) { - rfc5444_writer_cleanup(&writer); +writer_cleanup(void) +{ + rfc5444_writer_cleanup(&writer); } diff --git a/sys/net/routing/olsr2/writer.h b/sys/net/routing/olsr2/writer.h index 08ccd7fdea69..6d9314b6b9b5 100644 --- a/sys/net/routing/olsr2/writer.h +++ b/sys/net/routing/olsr2/writer.h @@ -5,7 +5,7 @@ #include "rfc5444/rfc5444_writer.h" typedef void (*write_packet_func_ptr)( - struct rfc5444_writer *wr, struct rfc5444_writer_target *iface, void *buffer, size_t length); + struct rfc5444_writer *wr, struct rfc5444_writer_target *iface, void *buffer, size_t length); /* these are also used in reader.c, just acces them directly instead of passing a pointer */ struct rfc5444_writer writer; From 8d59a5f52ffc2f3a4653eb3899accb09961634b7 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 1 Aug 2014 15:50:51 +0200 Subject: [PATCH 19/48] define SECOND --- sys/net/routing/olsr2/constants.h | 7 ++++--- sys/net/routing/olsr2/util.c | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index 30019841a138..3da27b4cbc3e 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -12,11 +12,12 @@ #define OLSR2_TC_HOP_LIMIT 16 #define OLSR2_HYST_SCALING 0.4 -#define OLSR2_HYST_LOW 0.3 -#define OLSR2_HYST_HIGH 0.8 +#define OLSR2_HYST_LOW 0.3 +#define OLSR2_HYST_HIGH 0.8 /* in µs */ -#define OLSR2_MAX_JITTER_US 1000000 +#define SECOND (1000 * 1000) +#define OLSR2_MAX_JITTER_US SECOND #define OLSR2_FLOODING_MPR_SELECTOR 1 #define OLSR2_ROUTING_MPR_SELECTOR 2 diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 08da7fa63cb7..355fcbde1aab 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -21,6 +21,7 @@ #include #endif +#include "constants.h" #include "util.h" #include "node.h" #include "olsr_debug.h" @@ -92,7 +93,7 @@ time_t time_now(void) void sleep_s(int secs) { #ifdef RIOT - vtimer_usleep(secs * 1000000); + vtimer_usleep(secs * SECOND); #else // process wakes up when a package arrives // go back to sleep to prevent flooding From 7d2fe2f2d6f44222a0174083bd830228d69c9bd3 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 3 Aug 2014 22:08:28 +0200 Subject: [PATCH 20/48] astyle --options=../../../../.astylerc * --- sys/net/routing/olsr2/Makefile | 2 +- sys/net/routing/olsr2/list.c | 72 +++++++++------ sys/net/routing/olsr2/list.h | 14 +-- sys/net/routing/olsr2/nhdp.c | 30 +++--- sys/net/routing/olsr2/nhdp.h | 2 +- sys/net/routing/olsr2/node.c | 91 +++++++++++------- sys/net/routing/olsr2/node.h | 54 +++++------ sys/net/routing/olsr2/olsr.c | 144 +++++++++++++++++++---------- sys/net/routing/olsr2/olsr.h | 8 +- sys/net/routing/olsr2/olsr_debug.h | 5 +- sys/net/routing/olsr2/olsr_init.c | 44 +++++---- sys/net/routing/olsr2/reader.c | 138 ++++++++++++++++----------- sys/net/routing/olsr2/reader.h | 2 +- sys/net/routing/olsr2/routing.c | 63 ++++++++----- sys/net/routing/olsr2/routing.h | 4 +- sys/net/routing/olsr2/util.c | 36 +++++--- sys/net/routing/olsr2/util.h | 12 +-- sys/net/routing/olsr2/writer.c | 48 +++++++--- 18 files changed, 469 insertions(+), 300 deletions(-) diff --git a/sys/net/routing/olsr2/Makefile b/sys/net/routing/olsr2/Makefile index 48422e909a47..1ead3177295b 100644 --- a/sys/net/routing/olsr2/Makefile +++ b/sys/net/routing/olsr2/Makefile @@ -1 +1 @@ -include $(RIOTBASE)/Makefile.base +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/routing/olsr2/list.c b/sys/net/routing/olsr2/list.c index 86743f70f7a7..ec58f401b5bb 100644 --- a/sys/net/routing/olsr2/list.c +++ b/sys/net/routing/olsr2/list.c @@ -17,16 +17,17 @@ #include "list.h" struct simple_list_elem { - struct simple_list_elem* next; + struct simple_list_elem *next; }; -void* __simple_list_add_tail(struct simple_list_elem** head, void* mem) +void *__simple_list_add_tail(struct simple_list_elem **head, void *mem) { - struct simple_list_elem* _head = *head; + struct simple_list_elem *_head = *head; /* check out-of-memory condition */ - if (mem == NULL) + if (mem == NULL) { return NULL; + } if (!_head) { *head = mem; @@ -41,13 +42,14 @@ void* __simple_list_add_tail(struct simple_list_elem** head, void* mem) return _head; } -void* __simple_list_add_head(struct simple_list_elem** head, void* mem) +void *__simple_list_add_head(struct simple_list_elem **head, void *mem) { - struct simple_list_elem* _head = *head; + struct simple_list_elem *_head = *head; /* check out-of-memory condition */ - if (mem == NULL) + if (mem == NULL) { return NULL; + } *head = mem; (*head)->next = _head; @@ -55,22 +57,24 @@ void* __simple_list_add_head(struct simple_list_elem** head, void* mem) return *head; } -void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset) +void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset) { - struct simple_list_elem* _head = *head; - struct simple_list_elem* prev = 0; + struct simple_list_elem *_head = *head; + struct simple_list_elem *prev = 0; /* check out-of-memory condition */ - if (mem == NULL) + if (mem == NULL) { return NULL; + } if (!_head) { *head = mem; return *head; } - while(_head) { - int* buff = (void*) _head + offset; + while (_head) { + int *buff = (void *) _head + offset; + if (*buff > needle) { if (prev) { prev->next = mem; @@ -83,6 +87,7 @@ void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int ne *head = prev; return prev; } + prev = _head; _head = _head->next; } @@ -91,28 +96,33 @@ void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int ne return _head; } -void* __simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size) +void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size) { while (head) { - void** buff = (void*) head + offset; + void **buff = (void *) head + offset; - if (size == 0 && *buff == needle) + if (size == 0 && *buff == needle) { return head; - if (size > 0 && memcmp(*buff, needle, size) == 0) + } + + if (size > 0 && memcmp(*buff, needle, size) == 0) { return head; + } + head = head->next; } return 0; } -void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)) +void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)) { while (head) { - void** buff = (void*) head + offset; + void **buff = (void *) head + offset; - if (compare(*buff, needle) == 0) + if (compare(*buff, needle) == 0) { return head; + } head = head->next; } @@ -120,10 +130,10 @@ void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int of return 0; } -void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep) +void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep) { - struct simple_list_elem* _head = *head; - struct simple_list_elem* prev = 0; + struct simple_list_elem *_head = *head; + struct simple_list_elem *prev = 0; while (_head && _head != node) { prev = _head; @@ -131,23 +141,27 @@ void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_el } /* not found */ - if (_head != node) + if (_head != node) { return NULL; + } /* remove head */ - if (!prev) + if (!prev) { *head = _head->next; - else + } + else { prev->next = node->next; + } - if (keep) + if (keep) { return node; + } free(node); - return (void*) 1; + return (void *) 1; } -void __simple_list_clear(struct simple_list_elem** head) +void __simple_list_clear(struct simple_list_elem **head) { struct simple_list_elem *tmp, *_head = *head; diff --git a/sys/net/routing/olsr2/list.h b/sys/net/routing/olsr2/list.h index 2e4dcf486738..48fc5366688f 100644 --- a/sys/net/routing/olsr2/list.h +++ b/sys/net/routing/olsr2/list.h @@ -192,12 +192,12 @@ struct simple_list_elem; (node) = (prev) ? (prev) : *(head); \ } while (0) -void* __simple_list_add_head(struct simple_list_elem** head, void* mem); -void* __simple_list_add_tail(struct simple_list_elem** head, void* mem); -void* __simple_list_add_before(struct simple_list_elem** head, void* mem, int needle, int offset); -void* __simple_list_find(struct simple_list_elem* head, void* needle, int offset, size_t size); -void* __simple_list_find_cmp(struct simple_list_elem* head, void* needle, int offset, int compare(void*, void*)); -void* __simple_list_remove(struct simple_list_elem** head, struct simple_list_elem* node, int keep); -void __simple_list_clear(struct simple_list_elem** head); +void *__simple_list_add_head(struct simple_list_elem **head, void *mem); +void *__simple_list_add_tail(struct simple_list_elem **head, void *mem); +void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset); +void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size); +void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)); +void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep); +void __simple_list_clear(struct simple_list_elem **head); #endif /* SIMPLE_LIST_H_ */ diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 27b4bb173a38..c15ba9be45b6 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -22,12 +22,13 @@ #include "common/avl.h" -static struct olsr_node* _node_replace(struct olsr_node* old_n) +static struct olsr_node *_node_replace(struct olsr_node *old_n) { - struct olsr_node* new_n = calloc(1, sizeof (struct nhdp_node)); + struct olsr_node *new_n = calloc(1, sizeof(struct nhdp_node)); - if (new_n == NULL) + if (new_n == NULL) { return old_n; + } /* remove things that held a pointer to this */ avl_remove(get_olsr_head(), &old_n->node); @@ -42,8 +43,9 @@ static struct olsr_node* _node_replace(struct olsr_node* old_n) free(old_n); - if (_free_node) + if (_free_node) { add_free_node(new_n); + } new_n->pending = 1; h1_deriv(new_n)->link_quality = OLSR2_HYST_SCALING; @@ -51,16 +53,17 @@ static struct olsr_node* _node_replace(struct olsr_node* old_n) return new_n; } -struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name) +struct olsr_node *olsr2_add_neighbor(struct netaddr *addr, metric_t metric, uint8_t vtime, char *name) { - struct olsr_node* n = get_node(addr); + struct olsr_node *n = get_node(addr); if (n == NULL) { DEBUG("\tadding new neighbor: %s", netaddr_to_str_s(&nbuf[0], addr)); n = calloc(1, sizeof(struct nhdp_node)); - if (n == NULL) + if (n == NULL) { return NULL; + } n->addr = netaddr_dup(addr); @@ -75,21 +78,26 @@ struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint h1_deriv(n)->link_quality = OLSR2_HYST_SCALING; n->pending = 1; #ifdef ENABLE_NAME - if (name != NULL) + + if (name != NULL) { n->name = strdup(name); + } + #endif n->node.key = n->addr; avl_insert(get_olsr_head(), &n->node); - } else if (n->type != NODE_TYPE_NHDP) { + } + else if (n->type != NODE_TYPE_NHDP) { DEBUG("\tconverting olsr node %s to nhdp node", netaddr_to_str_s(&nbuf[0], n->addr)); n = _node_replace(n); } /* add_other_route would otherwise not update expires */ - if (n->next_addr == NULL) + if (n->next_addr == NULL) { n->expires = time_now() + vtime; + } add_other_route(n, get_local_addr(), 1, metric, vtime); @@ -99,7 +107,7 @@ struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint #ifdef ENABLE_DEBUG_OLSR void print_neighbors(void) { - struct olsr_node* node; + struct olsr_node *node; DEBUG("1-hop neighbors:"); avl_for_each_element(get_olsr_head(), node, node) { diff --git a/sys/net/routing/olsr2/nhdp.h b/sys/net/routing/olsr2/nhdp.h index 47afa45f8b70..70258975dc82 100644 --- a/sys/net/routing/olsr2/nhdp.h +++ b/sys/net/routing/olsr2/nhdp.h @@ -6,7 +6,7 @@ #include "node.h" -struct olsr_node* olsr2_add_neighbor(struct netaddr* addr, metric_t metric, uint8_t vtime, char* name); +struct olsr_node *olsr2_add_neighbor(struct netaddr *addr, metric_t metric, uint8_t vtime, char *name); void print_neighbors(void); diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index af68ea288c7b..713da0c80691 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -24,34 +24,39 @@ static struct netaddr_rc local_addr; static struct avl_tree olsr_head; #ifdef ENABLE_NAME -char* local_name; +char *local_name; #endif -static void _decrease_mpr_neigh(struct olsr_node* node) +static void _decrease_mpr_neigh(struct olsr_node *node) { TRACE_FUN("%s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); /* only consider 2-hop nieghbors (only 2-hop neighbors have flood_mpr set) */ - if (node->flood_mpr == NULL) + if (node->flood_mpr == NULL) { return; + } /* update routing MPR information */ - struct nhdp_node* n1 = h1_deriv(get_node(node->next_addr)); - if (n1 != NULL && n1->mpr_neigh_route > 0) + struct nhdp_node *n1 = h1_deriv(get_node(node->next_addr)); + + if (n1 != NULL && n1->mpr_neigh_route > 0) { n1->mpr_neigh_route--; + } /* update flooding MPR information */ - struct nhdp_node* n1_f = h1_deriv(get_node(node->flood_mpr)); - if (n1_f != NULL && n1_f->mpr_neigh_flood > 0) + struct nhdp_node *n1_f = h1_deriv(get_node(node->flood_mpr)); + + if (n1_f != NULL && n1_f->mpr_neigh_flood > 0) { n1_f->mpr_neigh_flood--; + } } -static int _addr_cmp(const void* a, const void* b) +static int _addr_cmp(const void *a, const void *b) { return memcmp(a, b, NETADDR_MAX_LENGTH); } -int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b) +int olsr_node_cmp(struct olsr_node *a, struct olsr_node *b) { return netaddr_cmp(a->addr, b->addr); } @@ -62,38 +67,43 @@ void node_init(void) avl_init(get_olsr_head(), _addr_cmp, false); } -struct netaddr* get_local_addr(void) +struct netaddr *get_local_addr(void) { - return (struct netaddr*) &local_addr; + return (struct netaddr *) &local_addr; } -struct avl_tree* get_olsr_head(void) +struct avl_tree *get_olsr_head(void) { return &olsr_head; } -struct olsr_node* get_node(struct netaddr* addr) +struct olsr_node *get_node(struct netaddr *addr) { struct olsr_node *n; // for typeof - if (addr == NULL) + + if (addr == NULL) { return NULL; + } + return avl_find_element(get_olsr_head(), addr, n, node); } -metric_t get_link_metric(struct olsr_node* node, struct netaddr* last_addr) +metric_t get_link_metric(struct olsr_node *node, struct netaddr *last_addr) { - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { return node->link_metric; + } - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + struct alt_route *route = simple_list_find_memcmp(node->other_routes, last_addr); - if (route == NULL) + if (route == NULL) { return RFC5444_METRIC_INFINITE; + } return route->link_metric; } -void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t distance, metric_t metric, uint8_t vtime) +void add_other_route(struct olsr_node *node, struct netaddr *last_addr, uint8_t distance, metric_t metric, uint8_t vtime) { /* make sure the route is not already the default route */ if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { @@ -102,11 +112,13 @@ void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t node->path_metric -= node->link_metric - metric; node->link_metric = metric; } + node->expires = time_now() + vtime; return; } - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + struct alt_route *route = simple_list_find_memcmp(node->other_routes, last_addr); + if (route != NULL) { route->expires = time_now() + vtime; route->link_metric = metric; @@ -126,21 +138,25 @@ void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t /* if we add a route for the first time, increment flood_neighbors */ if (distance == 2 && node->type != NODE_TYPE_NHDP) { - struct nhdp_node* n1 = h1_deriv(get_node(last_addr)); - if (n1 != NULL) + struct nhdp_node *n1 = h1_deriv(get_node(last_addr)); + + if (n1 != NULL) { n1->flood_neighbors++; + } } } -void remove_default_node(struct olsr_node* node) +void remove_default_node(struct olsr_node *node) { if (node->last_addr) { _decrease_mpr_neigh(node); - struct nhdp_node* mpr = h1_deriv(get_node(node->last_addr)); - if (mpr != NULL) + struct nhdp_node *mpr = h1_deriv(get_node(node->last_addr)); + + if (mpr != NULL) { mpr->flood_neighbors--; + } node->last_addr = netaddr_free(node->last_addr); } @@ -151,15 +167,16 @@ void remove_default_node(struct olsr_node* node) /* * moves the default route of node to other_routes */ -void push_default_route(struct olsr_node* node) +void push_default_route(struct olsr_node *node) { - struct netaddr* last_addr = node->last_addr; + struct netaddr *last_addr = node->last_addr; - if (node->last_addr == NULL) + if (node->last_addr == NULL) { return; + } _decrease_mpr_neigh(node); - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + struct alt_route *route = simple_list_find_memcmp(node->other_routes, last_addr); /* don't add route if it already exists - this should never happen, right? */ if (route != NULL) { @@ -180,13 +197,14 @@ void push_default_route(struct olsr_node* node) node->last_addr = NULL; } -void pop_other_route(struct olsr_node* node, struct netaddr* last_addr) +void pop_other_route(struct olsr_node *node, struct netaddr *last_addr) { char skipped; struct alt_route *route, *prev; simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (netaddr_cmp(route->last_addr, last_addr)) + if (netaddr_cmp(route->last_addr, last_addr)) { continue; + } node->last_addr = route->last_addr; node->expires = route->expires; @@ -196,7 +214,7 @@ void pop_other_route(struct olsr_node* node, struct netaddr* last_addr) } } -void remove_other_route(struct olsr_node* node, struct netaddr* last_addr) +void remove_other_route(struct olsr_node *node, struct netaddr *last_addr) { TRACE_FUN("%s (%s), %s", netaddr_to_str_s(&nbuf[0], node->addr), node->name, netaddr_to_str_s(&nbuf[1], last_addr)); @@ -204,12 +222,15 @@ void remove_other_route(struct olsr_node* node, struct netaddr* last_addr) char skipped; struct alt_route *route, *prev; simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (netaddr_cmp(route->last_addr, last_addr)) + if (netaddr_cmp(route->last_addr, last_addr)) { continue; + } - struct nhdp_node* mpr = h1_deriv(get_node(route->last_addr)); - if (mpr != NULL) + struct nhdp_node *mpr = h1_deriv(get_node(route->last_addr)); + + if (mpr != NULL) { mpr->flood_neighbors--; + } netaddr_free(route->last_addr); simple_list_for_each_remove(&node->other_routes, route, prev); diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index 5f1a08ef3bda..f6d4a7c292ae 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -8,7 +8,7 @@ #include "olsr_debug.h" #ifdef ENABLE_NAME -extern char* local_name; +extern char *local_name; #endif /* if a connection is lost, the loss will be reported LOST_ITER_MAX times in HELLO and TC messages. */ @@ -23,9 +23,9 @@ typedef uint32_t metric_t; /* simple list to store alternative routes */ struct alt_route { - struct alt_route* next; + struct alt_route *next; - struct netaddr* last_addr; + struct netaddr *last_addr; metric_t link_metric; time_t expires; }; @@ -33,24 +33,24 @@ struct alt_route { struct olsr_node { struct avl_node node; /* for routing table Information Base */ - struct netaddr* addr; /* node address */ - struct netaddr* next_addr; /* neighbor addr to send packets to for this node*/ - struct netaddr* last_addr; /* node that announced this node */ - struct alt_route* other_routes; /* other possible last_addrs */ + struct netaddr *addr; /* node address */ + struct netaddr *next_addr; /* neighbor addr to send packets to for this node*/ + struct netaddr *last_addr; /* node that announced this node */ + struct alt_route *other_routes; /* other possible last_addrs */ time_t expires; /* time when this tuple is invalid */ uint16_t seq_no; /* last seq_no from last_addr */ uint8_t distance; /* hops between us and the node */ metric_t link_metric; metric_t path_metric; - struct netaddr* flood_mpr; /* flooding MPR to broadcast to this node (used for couting mpr_neigh_flood), 2-hop only */ + struct netaddr *flood_mpr; /* flooding MPR to broadcast to this node (used for couting mpr_neigh_flood), 2-hop only */ uint8_t type : 1; /* node type */ uint8_t pending : 1; /* whether the link can already be used - only 1-hop */ uint8_t lost : 4; /* [4 bit] if set, the node will be annouced as lost - only 1-hop */ #ifdef ENABLE_NAME - char* name; /* node name from graph.gv */ + char *name; /* node name from graph.gv */ #endif }; @@ -74,32 +74,34 @@ struct nhdp_node { float link_quality; }; -static inline struct olsr_node* h1_super(struct nhdp_node* n) +static inline struct olsr_node *h1_super(struct nhdp_node *n) { - return (struct olsr_node*) n; + return (struct olsr_node *) n; } -static inline struct nhdp_node* h1_deriv(struct olsr_node* n) +static inline struct nhdp_node *h1_deriv(struct olsr_node *n) { - if (n == NULL) + if (n == NULL) { return 0; + } - if (n->type != NODE_TYPE_NHDP) + if (n->type != NODE_TYPE_NHDP) { return 0; + } - return (struct nhdp_node*) n; + return (struct nhdp_node *) n; } void node_init(void); -struct netaddr* get_local_addr(void); -struct avl_tree* get_olsr_head(void); -int olsr_node_cmp(struct olsr_node* a, struct olsr_node* b); -struct olsr_node* get_node(struct netaddr* addr); -metric_t get_link_metric(struct olsr_node* node, struct netaddr* last_addr); - -void add_other_route(struct olsr_node* node, struct netaddr* last_addr, uint8_t distance, metric_t metric, uint8_t vtime); -void remove_other_route(struct olsr_node* node, struct netaddr* last_addr); -void remove_default_node(struct olsr_node* node); -void push_default_route(struct olsr_node* node); -void pop_other_route(struct olsr_node* node, struct netaddr* last_addr); +struct netaddr *get_local_addr(void); +struct avl_tree *get_olsr_head(void); +int olsr_node_cmp(struct olsr_node *a, struct olsr_node *b); +struct olsr_node *get_node(struct netaddr *addr); +metric_t get_link_metric(struct olsr_node *node, struct netaddr *last_addr); + +void add_other_route(struct olsr_node *node, struct netaddr *last_addr, uint8_t distance, metric_t metric, uint8_t vtime); +void remove_other_route(struct olsr_node *node, struct netaddr *last_addr); +void remove_default_node(struct olsr_node *node); +void push_default_route(struct olsr_node *node); +void pop_other_route(struct olsr_node *node, struct netaddr *last_addr); #endif /* NODE_H_ */ diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 257807b132d3..ca4c1d9f6a5c 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -28,14 +28,15 @@ #include "constants.h" #include "list.h" -static struct olsr_node* _new_olsr_node(struct netaddr* addr, - uint8_t distance, metric_t metric, uint8_t vtime, char* name) +static struct olsr_node *_new_olsr_node(struct netaddr *addr, + uint8_t distance, metric_t metric, uint8_t vtime, char *name) { - struct olsr_node* n = calloc(1, sizeof(struct olsr_node)); + struct olsr_node *n = calloc(1, sizeof(struct olsr_node)); - if (n == NULL) + if (n == NULL) { return NULL; + } n->addr = netaddr_dup(addr); @@ -50,23 +51,29 @@ static struct olsr_node* _new_olsr_node(struct netaddr* addr, n->link_metric = metric; n->expires = time_now() + vtime; #ifdef ENABLE_NAME - if (name) + + if (name) { n->name = strdup(name); + } + #endif avl_insert(get_olsr_head(), &n->node); return n; } -static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) +static void _get_new_flood_mpr(struct netaddr *old_flood_mpr) { TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], old_flood_mpr)); struct olsr_node *node; avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance != 2) + if (node->distance != 2) { continue; - if (node->flood_mpr != NULL && netaddr_cmp(old_flood_mpr, node->flood_mpr) != 0) + } + + if (node->flood_mpr != NULL && netaddr_cmp(old_flood_mpr, node->flood_mpr) != 0) { continue; + } DEBUG("chosing new flood MPR for %s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); @@ -74,10 +81,14 @@ static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) struct alt_route *route; simple_list_for_each(node->other_routes, route) { mpr_b = h1_deriv(get_node(route->last_addr)); - if (mpr_b == NULL || h1_super(mpr_b)->pending) + + if (mpr_b == NULL || h1_super(mpr_b)->pending) { continue; - if (mpr_a == NULL || h1_super(mpr_a)->pending || mpr_a->flood_neighbors < mpr_b->flood_neighbors) + } + + if (mpr_a == NULL || h1_super(mpr_a)->pending || mpr_a->flood_neighbors < mpr_b->flood_neighbors) { mpr_a = mpr_b; + } } if (mpr_a != NULL) { @@ -85,8 +96,10 @@ static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) netaddr_switch(&node->flood_mpr, h1_super(mpr_a)->addr); DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], node->flood_mpr)); - } else + } + else { node->flood_mpr = netaddr_free(node->flood_mpr); + } DEBUG("\tnew flood MPR: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); } @@ -96,7 +109,7 @@ static void _get_new_flood_mpr(struct netaddr* old_flood_mpr) * find a new route for nodes that use last_addr as their default route * if lost_node_addr is not null, all reference to it will be removed (aka lost node) */ -static void _update_children(struct netaddr* last_addr, struct netaddr* lost_node_addr) +static void _update_children(struct netaddr *last_addr, struct netaddr *lost_node_addr) { TRACE_FUN("%s, %s", netaddr_to_str_s(&nbuf[0], last_addr), netaddr_to_str_s(&nbuf[1], lost_node_addr)); @@ -106,16 +119,20 @@ static void _update_children(struct netaddr* last_addr, struct netaddr* lost_nod if (lost_node_addr != NULL) { remove_other_route(node, lost_node_addr); - if (node->flood_mpr != NULL && netaddr_cmp(lost_node_addr, node->flood_mpr) == 0) + + if (node->flood_mpr != NULL && netaddr_cmp(lost_node_addr, node->flood_mpr) == 0) { node->flood_mpr = netaddr_free(node->flood_mpr); + } } if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { - if (lost_node_addr != NULL) + if (lost_node_addr != NULL) { remove_default_node(node); - else + } + else { push_default_route(node); + } add_free_node(node); @@ -124,7 +141,7 @@ static void _update_children(struct netaddr* last_addr, struct netaddr* lost_nod } } -static void _olsr_node_expired(struct olsr_node* node) +static void _olsr_node_expired(struct olsr_node *node) { TRACE_FUN(); @@ -136,7 +153,7 @@ static void _olsr_node_expired(struct olsr_node* node) // 1-hop neighbors will become normal olsr_nodes here, should we care? (possible waste of memory) } -static void _remove_olsr_node(struct olsr_node* node) +static void _remove_olsr_node(struct olsr_node *node) { TRACE_FUN(); @@ -157,43 +174,53 @@ static void _remove_olsr_node(struct olsr_node* node) _update_children(node->addr, node->addr); #ifdef ENABLE_NAME - if (node->name) + + if (node->name) { free(node->name); + } + #endif netaddr_free(node->addr); free(node); } -static bool _route_expired(struct olsr_node* node, struct netaddr* last_addr) +static bool _route_expired(struct olsr_node *node, struct netaddr *last_addr) { - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { return time_now() > node->expires; + } - if (node->other_routes == NULL) + if (node->other_routes == NULL) { return true; + } - struct alt_route* route = simple_list_find_memcmp(node->other_routes, last_addr); + struct alt_route *route = simple_list_find_memcmp(node->other_routes, last_addr); - if (route == NULL) + if (route == NULL) { return true; + } return time_now() > route->expires; } -static void _update_link_quality(struct nhdp_node* node) +static void _update_link_quality(struct nhdp_node *node) { TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); - if (_route_expired(h1_super(node), get_local_addr())) + + if (_route_expired(h1_super(node), get_local_addr())) { node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING); - else + } + else { node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING) + OLSR2_HYST_SCALING; + } if (!h1_super(node)->pending && node->link_quality < OLSR2_HYST_LOW) { h1_super(node)->pending = 1; h1_super(node)->lost = LOST_ITER_MAX; - if (node->mpr_neigh_flood > 0) + if (node->mpr_neigh_flood > 0) { _get_new_flood_mpr(h1_super(node)->addr); + } node->mpr_neigh_flood = 0; node->mpr_neigh_route = 0; @@ -213,18 +240,20 @@ static void _update_link_quality(struct nhdp_node* node) } } -bool remove_expired(struct olsr_node* node) +bool remove_expired(struct olsr_node *node) { time_t _now = time_now(); - if (node->type == NODE_TYPE_NHDP) + if (node->type == NODE_TYPE_NHDP) { _update_link_quality(h1_deriv(node)); + } char skipped; struct alt_route *route, *prev; simple_list_for_each_safe(node->other_routes, route, prev, skipped) { - if (_now - route->expires < OLSR2_HOLD_TIME_SECONDS) + if (_now - route->expires < OLSR2_HOLD_TIME_SECONDS) { continue; + } DEBUG("alternative route to %s (%s) via %s expired, removing it", node->name, netaddr_to_str_s(&nbuf[0], node->addr), @@ -240,34 +269,40 @@ bool remove_expired(struct olsr_node* node) if (node->other_routes == NULL) { _remove_olsr_node(node); return true; - } else + } + else { _olsr_node_expired(node); + } } return false; } -void route_expired(struct olsr_node* node, struct netaddr* last_addr) +void route_expired(struct olsr_node *node, struct netaddr *last_addr) { DEBUG("%s (%s) over %s expired", node->name, netaddr_to_str_s(&nbuf[0], node->addr), netaddr_to_str_s(&nbuf[1], last_addr)); - if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) + if (node->last_addr != NULL && netaddr_cmp(node->last_addr, last_addr) == 0) { _olsr_node_expired(node); - else + } + else { remove_other_route(node, last_addr); + } - if (node->last_addr == NULL && node->other_routes == NULL) + if (node->last_addr == NULL && node->other_routes == NULL) { _remove_olsr_node(node); + } } -void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char* name) +void add_olsr_node(struct netaddr *addr, struct netaddr *last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char *name) { - struct olsr_node* n = get_node(addr); + struct olsr_node *n = get_node(addr); - if (n == NULL) + if (n == NULL) { n = _new_olsr_node(addr, distance, metric, vtime, name); + } if (n == NULL) { puts("ERROR: add_olsr_node failed - out of memory"); @@ -277,8 +312,11 @@ void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtim /* we have added a new node */ if (n->last_addr == NULL) { #ifdef ENABLE_NAME - if (n->name == NULL && name != NULL) + + if (n->name == NULL && name != NULL) { n->name = strdup(name); + } + #endif add_other_route(n, last_addr, distance, metric, vtime); add_free_node(n); @@ -286,14 +324,14 @@ void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtim return; } - struct olsr_node* new_lh = get_node(last_addr); + struct olsr_node *new_lh = get_node(last_addr); /* minimize MPR count */ if (new_lh->type == NODE_TYPE_NHDP) { /* see if a better flooding MPR is availiable */ if (n->flood_mpr != NULL && netaddr_cmp(n->flood_mpr, last_addr) != 0) { - struct nhdp_node* old_flood_mpr = h1_deriv(get_node(n->flood_mpr)); + struct nhdp_node *old_flood_mpr = h1_deriv(get_node(n->flood_mpr)); if (old_flood_mpr != NULL && h1_deriv(new_lh)->flood_neighbors > old_flood_mpr->flood_neighbors) { DEBUG("switching flooding MPR (%s -> %s)", h1_super(old_flood_mpr)->name, new_lh->name); @@ -305,7 +343,7 @@ void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtim /* see if a better routing MPR is availiable */ if (new_lh->path_metric + metric == n->path_metric && netaddr_cmp(last_addr, n->last_addr) != 0) { - struct nhdp_node* cur_mpr = h1_deriv(get_node(n->next_addr)); + struct nhdp_node *cur_mpr = h1_deriv(get_node(n->next_addr)); /* see if the new route is better, that means uses a neighbor that is alreay used for reaching (more) 2-hop neighbors. */ @@ -336,9 +374,10 @@ void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtim add_free_node(n); } -bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) +bool is_known_msg(struct netaddr *addr, uint16_t seq_no, uint8_t vtime) { - struct olsr_node* node = get_node(addr); + struct olsr_node *node = get_node(addr); + if (!node) { node = _new_olsr_node(addr, 255, RFC5444_METRIC_INFINITE, vtime, NULL); node->seq_no = seq_no; @@ -346,10 +385,11 @@ bool is_known_msg(struct netaddr* addr, uint16_t seq_no, uint8_t vtime) } uint16_t tmp = node->seq_no; + /* S1 > S2 AND S1 - S2 < MAXVALUE/2 OR S2 > S1 AND S2 - S1 > MAXVALUE/2 */ if (((seq_no > tmp) && (seq_no - tmp < (1 << 15))) || - ((seq_no < tmp) && (tmp - seq_no > (1 << 15))) ) { + ((seq_no < tmp) && (tmp - seq_no > (1 << 15)))) { node->seq_no = seq_no; return false; } @@ -363,7 +403,7 @@ void print_routing_graph(void) puts("\n----BEGIN ROUTING GRAPH----\n"); puts("subgraph routing {"); puts("\tedge [ color = red ]"); - struct olsr_node* node, *tmp; + struct olsr_node *node, *tmp; avl_for_each_element(get_olsr_head(), node, node) { if (node->addr != NULL && node->last_addr != NULL) { tmp = get_node(node->last_addr); @@ -407,8 +447,8 @@ void print_topology_set(void) struct netaddr_str nbuf[3]; #endif - struct alt_route* route; - struct olsr_node* node; + struct alt_route *route; + struct olsr_node *node; puts(""); puts("---[ Topology Set ]--"); @@ -431,6 +471,7 @@ void print_topology_set(void) netaddr_to_str_s(&nbuf[2], node->next_addr), node->link_metric, node->expires - time_now()); + if (node->type == NODE_TYPE_NHDP) { printf("%s %.2f ", node->pending ? "pending" : "", @@ -443,11 +484,14 @@ void print_topology_set(void) h1_deriv(node)->mpr_slctr_route ? "R" : " " ); } - if (node->flood_mpr != NULL) + + if (node->flood_mpr != NULL) { printf(" flood: %s", netaddr_to_str_s(&nbuf[0], node->flood_mpr)); + } + puts(""); - simple_list_for_each (node->other_routes, route) { + simple_list_for_each(node->other_routes, route) { printf("\t\t\t=> %s (%d); %ld s\n", netaddr_to_str_s(&nbuf[0], route->last_addr), route->link_metric, diff --git a/sys/net/routing/olsr2/olsr.h b/sys/net/routing/olsr2/olsr.h index 36a293f7b16b..c0819440c954 100644 --- a/sys/net/routing/olsr2/olsr.h +++ b/sys/net/routing/olsr2/olsr.h @@ -8,10 +8,10 @@ #include "node.h" -void add_olsr_node(struct netaddr* addr, struct netaddr* last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char* name); -bool is_known_msg(struct netaddr* src, uint16_t seq_no, uint8_t vtime); -bool remove_expired(struct olsr_node* node); -void route_expired(struct olsr_node* node, struct netaddr* last_addr); +void add_olsr_node(struct netaddr *addr, struct netaddr *last_addr, uint8_t vtime, uint8_t distance, metric_t metric, char *name); +bool is_known_msg(struct netaddr *src, uint16_t seq_no, uint8_t vtime); +bool remove_expired(struct olsr_node *node); +void route_expired(struct olsr_node *node, struct netaddr *last_addr); void print_topology_set(void); void print_routing_graph(void); diff --git a/sys/net/routing/olsr2/olsr_debug.h b/sys/net/routing/olsr2/olsr_debug.h index ce8ed29f3ca8..5034d95f24f8 100644 --- a/sys/net/routing/olsr2/olsr_debug.h +++ b/sys/net/routing/olsr2/olsr_debug.h @@ -47,8 +47,9 @@ static inline void print_trace(void) printf("Obtained %zd stack frames.\n", size); - for (i = 0; i < size; i++) - printf ("%s\n", strings[i]); + for (i = 0; i < size; i++) { + printf("%s\n", strings[i]); + } free(strings); } diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index de3fa7011953..7bd037e60000 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -47,7 +47,7 @@ static char sender_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; struct timer_msg { vtimer_t timer; timex_t interval; - void (*func) (void); + void (*func)(void); }; static struct timer_msg msg_hello = { .timer = {0}, .interval = { .seconds = OLSR2_HELLO_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_hello }; @@ -59,16 +59,18 @@ static mutex_t olsr_data; #if defined(BOARD_NATIVE) && defined(ENABLE_NAME) static char _name[5]; -static char* gen_name(char* dest, const size_t len) +static char *gen_name(char *dest, const size_t len) { - for (int i = 0; i < len - 1; ++i) - dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); + for (int i = 0; i < len - 1; ++i) { + dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); + } + dest[len - 1] = '\0'; return dest; } #endif -static void write_packet(struct rfc5444_writer *wr __attribute__ ((unused)), +static void write_packet(struct rfc5444_writer *wr __attribute__((unused)), struct rfc5444_writer_target *iface __attribute__((unused)), void *buffer, size_t length) { @@ -126,7 +128,7 @@ static void olsr_sender_thread(void) while (1) { msg_t m; msg_receive(&m); - struct timer_msg* tmsg = (struct timer_msg*) m.content.ptr; + struct timer_msg *tmsg = (struct timer_msg *) m.content.ptr; mutex_lock(&olsr_data); tmsg->func(); @@ -135,27 +137,31 @@ static void olsr_sender_thread(void) /* add jitter */ tmsg->interval.microseconds = genrand_uint32() % OLSR2_MAX_JITTER_US; - if (vtimer_set_msg(&tmsg->timer, tmsg->interval, thread_getpid(), tmsg) != 0) + if (vtimer_set_msg(&tmsg->timer, tmsg->interval, thread_getpid(), tmsg) != 0) { DEBUG("vtimer_set_msg failed, stopped sending"); + } } } -static ipv6_addr_t* get_next_hop(ipv6_addr_t* dest) +static ipv6_addr_t *get_next_hop(ipv6_addr_t *dest) { - struct olsr_node* node = get_node((struct netaddr*) dest); // get_node will only look at the first few bytes - if (node == NULL) + struct olsr_node *node = get_node((struct netaddr *) dest); // get_node will only look at the first few bytes + + if (node == NULL) { return NULL; + } - return (ipv6_addr_t*) node->next_addr; + return (ipv6_addr_t *) node->next_addr; } #ifdef ENABLE_NAME -ipv6_addr_t* get_ip_by_name(char* name) +ipv6_addr_t *get_ip_by_name(char *name) { struct olsr_node *node; avl_for_each_element(get_olsr_head(), node, node) { - if (node->name != NULL && strcmp(node->name, name) == 0) - return (ipv6_addr_t*) node->addr; + if (node->name != NULL && strcmp(node->name, name) == 0) { + return (ipv6_addr_t *) node->addr; + } } return NULL; @@ -184,12 +190,12 @@ void olsr_init(void) /* enable receive */ sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_receiver_thread, "olsr_rec"); + thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_receiver_thread, "olsr_rec"); /* set get_local_addr() */ get_local_addr()->_type = AF_INET6; get_local_addr()->_prefix_len = 128; - ipv6_net_if_get_best_src_addr((ipv6_addr_t*) get_local_addr(), &sa_bcast.sin6_addr); + ipv6_net_if_get_best_src_addr((ipv6_addr_t *) get_local_addr(), &sa_bcast.sin6_addr); /* register olsr for routing */ ipv6_iface_set_routing_provider(get_next_hop); @@ -197,16 +203,16 @@ void olsr_init(void) DEBUG("This is node %s with IP %s", local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); /* enable sending */ - int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN-1, CREATE_STACKTEST, olsr_sender_thread, "olsr_snd"); + int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_sender_thread, "olsr_snd"); msg_t m; DEBUG("setting up HELLO timer"); - m.content.ptr = (char*) &msg_hello; + m.content.ptr = (char *) &msg_hello; msg_send(&m, pid, false); sleep_s(1); DEBUG("setting up TC timer"); - m.content.ptr = (char*) &msg_tc; + m.content.ptr = (char *) &msg_tc; msg_send(&m, pid, false); } diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 757f60cbae72..230fff3566cd 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -33,8 +33,8 @@ #include "routing.h" static struct rfc5444_reader reader; -static struct netaddr* current_src; -static struct olsr_node* current_node; // only set by _cb_nhdp_blocktlv_packet_okay +static struct netaddr *current_src; +static struct olsr_node *current_node; // only set by _cb_nhdp_blocktlv_packet_okay /* ughh… these variables are needed in the addr callback, but read in the packet callback */ static uint8_t vtime; @@ -115,18 +115,21 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att { DEBUG("received HELLO message:"); - if (netaddr_cmp(get_local_addr(), current_src) == 0) + if (netaddr_cmp(get_local_addr(), current_src) == 0) { return RFC5444_DROP_PACKET; + } /* VTIME is defined as mandatory */ vtime = rfc5444_timetlv_decode(*_nhdp_message_tlvs[IDX_TLV_VTIME].tlv->single_value); - char* name = NULL; + char *name = NULL; #ifdef ENABLE_NAME + if (_nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv) { - name = (char*) _nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv->single_value; + name = (char *) _nhdp_message_tlvs[IDX_TLV_NODE_NAME].tlv->single_value; DEBUG("\tfrom: %s (%s)", name, netaddr_to_str_s(&nbuf[0], current_src)); } + #endif DEBUG("\tmetric: %d", metric); @@ -142,8 +145,9 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att h1_deriv(current_node)->mpr_slctr_route = 0; h1_deriv(current_node)->mpr_slctr_flood = 0; - if (current_node->pending) + if (current_node->pending) { return RFC5444_DROP_PACKET; + } return RFC5444_OKAY; } @@ -152,35 +156,40 @@ _cb_nhdp_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont __att static enum rfc5444_result _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { - struct rfc5444_reader_tlvblock_entry* tlv; + struct rfc5444_reader_tlvblock_entry *tlv; metric_t link_metric = RFC5444_METRIC_MIN; - char* name = NULL; + char *name = NULL; #ifdef ENABLE_NAME + if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { - name = (char*) tlv->single_value; + name = (char *) tlv->single_value; DEBUG("\t2-hop neighbor: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); } + #endif if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { - link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); + link_metric = rfc5444_metric_decode(*((uint16_t *) tlv->single_value)); DEBUG("\t\tmetric: %d", link_metric); } if ((tlv = _nhdp_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { - switch (* (char*) tlv->single_value) { - struct olsr_node* lost; - case RFC5444_LINKSTATUS_LOST: - lost = get_node(&cont->addr); - DEBUG("\t\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); - - if (lost != NULL) - route_expired(lost, current_node->addr); - - return RFC5444_DROP_ADDRESS; - default: - DEBUG("\t\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + switch (* (char *) tlv->single_value) { + struct olsr_node *lost; + + case RFC5444_LINKSTATUS_LOST: + lost = get_node(&cont->addr); + DEBUG("\t\texpired node reported, removing it (HELLO)%s", lost ? "" : " [not found]"); + + if (lost != NULL) { + route_expired(lost, current_node->addr); + } + + return RFC5444_DROP_ADDRESS; + + default: + DEBUG("\t\tunknown LINKSTATUS = %d", * (char *) tlv->single_value); } } @@ -195,8 +204,10 @@ _cb_nhdp_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) DEBUG("\tflood: %d, route: %d", h1_deriv(current_node)->mpr_slctr_flood, h1_deriv(current_node)->mpr_slctr_route); } - } else + } + else { add_olsr_node(&cont->addr, current_src, vtime, 2, link_metric, name); + } return RFC5444_OKAY; } @@ -207,25 +218,31 @@ _cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont) { DEBUG("received TC message:"); - if (!cont->has_origaddr) + if (!cont->has_origaddr) { return RFC5444_DROP_PACKET; + } - if (!cont->has_seqno) + if (!cont->has_seqno) { return RFC5444_DROP_PACKET; + } - if (!cont->has_hopcount || !cont->has_hoplimit) + if (!cont->has_hopcount || !cont->has_hoplimit) { return RFC5444_DROP_PACKET; + } - if (!netaddr_cmp(get_local_addr(), current_src)) + if (!netaddr_cmp(get_local_addr(), current_src)) { return RFC5444_DROP_PACKET; + } - if (!netaddr_cmp(get_local_addr(), &cont->orig_addr)) + if (!netaddr_cmp(get_local_addr(), &cont->orig_addr)) { return RFC5444_DROP_PACKET; + } vtime = rfc5444_timetlv_decode(*_olsr_message_tlvs[IDX_TLV_VTIME].tlv->single_value); - if (is_known_msg(&cont->orig_addr, cont->seqno, vtime)) + if (is_known_msg(&cont->orig_addr, cont->seqno, vtime)) { return RFC5444_DROP_PACKET; + } DEBUG("\tfrom: %s", netaddr_to_str_s(&nbuf[0], &cont->orig_addr)); DEBUG("\tsender: %s", netaddr_to_str_s(&nbuf[0], current_src)); @@ -242,43 +259,51 @@ _cb_olsr_blocktlv_packet_okay(struct rfc5444_reader_tlvblock_context *cont) static enum rfc5444_result _cb_olsr_blocktlv_address_okay(struct rfc5444_reader_tlvblock_context *cont) { - struct rfc5444_reader_tlvblock_entry* tlv __attribute__((unused)); + struct rfc5444_reader_tlvblock_entry *tlv __attribute__((unused)); metric_t link_metric = RFC5444_METRIC_MIN; - char* name = NULL; + char *name = NULL; - if (netaddr_cmp(get_local_addr(), &cont->addr) == 0) + if (netaddr_cmp(get_local_addr(), &cont->addr) == 0) { return RFC5444_DROP_ADDRESS; + } #ifdef ENABLE_NAME + if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_NODE_NAME].tlv)) { - name = (char*) tlv->single_value; + name = (char *) tlv->single_value; DEBUG("\tannounces: %s (%s)", name, netaddr_to_str_s(&nbuf[0], &cont->addr)); } + #endif if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_LINK_STATUS].tlv)) { - switch (* (char*) tlv->single_value) { - struct olsr_node* lost; - case RFC5444_LINKSTATUS_LOST: - lost = get_node(&cont->addr); - DEBUG("\texpired node reported, removing it (TC)%s", lost ? "" : " [not found]"); - - if (lost != NULL) - route_expired(lost, &cont->orig_addr); - - /* emergency flood */ - struct nhdp_node* node = h1_deriv(get_node(current_src)); - if (node != NULL) - node->mpr_slctr_flood = 1; - - return RFC5444_DROP_ADDRESS; - default: - DEBUG("\tunknown LINKSTATUS = %d", * (char*) tlv->single_value); + switch (* (char *) tlv->single_value) { + struct olsr_node *lost; + + case RFC5444_LINKSTATUS_LOST: + lost = get_node(&cont->addr); + DEBUG("\texpired node reported, removing it (TC)%s", lost ? "" : " [not found]"); + + if (lost != NULL) { + route_expired(lost, &cont->orig_addr); + } + + /* emergency flood */ + struct nhdp_node *node = h1_deriv(get_node(current_src)); + + if (node != NULL) { + node->mpr_slctr_flood = 1; + } + + return RFC5444_DROP_ADDRESS; + + default: + DEBUG("\tunknown LINKSTATUS = %d", * (char *) tlv->single_value); } } if ((tlv = _olsr_address_tlvs[IDX_ADDRTLV_METRIC].tlv)) { - link_metric = rfc5444_metric_decode(*((uint16_t*) tlv->single_value)); + link_metric = rfc5444_metric_decode(*((uint16_t *) tlv->single_value)); DEBUG("\t\tmetric: %d", link_metric); } @@ -301,17 +326,20 @@ static void _cb_olsr_forward_message(struct rfc5444_reader_tlvblock_context *context __attribute__((unused)), uint8_t *buffer, size_t length) { - struct olsr_node* node = get_node(current_src); + struct olsr_node *node = get_node(current_src); /* only forward if node selected us as flooding MPR */ - if (node == NULL || h1_deriv(node)->mpr_slctr_flood == 0) + if (node == NULL || h1_deriv(node)->mpr_slctr_flood == 0) { return; + } if (RFC5444_OKAY == rfc5444_writer_forward_msg(&writer, buffer, length)) { DEBUG("\tforwarding"); rfc5444_writer_flush(&writer, &interface, true); - } else + } + else { DEBUG("\tfailed forwarding package"); + } } /** @@ -335,7 +363,7 @@ void reader_init(void) /** * Inject a package into the RFC5444 reader */ -int reader_handle_packet(void* buffer, size_t length, struct netaddr* src, uint8_t metric_in) +int reader_handle_packet(void *buffer, size_t length, struct netaddr *src, uint8_t metric_in) { current_src = src; metric = metric_in; diff --git a/sys/net/routing/olsr2/reader.h b/sys/net/routing/olsr2/reader.h index 02ba94a92c48..8ee38da0cfd3 100644 --- a/sys/net/routing/olsr2/reader.h +++ b/sys/net/routing/olsr2/reader.h @@ -5,7 +5,7 @@ #include "rfc5444/rfc5444_reader.h" void reader_init(void); -int reader_handle_packet(void* buffer, size_t length, struct netaddr* src, uint8_t metric_in); +int reader_handle_packet(void *buffer, size_t length, struct netaddr *src, uint8_t metric_in); void reader_cleanup(void); #endif /* READER_H_ */ diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index e11d5c69cabf..c556666d9502 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -26,17 +26,18 @@ * Keeps yet unroutable nodes, so we don't have to traverse the entire list */ struct free_node { - struct free_node* next; - struct olsr_node* node; + struct free_node *next; + struct olsr_node *node; uint8_t hops; // for sorting only }; -static struct free_node* _pending_head = 0; +static struct free_node *_pending_head = 0; static bool _update_pending = false; -void add_free_node(struct olsr_node* node) +void add_free_node(struct olsr_node *node) { - struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); + struct free_node *n = simple_list_find_cmp(_pending_head, node, (int ( *)(void *, void *)) olsr_node_cmp); + if (n == NULL) { uint8_t hops = node->distance; n = simple_list_add_before(&_pending_head, hops); @@ -53,26 +54,31 @@ void add_free_node(struct olsr_node* node) _update_pending = true; } -bool remove_free_node(struct olsr_node* node) +bool remove_free_node(struct olsr_node *node) { - struct free_node* n = simple_list_find_cmp(_pending_head, node, (int (*)(void *, void *)) olsr_node_cmp); - if (n == NULL) + struct free_node *n = simple_list_find_cmp(_pending_head, node, (int ( *)(void *, void *)) olsr_node_cmp); + + if (n == NULL) { return false; + } + return simple_list_remove(&_pending_head, n); } void fill_routing_table(void) { - struct free_node* head = _pending_head; + struct free_node *head = _pending_head; - if (_pending_head == NULL || !_update_pending) + if (_pending_head == NULL || !_update_pending) { return; + } _update_pending = false; DEBUG("update routing table"); - struct free_node* fn; + struct free_node *fn; bool noop = false; /* when in an iteration there was nothing removed from free nodes */ + while (head && !noop) { noop = true; /* if no nodes could be removed in an iteration, abort */ struct free_node *prev; @@ -81,9 +87,9 @@ void fill_routing_table(void) DEBUG("trying to find a route to %s", fn->node->name); /* chose shortest route from the set of availiable routes */ metric_t min_mtrc = RFC5444_METRIC_INFINITE; - struct olsr_node* node = NULL; /* chosen route */ - struct nhdp_node* flood_mpr = NULL; - struct alt_route* route; /* current other_route */ + struct olsr_node *node = NULL; /* chosen route */ + struct nhdp_node *flood_mpr = NULL; + struct alt_route *route; /* current other_route */ simple_list_for_each(fn->node->other_routes, route) { DEBUG("\tconsidering %s (%d)", netaddr_to_string(&nbuf[0], route->last_addr), route->link_metric); @@ -97,8 +103,9 @@ void fill_routing_table(void) continue; } - if (route->link_metric > min_mtrc) + if (route->link_metric > min_mtrc) { continue; + } min_mtrc = route->link_metric; node = fn->node; @@ -106,7 +113,8 @@ void fill_routing_table(void) } /* see if we can find a better route */ - struct olsr_node* _tmp = get_node(route->last_addr); + struct olsr_node *_tmp = get_node(route->last_addr); + if (_tmp == NULL || _tmp->addr == NULL || _tmp->next_addr == NULL) { DEBUG("\t\tnot routable"); continue; @@ -120,8 +128,9 @@ void fill_routing_table(void) /* flooding MPR selection */ if (_tmp->type == NODE_TYPE_NHDP && - (flood_mpr == NULL || flood_mpr->flood_neighbors < h1_deriv(_tmp)->flood_neighbors)) + (flood_mpr == NULL || flood_mpr->flood_neighbors < h1_deriv(_tmp)->flood_neighbors)) { flood_mpr = h1_deriv(_tmp); + } if (_tmp->path_metric + route->link_metric > min_mtrc) { DEBUG("\t\tdoesn't offer a better route, %d + %d > %d", _tmp->path_metric, route->link_metric, min_mtrc); @@ -131,11 +140,12 @@ void fill_routing_table(void) /* try to minimize MPR count */ if (_tmp->type == NODE_TYPE_NHDP && min_mtrc == _tmp->path_metric + route->link_metric) { DEBUG("\t\tequaly good route found, try to optimize MPR seleciton"); - struct nhdp_node* old_mpr = h1_deriv(node); + struct nhdp_node *old_mpr = h1_deriv(node); /* a direct neighbor might be reached over an additional hop, the true MPR */ - if (netaddr_cmp(_tmp->next_addr, _tmp->addr) != 0) + if (netaddr_cmp(_tmp->next_addr, _tmp->addr) != 0) { old_mpr = h1_deriv(get_node(_tmp->next_addr)); + } /* use the neighbor with the most 2-hop neighbors */ if (old_mpr->mpr_neigh_route >= h1_deriv(_tmp)->mpr_neigh_route + 1) { @@ -153,8 +163,10 @@ void fill_routing_table(void) netaddr_switch(&fn->node->flood_mpr, h1_super(flood_mpr)->addr); DEBUG("[%s] setting flood MPR to %s", __FUNCTION__, netaddr_to_str_s(&nbuf[0], fn->node->flood_mpr)); flood_mpr->mpr_neigh_flood++; - } else + } + else { fn->node->flood_mpr = netaddr_free(fn->node->flood_mpr); + } /* We found a valid route */ if (node == fn->node) { @@ -169,7 +181,8 @@ void fill_routing_table(void) pop_other_route(fn->node, get_local_addr()); simple_list_for_each_remove(&head, fn, prev); - } else if (node != NULL) { + } + else if (node != NULL) { DEBUG("\t%s (%s) -> %s (%s) -> […] -> %s", netaddr_to_str_s(&nbuf[0], fn->node->addr), fn->node->name, netaddr_to_str_s(&nbuf[1], node->addr), node->name, @@ -180,7 +193,7 @@ void fill_routing_table(void) /* update routing MPR information */ if (node->type == NODE_TYPE_NHDP || fn->node->flood_mpr != NULL) { - struct nhdp_node* mpr = h1_deriv(get_node(node->next_addr)); + struct nhdp_node *mpr = h1_deriv(get_node(node->next_addr)); DEBUG("\tincrementing mpr_neigh_route for %s", h1_super(mpr)->name); mpr->mpr_neigh_route++; } @@ -191,14 +204,17 @@ void fill_routing_table(void) pop_other_route(fn->node, node->addr); simple_list_for_each_remove(&head, fn, prev); - } else + } + else { DEBUG("\tdon't yet know how to route %s", netaddr_to_str_s(&nbuf[0], fn->node->addr)); + } } } _pending_head = head; #ifdef DEBUG + while (head != NULL) { DEBUG("Could not find next hop for %s (%s), should be %s (%d hops)", netaddr_to_str_s(&nbuf[0], head->node->addr), head->node->name, @@ -206,5 +222,6 @@ void fill_routing_table(void) head = head->next; } + #endif } diff --git a/sys/net/routing/olsr2/routing.h b/sys/net/routing/olsr2/routing.h index a68eaa2690e3..3657256d1cd2 100644 --- a/sys/net/routing/olsr2/routing.h +++ b/sys/net/routing/olsr2/routing.h @@ -6,13 +6,13 @@ /* * add a node to the list of pending nodes */ -void add_free_node(struct olsr_node* node); +void add_free_node(struct olsr_node *node); /* * remove a node from the list of pending nodes * returns true if node was found and removed */ -bool remove_free_node(struct olsr_node* node); +bool remove_free_node(struct olsr_node *node); /* * try to find a route for pending nodes diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 355fcbde1aab..b0cd8ac98845 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -26,55 +26,61 @@ #include "node.h" #include "olsr_debug.h" -const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src) +const char *netaddr_to_str_s(struct netaddr_str *dst, const struct netaddr *src) { return src ? netaddr_to_string(dst, src) : NULL; } -struct netaddr* netaddr_dup(struct netaddr* addr) +struct netaddr *netaddr_dup(struct netaddr *addr) { - struct netaddr_rc* addr_new = calloc(1, sizeof(struct netaddr_rc)); + struct netaddr_rc *addr_new = calloc(1, sizeof(struct netaddr_rc)); - if (addr_new == NULL) + if (addr_new == NULL) { return NULL; + } addr_new->_refs = 1; return memcpy(addr_new, addr, sizeof(struct netaddr)); } -struct netaddr* netaddr_use(struct netaddr* addr) +struct netaddr *netaddr_use(struct netaddr *addr) { - ((struct netaddr_rc*) addr)->_refs++; + ((struct netaddr_rc *) addr)->_refs++; return addr; } -struct netaddr* netaddr_reuse(struct netaddr* addr) +struct netaddr *netaddr_reuse(struct netaddr *addr) { - if (netaddr_cmp(addr, get_local_addr()) == 0) + if (netaddr_cmp(addr, get_local_addr()) == 0) { return netaddr_use(get_local_addr()); + } + + struct olsr_node *n = get_node(addr); - struct olsr_node* n = get_node(addr); if (!n) { DEBUG("Address %s not found, this shouldn't happen", netaddr_to_str_s(&nbuf[0], addr)); return netaddr_dup(addr); } + return netaddr_use(n->addr); } -struct netaddr* netaddr_free(struct netaddr* addr) +struct netaddr *netaddr_free(struct netaddr *addr) { - struct netaddr_rc* addr_rc = (struct netaddr_rc*) addr; + struct netaddr_rc *addr_rc = (struct netaddr_rc *) addr; - if (addr) + if (addr) { DEBUG("netaddr_free(%s) - %d refs", netaddr_to_str_s(&nbuf[0], addr), addr_rc->_refs); + } - if (addr != NULL && --addr_rc->_refs == 0) + if (addr != NULL && --addr_rc->_refs == 0) { free(addr_rc); + } return NULL; } -void netaddr_switch(struct netaddr** old_addr, struct netaddr* new_addr) +void netaddr_switch(struct netaddr **old_addr, struct netaddr *new_addr) { netaddr_free(*old_addr); *old_addr = netaddr_reuse(new_addr); @@ -98,6 +104,8 @@ void sleep_s(int secs) // process wakes up when a package arrives // go back to sleep to prevent flooding int remaining_sleep = secs; + while ((remaining_sleep = sleep(remaining_sleep))); + #endif } diff --git a/sys/net/routing/olsr2/util.h b/sys/net/routing/olsr2/util.h index bacf8e4a96c6..63182b30e3a7 100644 --- a/sys/net/routing/olsr2/util.h +++ b/sys/net/routing/olsr2/util.h @@ -8,13 +8,13 @@ struct netaddr_rc { uint8_t _refs; }; -const char* netaddr_to_str_s(struct netaddr_str* dst, const struct netaddr* src); +const char *netaddr_to_str_s(struct netaddr_str *dst, const struct netaddr *src); -struct netaddr* netaddr_dup(struct netaddr* addr); -struct netaddr* netaddr_use(struct netaddr* addr); -struct netaddr* netaddr_reuse(struct netaddr* addr); -struct netaddr* netaddr_free(struct netaddr* addr); -void netaddr_switch(struct netaddr** old_addr, struct netaddr* new_addr); +struct netaddr *netaddr_dup(struct netaddr *addr); +struct netaddr *netaddr_use(struct netaddr *addr); +struct netaddr *netaddr_reuse(struct netaddr *addr); +struct netaddr *netaddr_free(struct netaddr *addr); +void netaddr_switch(struct netaddr **old_addr, struct netaddr *new_addr); time_t time_now(void); void sleep_s(int secs); diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index a93474941770..5f859a3f3a16 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -94,7 +94,7 @@ _cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr) static void _cb_add_nhdp_addresses(struct rfc5444_writer *wr) { - struct olsr_node* node, *safe; + struct olsr_node *node, *safe; int value; uint8_t mpr; send_tc_messages = false; @@ -103,33 +103,41 @@ _cb_add_nhdp_addresses(struct rfc5444_writer *wr) avl_for_each_element_safe(get_olsr_head(), node, node, safe) { /* if the node was just removed entirely from the database, continue */ - if (remove_expired(node)) + if (remove_expired(node)) { continue; + } - if (node->type != NODE_TYPE_NHDP && !node->lost) + if (node->type != NODE_TYPE_NHDP && !node->lost) { continue; + } - if (node->pending && !node->lost) + if (node->pending && !node->lost) { continue; + } - if (!node->pending && h1_deriv(node)->mpr_slctr_route) + if (!node->pending && h1_deriv(node)->mpr_slctr_route) { send_tc_messages = true; + } struct rfc5444_writer_address *address = rfc5444_writer_add_address(wr, _nhdp_message_content_provider.creator, node->addr, false); mpr = 0; - if (h1_deriv(node)->mpr_neigh_flood > 0) + + if (h1_deriv(node)->mpr_neigh_flood > 0) { mpr |= RFC5444_MPR_FLOODING; + } - if (h1_deriv(node)->mpr_neigh_route > 0) + if (h1_deriv(node)->mpr_neigh_route > 0) { mpr |= RFC5444_MPR_ROUTING; + } if (mpr > 0) rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_MPR], &mpr, sizeof mpr, false); metric_t link_metric = get_link_metric(node, get_local_addr()); + if (link_metric > RFC5444_METRIC_MIN) { uint16_t mtrc = rfc5444_metric_encode(link_metric); rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_METRIC], @@ -142,13 +150,17 @@ _cb_add_nhdp_addresses(struct rfc5444_writer *wr) rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_LINK_STATUS], &value, sizeof value, false); - if (!send_tc_messages) + if (!send_tc_messages) { node->lost--; + } } + #ifdef ENABLE_NAME + if (node->name) rfc5444_writer_add_addrtlv(wr, address, &_nhdp_addrtlvs[IDX_ADDRTLV_NODE_NAME], node->name, strlen(node->name) + 1, false); + #endif } } @@ -169,25 +181,30 @@ _cb_add_olsr_message_TLVs(struct rfc5444_writer *wr) static void _cb_add_olsr_addresses(struct rfc5444_writer *wr) { - struct olsr_node* node; + struct olsr_node *node; int value; /* add all neighbors */ avl_for_each_element(get_olsr_head(), node, node) { - if (h1_deriv(node) == NULL) + if (h1_deriv(node) == NULL) { continue; + } - if (!h1_deriv(node)->mpr_slctr_route) + if (!h1_deriv(node)->mpr_slctr_route) { continue; + } /* don't advertise neighbors routed over another hop */ - if (node->distance != 1 && !node->lost) + if (node->distance != 1 && !node->lost) { continue; + } - if (node->pending && !node->lost) + if (node->pending && !node->lost) { continue; + } struct rfc5444_writer_address *address __attribute__((unused)); + address = rfc5444_writer_add_address(wr, _olsr_message_content_provider.creator, node->addr, false); if (node->link_metric > RFC5444_METRIC_MIN) { @@ -206,9 +223,11 @@ _cb_add_olsr_addresses(struct rfc5444_writer *wr) } #ifdef ENABLE_NAME + if (node->name) rfc5444_writer_add_addrtlv(wr, address, &_olsr_addrtlvs[IDX_ADDRTLV_NODE_NAME], node->name, strlen(node->name) + 1, false); + #endif } } @@ -289,8 +308,9 @@ void writer_send_hello(void) void writer_send_tc(void) { - if (!send_tc_messages) + if (!send_tc_messages) { return; + } DEBUG("[TC]"); From 3654a1d4a6b7f4871c70d5c2e3ea5be14c4bea11 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 3 Aug 2014 22:20:28 +0200 Subject: [PATCH 21/48] move list to sys/ --- Makefile.dep | 1 + sys/net/routing/olsr2/list.c | 175 --------------------------- sys/net/routing/olsr2/list.h | 203 -------------------------------- sys/net/routing/olsr2/node.c | 2 +- sys/net/routing/olsr2/olsr.c | 2 +- sys/net/routing/olsr2/routing.c | 2 +- 6 files changed, 4 insertions(+), 381 deletions(-) delete mode 100644 sys/net/routing/olsr2/list.c delete mode 100644 sys/net/routing/olsr2/list.h diff --git a/Makefile.dep b/Makefile.dep index 064eb167ad43..fc98313728e6 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -6,6 +6,7 @@ ifneq (,$(filter olsr2,$(USEMODULE))) USEMODULE += vtimer USEMODULE += destiny USEMODULE += sixlowpan + USEMODULE += slist USEMODULE += oonf_common USEMODULE += oonf_rfc5444 endif diff --git a/sys/net/routing/olsr2/list.c b/sys/net/routing/olsr2/list.c deleted file mode 100644 index ec58f401b5bb..000000000000 --- a/sys/net/routing/olsr2/list.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - */ - -/** -* @file list.c -* @author Benjamin Valentin -*/ - -#include -#include - -#include "list.h" - -struct simple_list_elem { - struct simple_list_elem *next; -}; - -void *__simple_list_add_tail(struct simple_list_elem **head, void *mem) -{ - struct simple_list_elem *_head = *head; - - /* check out-of-memory condition */ - if (mem == NULL) { - return NULL; - } - - if (!_head) { - *head = mem; - return *head; - } - - while (_head->next) { - _head = _head->next; - } - - _head = _head->next = mem; - return _head; -} - -void *__simple_list_add_head(struct simple_list_elem **head, void *mem) -{ - struct simple_list_elem *_head = *head; - - /* check out-of-memory condition */ - if (mem == NULL) { - return NULL; - } - - *head = mem; - (*head)->next = _head; - - return *head; -} - -void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset) -{ - struct simple_list_elem *_head = *head; - struct simple_list_elem *prev = 0; - - /* check out-of-memory condition */ - if (mem == NULL) { - return NULL; - } - - if (!_head) { - *head = mem; - return *head; - } - - while (_head) { - int *buff = (void *) _head + offset; - - if (*buff > needle) { - if (prev) { - prev->next = mem; - prev->next->next = _head; - return prev->next; - } - - prev = mem; - prev->next = _head; - *head = prev; - return prev; - } - - prev = _head; - _head = _head->next; - } - - _head = prev->next = mem; - return _head; -} - -void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size) -{ - while (head) { - void **buff = (void *) head + offset; - - if (size == 0 && *buff == needle) { - return head; - } - - if (size > 0 && memcmp(*buff, needle, size) == 0) { - return head; - } - - head = head->next; - } - - return 0; -} - -void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)) -{ - while (head) { - void **buff = (void *) head + offset; - - if (compare(*buff, needle) == 0) { - return head; - } - - head = head->next; - } - - return 0; -} - -void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep) -{ - struct simple_list_elem *_head = *head; - struct simple_list_elem *prev = 0; - - while (_head && _head != node) { - prev = _head; - _head = _head->next; - } - - /* not found */ - if (_head != node) { - return NULL; - } - - /* remove head */ - if (!prev) { - *head = _head->next; - } - else { - prev->next = node->next; - } - - if (keep) { - return node; - } - - free(node); - return (void *) 1; -} - -void __simple_list_clear(struct simple_list_elem **head) -{ - struct simple_list_elem *tmp, *_head = *head; - - while (_head != NULL) { - tmp = _head; - _head = _head->next; - free(tmp); - } - - *head = NULL; -} diff --git a/sys/net/routing/olsr2/list.h b/sys/net/routing/olsr2/list.h deleted file mode 100644 index 48fc5366688f..000000000000 --- a/sys/net/routing/olsr2/list.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more - * details. - */ - -/** - * @file list.h - * @brief simple single linked list implementation with iterators - * - * A list entry is a struct of an arbitrary type but with the only constraint that - * it's first entry is a pointer of the same type as the struct with the name next. - * - * A list is defined by it's first entry, called head. Since the first entry may - * change, a pointer to the first entry is used to refer to the list. - * - * The list automatically allocates and deallocates memory when list elements - * are added or removed - * - * @author Benjamin Valentin - */ - - -#ifndef SIMPLE_LIST_H_ -#define SIMPLE_LIST_H_ -#include -#include - -struct simple_list_elem; - -/** - * @brief allocates memory for a new list entry and appends it before the head. The new entry is the new head. - * - * @param head pointer to the list - * @return the new list entry, NULL if no new list entry could be allocated - */ -#define simple_list_add_head(head) __simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) - - -/** - * @brief appends a preallocated element to the top of the list. The new entry is the new head. - * - * @param head pointer to the list - * @param node preallocated list element - * @return the new list entry (node) - */ -#define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) head, node) - -/** -* @brief allocates memory for a new list entry and appends it at the end of the list. -* -* @param head pointer to pointer to the first list element -* @param head pointer to the list -* @return the new list entry, NULL if no new list entry could be allocated -*/ -#define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) - -/** - * @brief appends a preallocated element to the end of the list. - * - * @param head pointer to the list - * @param node preallocated list element - * @return the new list entry (node) - */ -#define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) - -/** -* @brief allocates memory for a new list entry and adds it before an existing entry. -* The new entry is added before the existing element where old_entry->value > value -* If no such entry could be found, the new entry will be added at the end of the list -* -* @param head pointer to the list -* @param value value to compare list entries -* has to be the same name as the element in the list entry structure that is be used for comparison -* @return pointer to the new element, NULL if no new list element could be allocated -*/ -#define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ - __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) - -/** -* @brief adds an preallocated list element before an existing one. -* The new entry is added before the existing element where old_entry->value > value -* If no such entry could be found, the new entry will be added at the end of the list * -* @param head pointer to the list -* @param value value to compare list entries -* has to be the same name as the element in the list entry structure that is be used for comparison -* @param node preallocated list element -* @return the new list entry (node) -*/ -#define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ - __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) - -/** -* @brief searches for a list element by simple comparison of a struct value -* -* @param head pointer to the list -* @param value the member value of a list entry that is to be found -* has to be the same name as the value in the list element struct -* @return pointer the list entry if found, otherwise NULL -*/ -#define simple_list_find(head, value) (head) == 0 ? NULL : \ - __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) - -/** -* @brief searches for a list element by comparing a buffer in the list element struct -* -* @param head pointer to the list -* @param value pointer to the buffer that is to be found in the list -* has to be the same name as the value in the list element struct -* @return pointer the list entry if found, otherwise NULL -*/ -#define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ - __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) - -/** -* @brief searches for a list element by applying a comparator function to each list entry -* -* @param head pointer to the list -* @param value input to the comparator function -* @param comperator a function that takes (value, node) and returns 0 if they match -* @return pointer the list entry if found, otherwise NULL -*/ -#define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ - __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) - -/** - * @brief removes an entry from the list and frees it's memory - * - * @param head pointer to the list - * @param node entry to be removed - * @returns a non-zero value if the element was found and removed - */ -#define simple_list_remove(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) - -/** - * @brief removes an entry from the list, doesn't free it's memory but returns the element - * - * @param head pointer to the list - * @param node entry to be extracted - * @returns pointer to the element, NULL if it couldn't be found - */ -#define simple_list_extract(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) - -/** - * @brief removes all entries from the list and frees their memory - * - * @param head pointer to the list - */ -#define simple_list_clear(head) __simple_list_clear((struct simple_list_elem**) (head)) - -/** - * @brief starts a loop to iterate over all list entries. Read-only list access only. - * needs to be provided with a local loop variable - * - * @param head pointer to the list - * @param node to the current entry (loop variable) - */ -#define simple_list_for_each(head, node) for ((node) = (head); (node); (node) = (node)->next) - -/** - * @brief starts a loop to iterate over all list elements with the possibility to remove elements - to remove an element, use simple_list_for_each_remove - needs to be provided with a local loop variable as well as two local auxiliary variables - * - * @param head pointer to the list - * @param node to the current entry (loop variable) - * @param prev internal variable, pointer to previous list entry - do not modify - * @param skipped internal variable, integer - do not modify - */ -#define simple_list_for_each_safe(head, node, prev, skipped) \ - for ((skipped) = 0, (prev) = 0, (node) = (head);\ - (node); \ - (prev) = ((skipped) ? (prev) : (node)), \ - (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) - -/** - * @brief removes an element in a simple_list_for_each_safe context - * - * @param head pointer to the list - * @param node pointer to the current entry (loop variable) - * @param prev internal variable, provided by simple_list_for_each_safe - */ -#define simple_list_for_each_remove(head, node, prev) do { \ - if (!prev) { \ - (skipped) = 1; \ - *(head) = (*(head))->next; \ - } else \ - (prev)->next = (node)->next; \ - free(node); \ - (node) = (prev) ? (prev) : *(head); \ - } while (0) - -void *__simple_list_add_head(struct simple_list_elem **head, void *mem); -void *__simple_list_add_tail(struct simple_list_elem **head, void *mem); -void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset); -void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size); -void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)); -void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep); -void __simple_list_clear(struct simple_list_elem **head); - -#endif /* SIMPLE_LIST_H_ */ diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index 713da0c80691..121cbf5e8926 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -14,7 +14,7 @@ #include #include "node.h" -#include "list.h" +#include #include "olsr_debug.h" #include "common/netaddr.h" diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index ca4c1d9f6a5c..b8f393d6f8a0 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -26,7 +26,7 @@ #include "olsr_debug.h" #include "routing.h" #include "constants.h" -#include "list.h" +#include static struct olsr_node *_new_olsr_node(struct netaddr *addr, uint8_t distance, metric_t metric, uint8_t vtime, char *name) diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index c556666d9502..fe659ab79ae5 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -15,7 +15,7 @@ #include #include "olsr.h" -#include "list.h" +#include #include "olsr_debug.h" #include "util.h" #include "routing.h" From 9635f8da49f5ae869ade6ae63afa8aaf0c54c9b2 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 3 Aug 2014 22:23:05 +0200 Subject: [PATCH 22/48] add single-linked list implementation This adds a simple single linked list which allocates and deallocates memory for it's elements on it's own. It also provides functions to search for and iterate over elements. --- sys/Makefile | 3 + sys/include/slist.h | 203 ++++++++++++++++++++++++++++++++++++++++++++ sys/slist/Makefile | 1 + sys/slist/slist.c | 175 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 382 insertions(+) create mode 100644 sys/include/slist.h create mode 100644 sys/slist/Makefile create mode 100644 sys/slist/slist.c diff --git a/sys/Makefile b/sys/Makefile index 8b7985464dfc..f7222d8907fa 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -37,6 +37,9 @@ endif ifneq (,$(filter shell_commands,$(USEMODULE))) DIRS += shell/commands endif +ifneq (,$(filter slist,$(USEMODULE))) + DIRS += slist +endif ifneq (,$(filter timex,$(USEMODULE))) DIRS += timex endif diff --git a/sys/include/slist.h b/sys/include/slist.h new file mode 100644 index 000000000000..e599a5553c31 --- /dev/null +++ b/sys/include/slist.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @file slist.h + * @brief simple single linked list implementation with iterators + * + * A list entry is a struct of an arbitrary type but with the only constraint that + * it's first entry is a pointer of the same type as the struct with the name next. + * + * A list is defined by it's first entry, called head. Since the first entry may + * change, a pointer to the first entry is used to refer to the list. + * + * The list automatically allocates and deallocates memory when list elements + * are added or removed + * + * @author Benjamin Valentin + */ + + +#ifndef SIMPLE_LIST_H_ +#define SIMPLE_LIST_H_ +#include +#include + +struct simple_list_elem; + +/** + * @brief allocates memory for a new list entry and appends it before the head. The new entry is the new head. + * + * @param head pointer to the list + * @return the new list entry, NULL if no new list entry could be allocated + */ +#define simple_list_add_head(head) __simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) + + +/** + * @brief appends a preallocated element to the top of the list. The new entry is the new head. + * + * @param head pointer to the list + * @param node preallocated list element + * @return the new list entry (node) + */ +#define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) head, node) + +/** +* @brief allocates memory for a new list entry and appends it at the end of the list. +* +* @param head pointer to pointer to the first list element +* @param head pointer to the list +* @return the new list entry, NULL if no new list entry could be allocated +*/ +#define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) + +/** + * @brief appends a preallocated element to the end of the list. + * + * @param head pointer to the list + * @param node preallocated list element + * @return the new list entry (node) + */ +#define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) + +/** +* @brief allocates memory for a new list entry and adds it before an existing entry. +* The new entry is added before the existing element where old_entry->value > value +* If no such entry could be found, the new entry will be added at the end of the list +* +* @param head pointer to the list +* @param value value to compare list entries +* has to be the same name as the element in the list entry structure that is be used for comparison +* @return pointer to the new element, NULL if no new list element could be allocated +*/ +#define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ + __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) + +/** +* @brief adds an preallocated list element before an existing one. +* The new entry is added before the existing element where old_entry->value > value +* If no such entry could be found, the new entry will be added at the end of the list * +* @param head pointer to the list +* @param value value to compare list entries +* has to be the same name as the element in the list entry structure that is be used for comparison +* @param node preallocated list element +* @return the new list entry (node) +*/ +#define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ + __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) + +/** +* @brief searches for a list element by simple comparison of a struct value +* +* @param head pointer to the list +* @param value the member value of a list entry that is to be found +* has to be the same name as the value in the list element struct +* @return pointer the list entry if found, otherwise NULL +*/ +#define simple_list_find(head, value) (head) == 0 ? NULL : \ + __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) + +/** +* @brief searches for a list element by comparing a buffer in the list element struct +* +* @param head pointer to the list +* @param value pointer to the buffer that is to be found in the list +* has to be the same name as the value in the list element struct +* @return pointer the list entry if found, otherwise NULL +*/ +#define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ + __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) + +/** +* @brief searches for a list element by applying a comparator function to each list entry +* +* @param head pointer to the list +* @param value input to the comparator function +* @param comperator a function that takes (value, node) and returns 0 if they match +* @return pointer the list entry if found, otherwise NULL +*/ +#define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ + __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) + +/** + * @brief removes an entry from the list and frees it's memory + * + * @param head pointer to the list + * @param node entry to be removed + * @returns a non-zero value if the element was found and removed + */ +#define simple_list_remove(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) + +/** + * @brief removes an entry from the list, doesn't free it's memory but returns the element + * + * @param head pointer to the list + * @param node entry to be extracted + * @returns pointer to the element, NULL if it couldn't be found + */ +#define simple_list_extract(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) + +/** + * @brief removes all entries from the list and frees their memory + * + * @param head pointer to the list + */ +#define simple_list_clear(head) __simple_list_clear((struct simple_list_elem**) (head)) + +/** + * @brief starts a loop to iterate over all list entries. Read-only list access only. + * needs to be provided with a local loop variable + * + * @param head pointer to the list + * @param node to the current entry (loop variable) + */ +#define simple_list_for_each(head, node) for ((node) = (head); (node); (node) = (node)->next) + +/** + * @brief starts a loop to iterate over all list elements with the possibility to remove elements + to remove an element, use simple_list_for_each_remove + needs to be provided with a local loop variable as well as two local auxiliary variables + * + * @param head pointer to the list + * @param node to the current entry (loop variable) + * @param prev internal variable, pointer to previous list entry - do not modify + * @param skipped internal variable, integer - do not modify + */ +#define simple_list_for_each_safe(head, node, prev, skipped) \ + for ((skipped) = 0, (prev) = 0, (node) = (head);\ + (node); \ + (prev) = ((skipped) ? (prev) : (node)), \ + (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) + +/** + * @brief removes an element in a simple_list_for_each_safe context + * + * @param head pointer to the list + * @param node pointer to the current entry (loop variable) + * @param prev internal variable, provided by simple_list_for_each_safe + */ +#define simple_list_for_each_remove(head, node, prev) do { \ + if (!prev) { \ + (skipped) = 1; \ + *(head) = (*(head))->next; \ + } else \ + (prev)->next = (node)->next; \ + free(node); \ + (node) = (prev) ? (prev) : *(head); \ + } while (0) + +void *__simple_list_add_head(struct simple_list_elem **head, void *mem); +void *__simple_list_add_tail(struct simple_list_elem **head, void *mem); +void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset); +void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size); +void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)); +void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep); +void __simple_list_clear(struct simple_list_elem **head); + +#endif /* SIMPLE_LIST_H_ */ diff --git a/sys/slist/Makefile b/sys/slist/Makefile new file mode 100644 index 000000000000..48422e909a47 --- /dev/null +++ b/sys/slist/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/slist/slist.c b/sys/slist/slist.c new file mode 100644 index 000000000000..1da7a3758e6a --- /dev/null +++ b/sys/slist/slist.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/** +* @file slist.c +* @author Benjamin Valentin +*/ + +#include +#include + +#include "slist.h" + +struct simple_list_elem { + struct simple_list_elem *next; +}; + +void *__simple_list_add_tail(struct simple_list_elem **head, void *mem) +{ + struct simple_list_elem *_head = *head; + + /* check out-of-memory condition */ + if (mem == NULL) { + return NULL; + } + + if (!_head) { + *head = mem; + return *head; + } + + while (_head->next) { + _head = _head->next; + } + + _head = _head->next = mem; + return _head; +} + +void *__simple_list_add_head(struct simple_list_elem **head, void *mem) +{ + struct simple_list_elem *_head = *head; + + /* check out-of-memory condition */ + if (mem == NULL) { + return NULL; + } + + *head = mem; + (*head)->next = _head; + + return *head; +} + +void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset) +{ + struct simple_list_elem *_head = *head; + struct simple_list_elem *prev = 0; + + /* check out-of-memory condition */ + if (mem == NULL) { + return NULL; + } + + if (!_head) { + *head = mem; + return *head; + } + + while (_head) { + int *buff = (void *) _head + offset; + + if (*buff > needle) { + if (prev) { + prev->next = mem; + prev->next->next = _head; + return prev->next; + } + + prev = mem; + prev->next = _head; + *head = prev; + return prev; + } + + prev = _head; + _head = _head->next; + } + + _head = prev->next = mem; + return _head; +} + +void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size) +{ + while (head) { + void **buff = (void *) head + offset; + + if (size == 0 && *buff == needle) { + return head; + } + + if (size > 0 && memcmp(*buff, needle, size) == 0) { + return head; + } + + head = head->next; + } + + return 0; +} + +void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)) +{ + while (head) { + void **buff = (void *) head + offset; + + if (compare(*buff, needle) == 0) { + return head; + } + + head = head->next; + } + + return 0; +} + +void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep) +{ + struct simple_list_elem *_head = *head; + struct simple_list_elem *prev = 0; + + while (_head && _head != node) { + prev = _head; + _head = _head->next; + } + + /* not found */ + if (_head != node) { + return NULL; + } + + /* remove head */ + if (!prev) { + *head = _head->next; + } + else { + prev->next = node->next; + } + + if (keep) { + return node; + } + + free(node); + return (void *) 1; +} + +void __simple_list_clear(struct simple_list_elem **head) +{ + struct simple_list_elem *tmp, *_head = *head; + + while (_head != NULL) { + tmp = _head; + _head = _head->next; + free(tmp); + } + + *head = NULL; +} From 50cd845240fe908204d37496acd9c9abcc2a2167 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 3 Aug 2014 22:49:24 +0200 Subject: [PATCH 23/48] adapt to thread api changes --- sys/net/routing/olsr2/olsr_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 7bd037e60000..87e0dd326c69 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -190,7 +190,7 @@ void olsr_init(void) /* enable receive */ sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_receiver_thread, "olsr_rec"); + thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_receiver_thread, NULL, "olsr_rec"); /* set get_local_addr() */ get_local_addr()->_type = AF_INET6; @@ -203,7 +203,7 @@ void olsr_init(void) DEBUG("This is node %s with IP %s", local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); /* enable sending */ - int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_sender_thread, "olsr_snd"); + int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_sender_thread, NULL, "olsr_snd"); msg_t m; DEBUG("setting up HELLO timer"); From 598aa6337b95e0d6ba3b6797315aa40086ae6c9f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sun, 3 Aug 2014 23:27:21 +0200 Subject: [PATCH 24/48] fix licence --- examples/olsr2/main.c | 2 +- sys/include/slist.h | 2 +- sys/net/include/olsr2/olsr2.h | 15 +++++++++++++++ sys/net/routing/olsr2/constants.h | 19 ++++++++++++++++--- sys/net/routing/olsr2/nhdp.c | 2 +- sys/net/routing/olsr2/nhdp.h | 13 +++++++++++++ sys/net/routing/olsr2/node.c | 2 +- sys/net/routing/olsr2/node.h | 13 +++++++++++++ sys/net/routing/olsr2/olsr.c | 2 +- sys/net/routing/olsr2/olsr.h | 13 +++++++++++++ sys/net/routing/olsr2/olsr_debug.h | 13 +++++++++++++ sys/net/routing/olsr2/olsr_init.c | 2 +- sys/net/routing/olsr2/reader.c | 2 +- sys/net/routing/olsr2/reader.h | 19 ++++++++++++++++--- sys/net/routing/olsr2/routing.c | 2 +- sys/net/routing/olsr2/routing.h | 13 +++++++++++++ sys/net/routing/olsr2/util.c | 2 +- sys/net/routing/olsr2/util.h | 17 +++++++++++++++-- sys/net/routing/olsr2/writer.c | 2 +- sys/net/routing/olsr2/writer.h | 19 ++++++++++++++++--- sys/slist/slist.c | 2 +- 21 files changed, 154 insertions(+), 22 deletions(-) diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c index 26fc8ecffb6d..8e82d3d56e03 100644 --- a/examples/olsr2/main.c +++ b/examples/olsr2/main.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. */ diff --git a/sys/include/slist.h b/sys/include/slist.h index e599a5553c31..5a1857f5410a 100644 --- a/sys/include/slist.h +++ b/sys/include/slist.h @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. */ diff --git a/sys/net/include/olsr2/olsr2.h b/sys/net/include/olsr2/olsr2.h index 6f7f1f3e8e34..d0dea8c76b06 100644 --- a/sys/net/include/olsr2/olsr2.h +++ b/sys/net/include/olsr2/olsr2.h @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @brief The OLSRv2 routing algorithm. + * @author Benjamin Valentin + * @} + */ + + #include "sixlowpan/types.h" /** diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index 3da27b4cbc3e..9f6adcf012cb 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -1,5 +1,18 @@ -#ifndef CONSTANTS_H_ -#define CONSTANTS_H_ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + +#ifndef OLSR2_CONSTANTS_H_ +#define OLSR2_CONSTANTS_H_ /* The well-known UDP port for MANET as defined in RFC 5498 */ #define MANET_PORT 269 @@ -40,4 +53,4 @@ enum { IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ }; -#endif /* CONSTANTS_H_ */ +#endif /* OLSR2_CONSTANTS_H_ */ diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index c15ba9be45b6..bc26b4be639f 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/nhdp.h b/sys/net/routing/olsr2/nhdp.h index 70258975dc82..c0a56e8ca11f 100644 --- a/sys/net/routing/olsr2/nhdp.h +++ b/sys/net/routing/olsr2/nhdp.h @@ -1,3 +1,16 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + #ifndef NHDP_H_ #define NHDP_H_ diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index 121cbf5e8926..39963b4649a9 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index f6d4a7c292ae..e950e9b3d606 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -1,3 +1,16 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + #ifndef NODE_H_ #define NODE_H_ diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index b8f393d6f8a0..2b62f2b78d2f 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/olsr.h b/sys/net/routing/olsr2/olsr.h index c0819440c954..13a3a84b2c45 100644 --- a/sys/net/routing/olsr2/olsr.h +++ b/sys/net/routing/olsr2/olsr.h @@ -1,3 +1,16 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + #ifndef OLSR_H_ #define OLSR_H_ diff --git a/sys/net/routing/olsr2/olsr_debug.h b/sys/net/routing/olsr2/olsr_debug.h index 5034d95f24f8..7aed558dec8b 100644 --- a/sys/net/routing/olsr2/olsr_debug.h +++ b/sys/net/routing/olsr2/olsr_debug.h @@ -1,3 +1,16 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + #ifndef OLSR2_DEBUG_H_ #define OLSR2_DEBUG_H_ diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 87e0dd326c69..4ee25c1a4033 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 230fff3566cd..32426bdb53e1 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/reader.h b/sys/net/routing/olsr2/reader.h index 8ee38da0cfd3..b5bcbe748ffa 100644 --- a/sys/net/routing/olsr2/reader.h +++ b/sys/net/routing/olsr2/reader.h @@ -1,5 +1,18 @@ -#ifndef READER_H_ -#define READER_H_ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + +#ifndef OLSR2_READER_H_ +#define OLSR2_READER_H_ #include "common/common_types.h" #include "rfc5444/rfc5444_reader.h" @@ -8,4 +21,4 @@ void reader_init(void); int reader_handle_packet(void *buffer, size_t length, struct netaddr *src, uint8_t metric_in); void reader_cleanup(void); -#endif /* READER_H_ */ +#endif /* OLSR2_READER_H_ */ diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index fe659ab79ae5..77672a4ee9db 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/routing.h b/sys/net/routing/olsr2/routing.h index 3657256d1cd2..4ec730e53d25 100644 --- a/sys/net/routing/olsr2/routing.h +++ b/sys/net/routing/olsr2/routing.h @@ -1,3 +1,16 @@ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + #ifndef ROUTING_H_ #define ROUTING_H_ diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index b0cd8ac98845..f8eea7175c91 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/util.h b/sys/net/routing/olsr2/util.h index 63182b30e3a7..c5ff9364602d 100644 --- a/sys/net/routing/olsr2/util.h +++ b/sys/net/routing/olsr2/util.h @@ -1,5 +1,18 @@ -#ifndef UTIL_H_ -#define UTIL_H_ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + +#ifndef OLSR2_UTIL_H_ +#define OLSR2_UTIL_H_ #include "common/netaddr.h" diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index 5f859a3f3a16..15187f18c7d8 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. * * @ingroup olsr2 diff --git a/sys/net/routing/olsr2/writer.h b/sys/net/routing/olsr2/writer.h index 6d9314b6b9b5..02fd03bb97ab 100644 --- a/sys/net/routing/olsr2/writer.h +++ b/sys/net/routing/olsr2/writer.h @@ -1,5 +1,18 @@ -#ifndef WRITER_H_ -#define WRITER_H_ +/* + * Copyright (C) 2014 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + * + * @ingroup olsr2 + * @{ + * @author Benjamin Valentin + * @} + */ + +#ifndef OLSR2_WRITER_H_ +#define OLSR2_WRITER_H_ #include "common/common_types.h" #include "rfc5444/rfc5444_writer.h" @@ -16,4 +29,4 @@ void writer_send_hello(void); void writer_send_tc(void); void writer_cleanup(void); -#endif /* WRITER_H_ */ +#endif /* OLSR2_WRITER_H_ */ diff --git a/sys/slist/slist.c b/sys/slist/slist.c index 1da7a3758e6a..7c1951cb2d4d 100644 --- a/sys/slist/slist.c +++ b/sys/slist/slist.c @@ -2,7 +2,7 @@ * Copyright (C) 2014 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser General - * Public License. See the file LICENSE in the top level directory for more + * Public License v2.1. See the file LICENSE in the top level directory for more * details. */ From bdad777ea7d9f2e0255a475ee8f7b03567a4eb9f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 25 Aug 2014 03:32:18 +0200 Subject: [PATCH 25/48] add test for slist loosely based on a cunit test file for slist --- tests/slist/Makefile | 6 ++ tests/slist/main.c | 215 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 tests/slist/Makefile create mode 100644 tests/slist/main.c diff --git a/tests/slist/Makefile b/tests/slist/Makefile new file mode 100644 index 000000000000..c531bcb32c6b --- /dev/null +++ b/tests/slist/Makefile @@ -0,0 +1,6 @@ +export APPLICATION = slist +include ../Makefile.tests_common + +USEMODULE += slist + +include $(RIOTBASE)/Makefile.include diff --git a/tests/slist/main.c b/tests/slist/main.c new file mode 100644 index 000000000000..3a806eb02675 --- /dev/null +++ b/tests/slist/main.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2014 Benjamin Valentin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief slist (simple list) test application + * + * @author Benjamin Valentin + * + * @} + */ + +#include +#include +#include +#include "slist.h" + +int fail = 0; +void cunit_named_check(int cond, const char *name, int line, const char *format, ...) +{ + va_list ap; + + if (cond) { + return; + } + + fail++; + + va_start(ap, format); + + printf("\t%s (%d) fail: ", name, line); + vprintf(format, ap); + puts("\n"); + va_end(ap); +} +#define CHECK_TRUE(cond, format, args...) cunit_named_check(cond, __func__, __LINE__, format, ##args); + +char foo[] = "Hello World!"; +char bar[] = "Hello CUnit!"; +char baz[] = "c-c-c-combobreaker"; + +char print_buffer[128]; + +struct test_list { + struct test_list *next; + char *buffer; + int value; +}; + +struct number_list { + struct number_list *next; + int value; +}; + +struct test_list *_get_by_buffer(struct test_list *head, char *buffer) +{ + return simple_list_find(head, buffer); +} + +struct test_list *_get_by_value(struct test_list *head, int value) +{ + return simple_list_find(head, value); +} + +struct test_list *_add_test_list(struct test_list **head, char *buffer, int value) +{ + struct test_list *node = simple_list_add_tail(head); + + node->buffer = buffer; + node->value = value; + + return node; +} + +char *_print_result(struct test_list *result) +{ + if (result) { + snprintf(print_buffer, sizeof print_buffer, "%d, %s\n", result->value, result->buffer); + } + else { + snprintf(print_buffer, sizeof print_buffer, "Not found\n"); + } + + return print_buffer; +} + +int _is_equal(struct test_list *node, const int value, const char *buffer) +{ + return node != 0 && node->value == value && !strcmp(node->buffer, buffer); +} + +void test_simple_list_fill(struct test_list *_head) +{ + CHECK_TRUE(_is_equal(_get_by_buffer(_head, bar), 42, bar), "%s", _print_result(_get_by_buffer(_head, bar))); + CHECK_TRUE(_is_equal(_get_by_value(_head, 23), 23, foo), "%s", _print_result(_get_by_value(_head, 23))); +} + +void test_simple_list_remove(struct test_list **__head) +{ + struct test_list *_head; + simple_list_remove(__head, _get_by_buffer(*__head, foo)); + _head = *__head; + + CHECK_TRUE(_is_equal(_head, 42, bar), "%s", _print_result(_head)); + CHECK_TRUE(_is_equal(_head->next, 1337, baz), "%s", _print_result(_head->next)); +} + +void test_simple_list_find(struct test_list *_head) +{ + char buffer[sizeof bar]; + memcpy(buffer, bar, sizeof buffer); + + CHECK_TRUE(_is_equal(simple_list_find_memcmp(_head, buffer), 42, bar), "%s", + _print_result(simple_list_find_memcmp(_head, buffer))); + + CHECK_TRUE(_is_equal(simple_list_find_cmp(_head, buffer, (int ( *)(void *, void *)) strcmp), 42, bar), "%s", + _print_result(simple_list_find_cmp(_head, buffer, (int ( *)(void *, void *)) strcmp))); +} + +void _add_number_list(struct number_list **head, int value) +{ + struct number_list *node = simple_list_add_before(head, value); + node->value = value; +} + +void test_number_list(void) +{ + struct number_list *head = 0; + + _add_number_list(&head, 23); + _add_number_list(&head, 42); + _add_number_list(&head, 17); + _add_number_list(&head, 32); + _add_number_list(&head, 1); + + int prev = 0; + struct number_list *node; + simple_list_for_each(head, node) { + CHECK_TRUE(node->value >= prev, "%d < %d", node->value, prev); + prev = node->value; + } +} + +void test_for_each_remove(void) +{ + struct number_list *head = 0; + + int i = 0; + int max = 11; + + for (i = 1; i < max; ++i) { + if (i == 2) { + _add_number_list(&head, 3); + } + else { + _add_number_list(&head, i); + } + } + + char skipped; + struct number_list *node, *prev; + simple_list_for_each_safe(head, node, prev, skipped) { + if (node->value % 2) { + printf("removing %d\n", node->value); + simple_list_for_each_remove(&head, node, prev); + } + else { + printf("keeping %d\n", node->value); + } + } + + i = 0; + simple_list_for_each(head, node) { + CHECK_TRUE(node->value % 2 == 0, "%d", node->value); + ++i; + } + CHECK_TRUE(i == max / 2 - 1, "missed an entry"); + + simple_list_clear(&head); + + CHECK_TRUE(head == NULL, "list not cleared properly"); +} + +int main(void) +{ + struct test_list *_head = 0; + + _add_test_list(&_head, foo, 23); + _add_test_list(&_head, bar, 42); + _add_test_list(&_head, baz, 1337); + + struct test_list *node; + simple_list_for_each(_head, node) + printf("%s\n", _print_result(node)); + + test_simple_list_fill(_head); + test_simple_list_remove(&_head); + test_simple_list_find(_head); + + test_number_list(); + test_for_each_remove(); + + puts("-----------------"); + printf("End, %d errors\n", fail); + + return fail; +} From 44e2cd36c30d381e9a889eccfcb737362430d960 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 2 Sep 2014 16:03:40 +0200 Subject: [PATCH 26/48] get rid of olsr_debug.h --- sys/net/routing/olsr2/nhdp.c | 35 ++----------- sys/net/routing/olsr2/nhdp.h | 2 - sys/net/routing/olsr2/node.c | 10 ++-- sys/net/routing/olsr2/node.h | 1 - sys/net/routing/olsr2/olsr.c | 21 ++++---- sys/net/routing/olsr2/olsr_debug.h | 79 ------------------------------ sys/net/routing/olsr2/olsr_init.c | 6 ++- sys/net/routing/olsr2/reader.c | 6 ++- sys/net/routing/olsr2/routing.c | 6 ++- sys/net/routing/olsr2/util.c | 6 ++- sys/net/routing/olsr2/writer.c | 2 +- 11 files changed, 45 insertions(+), 129 deletions(-) delete mode 100644 sys/net/routing/olsr2/olsr_debug.h diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index bc26b4be639f..2b1eca9d5600 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -15,13 +15,17 @@ #include "nhdp.h" #include "util.h" -#include "olsr_debug.h" +#include "debug.h" #include "node.h" #include "routing.h" #include "constants.h" #include "common/avl.h" +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[1]; +#endif + static struct olsr_node *_node_replace(struct olsr_node *old_n) { struct olsr_node *new_n = calloc(1, sizeof(struct nhdp_node)); @@ -103,32 +107,3 @@ struct olsr_node *olsr2_add_neighbor(struct netaddr *addr, metric_t metric, uint return n; } - -#ifdef ENABLE_DEBUG_OLSR -void print_neighbors(void) -{ - struct olsr_node *node; - - DEBUG("1-hop neighbors:"); - avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance == 1 && node->type == NODE_TYPE_NHDP) - DEBUG("\tneighbor: %s (%s) (mpr for [%d|%d] nodes)", - node->name, - netaddr_to_str_s(&nbuf[0], node->addr), - h1_deriv(node)->mpr_neigh_flood, - h1_deriv(node)->mpr_neigh_route); - } - - DEBUG("2-hop neighbors:"); - avl_for_each_element(get_olsr_head(), node, node) { - if (node->distance == 2) - DEBUG("\t%s (%s) -> %s -> %s (%s)", - node->name, netaddr_to_str_s(&nbuf[0], node->addr), - netaddr_to_str_s(&nbuf[1], node->next_addr), - local_name, - netaddr_to_str_s(&nbuf[2], get_local_addr())); - } -} -#else -void print_neighbors(void) {} -#endif diff --git a/sys/net/routing/olsr2/nhdp.h b/sys/net/routing/olsr2/nhdp.h index c0a56e8ca11f..2809dabe15b1 100644 --- a/sys/net/routing/olsr2/nhdp.h +++ b/sys/net/routing/olsr2/nhdp.h @@ -21,6 +21,4 @@ struct olsr_node *olsr2_add_neighbor(struct netaddr *addr, metric_t metric, uint8_t vtime, char *name); -void print_neighbors(void); - #endif /* NHDP_H_ */ diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index 39963b4649a9..546d21eaa322 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -15,7 +15,7 @@ #include "node.h" #include -#include "olsr_debug.h" +#include "debug.h" #include "common/netaddr.h" #include "rfc5444/rfc5444.h" @@ -23,13 +23,17 @@ static struct netaddr_rc local_addr; static struct avl_tree olsr_head; +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[2]; +#endif + #ifdef ENABLE_NAME char *local_name; #endif static void _decrease_mpr_neigh(struct olsr_node *node) { - TRACE_FUN("%s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); + DEBUGF("%s (%s)", netaddr_to_str_s(&nbuf[0], node->addr), node->name); /* only consider 2-hop nieghbors (only 2-hop neighbors have flood_mpr set) */ if (node->flood_mpr == NULL) { @@ -216,7 +220,7 @@ void pop_other_route(struct olsr_node *node, struct netaddr *last_addr) void remove_other_route(struct olsr_node *node, struct netaddr *last_addr) { - TRACE_FUN("%s (%s), %s", netaddr_to_str_s(&nbuf[0], node->addr), node->name, + DEBUGF("%s (%s), %s", netaddr_to_str_s(&nbuf[0], node->addr), node->name, netaddr_to_str_s(&nbuf[1], last_addr)); char skipped; diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index e950e9b3d606..d4375fcde1f3 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -18,7 +18,6 @@ #include "common/netaddr.h" #include "util.h" -#include "olsr_debug.h" #ifdef ENABLE_NAME extern char *local_name; diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 2b62f2b78d2f..3d88056db53c 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -23,11 +23,15 @@ #include "olsr.h" #include "util.h" -#include "olsr_debug.h" +#include "debug.h" #include "routing.h" #include "constants.h" #include +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[3]; +#endif + static struct olsr_node *_new_olsr_node(struct netaddr *addr, uint8_t distance, metric_t metric, uint8_t vtime, char *name) { @@ -64,7 +68,7 @@ static struct olsr_node *_new_olsr_node(struct netaddr *addr, static void _get_new_flood_mpr(struct netaddr *old_flood_mpr) { - TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], old_flood_mpr)); + DEBUGF("%s", netaddr_to_str_s(&nbuf[0], old_flood_mpr)); struct olsr_node *node; avl_for_each_element(get_olsr_head(), node, node) { if (node->distance != 2) { @@ -111,7 +115,7 @@ static void _get_new_flood_mpr(struct netaddr *old_flood_mpr) */ static void _update_children(struct netaddr *last_addr, struct netaddr *lost_node_addr) { - TRACE_FUN("%s, %s", netaddr_to_str_s(&nbuf[0], last_addr), + DEBUGF("%s, %s", netaddr_to_str_s(&nbuf[0], last_addr), netaddr_to_str_s(&nbuf[1], lost_node_addr)); struct olsr_node *node; @@ -143,7 +147,7 @@ static void _update_children(struct netaddr *last_addr, struct netaddr *lost_nod static void _olsr_node_expired(struct olsr_node *node) { - TRACE_FUN(); + DEBUGF(); remove_default_node(node); _update_children(node->addr, NULL); @@ -155,7 +159,7 @@ static void _olsr_node_expired(struct olsr_node *node) static void _remove_olsr_node(struct olsr_node *node) { - TRACE_FUN(); + DEBUGF(); avl_remove(get_olsr_head(), &node->node); remove_free_node(node); @@ -205,7 +209,7 @@ static bool _route_expired(struct olsr_node *node, struct netaddr *last_addr) static void _update_link_quality(struct nhdp_node *node) { - TRACE_FUN("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); + DEBUGF("%s", netaddr_to_str_s(&nbuf[0], h1_super(node)->addr)); if (_route_expired(h1_super(node), get_local_addr())) { node->link_quality = node->link_quality * (1 - OLSR2_HYST_SCALING); @@ -443,10 +447,9 @@ void print_routing_graph(void) {} void print_topology_set(void) { -#ifndef ENABLE_DEBUG_OLSR - struct netaddr_str nbuf[3]; +#ifndef ENABLE_DEBUG + struct netaddr_str nbuf[3]; #endif - struct alt_route *route; struct olsr_node *node; diff --git a/sys/net/routing/olsr2/olsr_debug.h b/sys/net/routing/olsr2/olsr_debug.h deleted file mode 100644 index 7aed558dec8b..000000000000 --- a/sys/net/routing/olsr2/olsr_debug.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2014 Freie Universität Berlin - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for more - * details. - * - * @ingroup olsr2 - * @{ - * @author Benjamin Valentin - * @} - */ - -#ifndef OLSR2_DEBUG_H_ -#define OLSR2_DEBUG_H_ - -#ifdef ENABLE_DEBUG_OLSR -#ifndef RIOT -#include -#include -#endif /* not RIOT */ -#include -#include -#include "common/netaddr.h" - -struct netaddr_str nbuf[4]; -int debug_ticks; - -#define DEBUG_TICK debug_ticks++ - -#ifdef RIOT -#define DEBUG(fmt, ...) printf((fmt "\n"), ##__VA_ARGS__) -#define TRACE_FUN(fmt, ...) printf(("%s(" fmt ")\n"), __FUNCTION__, ##__VA_ARGS__) - -#else - -time_t _t_tmr; -char _t_buf[9]; -#define DEBUG(fmt, ...) { \ - _t_tmr = time_now(); \ - strftime(_t_buf, sizeof _t_buf, "%H:%M:%S", localtime(&_t_tmr)); \ - printf(("[%d, %s] " fmt "\n"), debug_ticks, _t_buf, ##__VA_ARGS__); \ - } - -#define TRACE_FUN(fmt, ...) { \ - _t_tmr = time_now(); \ - strftime(_t_buf, sizeof _t_buf, "%H:%M:%S", localtime(&_t_tmr)); \ - printf(("[%d, %s] %s(" fmt ")\n"), debug_ticks, _t_buf, __FUNCTION__, ##__VA_ARGS__); \ - } - -static inline void print_trace(void) -{ - void *array[10]; - size_t size; - char **strings; - size_t i; - - size = backtrace(array, 10); - strings = backtrace_symbols(array, size); - - printf("Obtained %zd stack frames.\n", size); - - for (i = 0; i < size; i++) { - printf("%s\n", strings[i]); - } - - free(strings); -} - -#endif /* not RIOT */ - -#else /* no ENABLE_DEBUG_OLSR */ - -#define DEBUG(...) -#define DEBUG_TICK -#define TRACE_FUN(...) - -#endif -#endif diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 4ee25c1a4033..f81e37870c03 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -33,7 +33,7 @@ #include "rfc5444/rfc5444_writer.h" #include "constants.h" -#include "olsr_debug.h" +#include "debug.h" #include "node.h" #include "olsr.h" #include "reader.h" @@ -41,6 +41,10 @@ #include +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[1]; +#endif + static char receive_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; static char sender_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 32426bdb53e1..bd0cd764e8df 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -20,11 +20,15 @@ #include "rfc5444/rfc5444_iana.h" #include "rfc5444/rfc5444_reader.h" +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[1]; +#endif + #ifdef RIOT #include "net_help.h" #endif -#include "olsr_debug.h" +#include "debug.h" #include "nhdp.h" #include "olsr.h" #include "reader.h" diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index 77672a4ee9db..0a1e9ca267f3 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -14,9 +14,13 @@ #include #include +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[3]; +#endif + #include "olsr.h" #include -#include "olsr_debug.h" +#include "debug.h" #include "util.h" #include "routing.h" #include "constants.h" diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index f8eea7175c91..2099b1fc2e4a 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -21,10 +21,14 @@ #include #endif +#ifdef ENABLE_DEBUG +struct netaddr_str nbuf[1]; +#endif + #include "constants.h" #include "util.h" #include "node.h" -#include "olsr_debug.h" +#include "debug.h" const char *netaddr_to_str_s(struct netaddr_str *dst, const struct netaddr *src) { diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index 15187f18c7d8..7b71c2358dfd 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -30,7 +30,7 @@ #include "writer.h" #include "nhdp.h" #include "olsr.h" -#include "olsr_debug.h" +#include "debug.h" #include "routing.h" uint8_t msg_buffer[256]; From eb29e39bc44d0de521d7e9ac63ed1944980f1321 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 2 Sep 2014 16:18:19 +0200 Subject: [PATCH 27/48] [slist] explicit check for NULL --- sys/slist/slist.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/slist/slist.c b/sys/slist/slist.c index 7c1951cb2d4d..884f987bddb2 100644 --- a/sys/slist/slist.c +++ b/sys/slist/slist.c @@ -29,12 +29,12 @@ void *__simple_list_add_tail(struct simple_list_elem **head, void *mem) return NULL; } - if (!_head) { + if (_head == NULL) { *head = mem; return *head; } - while (_head->next) { + while (_head->next != NULL) { _head = _head->next; } @@ -67,16 +67,16 @@ void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int ne return NULL; } - if (!_head) { + if (_head == NULL) { *head = mem; return *head; } - while (_head) { + while (_head != NULL) { int *buff = (void *) _head + offset; if (*buff > needle) { - if (prev) { + if (prev != NULL) { prev->next = mem; prev->next->next = _head; return prev->next; @@ -98,7 +98,7 @@ void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int ne void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size) { - while (head) { + while (head != NULL) { void **buff = (void *) head + offset; if (size == 0 && *buff == needle) { @@ -117,7 +117,7 @@ void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)) { - while (head) { + while (head != NULL) { void **buff = (void *) head + offset; if (compare(*buff, needle) == 0) { @@ -135,7 +135,7 @@ void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_el struct simple_list_elem *_head = *head; struct simple_list_elem *prev = 0; - while (_head && _head != node) { + while (_head != NULL && _head != node) { prev = _head; _head = _head->next; } @@ -146,7 +146,7 @@ void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_el } /* remove head */ - if (!prev) { + if (prev == NULL) { *head = _head->next; } else { From 4196a4d0adcc644aa3510e97e1b4589122e69e08 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 2 Sep 2014 16:18:56 +0200 Subject: [PATCH 28/48] explicit check for NULL --- sys/net/routing/olsr2/routing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing.c index 0a1e9ca267f3..4e5fab5db8d1 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing.c @@ -83,7 +83,7 @@ void fill_routing_table(void) struct free_node *fn; bool noop = false; /* when in an iteration there was nothing removed from free nodes */ - while (head && !noop) { + while (head != NULL && !noop) { noop = true; /* if no nodes could be removed in an iteration, abort */ struct free_node *prev; char skipped; From b2f6c02a8511b341f7deaafcc3b6ac7c303b7f1e Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 2 Sep 2014 21:53:53 +0200 Subject: [PATCH 29/48] style fixes --- sys/include/slist.h | 29 +++++++++++++++-------------- sys/net/routing/olsr2/constants.h | 16 ++++++++-------- sys/net/routing/olsr2/nhdp.c | 3 ++- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/sys/include/slist.h b/sys/include/slist.h index 5a1857f5410a..8194129e3708 100644 --- a/sys/include/slist.h +++ b/sys/include/slist.h @@ -169,11 +169,11 @@ struct simple_list_elem; * @param prev internal variable, pointer to previous list entry - do not modify * @param skipped internal variable, integer - do not modify */ -#define simple_list_for_each_safe(head, node, prev, skipped) \ - for ((skipped) = 0, (prev) = 0, (node) = (head);\ - (node); \ - (prev) = ((skipped) ? (prev) : (node)), \ - (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) +#define simple_list_for_each_safe(head, node, prev, skipped) \ + for ((skipped) = 0, (prev) = 0, (node) = (head); \ + (node); \ + (prev) = ((skipped) ? (prev) : (node)), \ + (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) /** * @brief removes an element in a simple_list_for_each_safe context @@ -182,15 +182,16 @@ struct simple_list_elem; * @param node pointer to the current entry (loop variable) * @param prev internal variable, provided by simple_list_for_each_safe */ -#define simple_list_for_each_remove(head, node, prev) do { \ - if (!prev) { \ - (skipped) = 1; \ - *(head) = (*(head))->next; \ - } else \ - (prev)->next = (node)->next; \ - free(node); \ - (node) = (prev) ? (prev) : *(head); \ - } while (0) +#define simple_list_for_each_remove(head, node, prev) do { \ + if (!prev) { \ + (skipped) = 1; \ + *(head) = (*(head))->next; \ + } else { \ + (prev)->next = (node)->next; \ + } \ + free(node); \ + (node) = (prev) ? (prev) : *(head); \ + } while (0) void *__simple_list_add_head(struct simple_list_elem **head, void *mem); void *__simple_list_add_tail(struct simple_list_elem **head, void *mem); diff --git a/sys/net/routing/olsr2/constants.h b/sys/net/routing/olsr2/constants.h index 9f6adcf012cb..3145778a3482 100644 --- a/sys/net/routing/olsr2/constants.h +++ b/sys/net/routing/olsr2/constants.h @@ -39,18 +39,18 @@ /* NHDP message TLV array index */ enum { - IDX_TLV_ITIME, /* Interval time */ - IDX_TLV_VTIME, /* validity time */ - IDX_TLV_NODE_NAME, /* name of the node */ + IDX_TLV_ITIME, /* Interval time */ + IDX_TLV_VTIME, /* validity time */ + IDX_TLV_NODE_NAME, /* name of the node */ }; /* NHDP address TLV array index */ enum { - IDX_ADDRTLV_LOCAL_IF, /* is local if */ - IDX_ADDRTLV_LINK_STATUS, /* link status TODO */ - IDX_ADDRTLV_MPR, /* neighbor selected as mpr */ - IDX_ADDRTLV_METRIC, /* incomming link metric */ - IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ + IDX_ADDRTLV_LOCAL_IF, /* is local if */ + IDX_ADDRTLV_LINK_STATUS, /* link status TODO */ + IDX_ADDRTLV_MPR, /* neighbor selected as mpr */ + IDX_ADDRTLV_METRIC, /* incomming link metric */ + IDX_ADDRTLV_NODE_NAME, /* 'name' of a node from graph.gv */ }; #endif /* OLSR2_CONSTANTS_H_ */ diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 2b1eca9d5600..9150645613a3 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -39,7 +39,7 @@ static struct olsr_node *_node_replace(struct olsr_node *old_n) bool _free_node = remove_free_node(old_n); memcpy(new_n, old_n, sizeof(struct olsr_node)); - memset(&new_n->node, 0, sizeof(new_n->node)); // just to be sure + memset(&new_n->node, 0, sizeof(new_n->node)); new_n->type = NODE_TYPE_NHDP; new_n->node.key = new_n->addr; @@ -81,6 +81,7 @@ struct olsr_node *olsr2_add_neighbor(struct netaddr *addr, metric_t metric, uint n->link_metric = metric; h1_deriv(n)->link_quality = OLSR2_HYST_SCALING; n->pending = 1; + #ifdef ENABLE_NAME if (name != NULL) { From 97eaa4a751c0c96e63df00ca6560129eee6c1575 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 2 Sep 2014 22:22:55 +0200 Subject: [PATCH 30/48] use cpuid_get() when availiable --- examples/olsr2/Makefile | 9 +++------ examples/olsr2/main.c | 22 +++++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/examples/olsr2/Makefile b/examples/olsr2/Makefile index cc385e1b060d..6d7333ae0fd7 100644 --- a/examples/olsr2/Makefile +++ b/examples/olsr2/Makefile @@ -22,12 +22,9 @@ USEMODULE += config USEMODULE += olsr2 USEMODULE += defaulttransceiver -# on native, use PID as node ID -ifeq ($(BOARD),native) - export CFLAGS += -DUSE_PID -endif -ifeq ($(BOARD),msba2) - export CFLAGS += -DENABLE_LEDS +# on msba2 and avsextrem cpuid_get is not implemented +ifneq (,$(filter $(BOARD), msba2 avsextrem)) + export CFLAGS += -DENABLE_LEDS -DHAVE_NO_CPUID endif include $(RIOTBASE)/Makefile.include diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c index 8e82d3d56e03..f02c6d101fc3 100644 --- a/examples/olsr2/main.c +++ b/examples/olsr2/main.c @@ -26,19 +26,23 @@ #define IF_ID (0) -#if defined(USE_PID) -#include -#include -static uint16_t get_node_id(void) { - return getpid(); -} -#else +#ifdef HAVE_NO_CPUID #include -static uint16_t get_node_id(void) { +static uint32_t get_node_id(void) { return sysconfig.id; } -#endif + +#else /* CPU ID availiable */ +#include "cpu-conf.h" + +static uint32_t get_node_id(void) { + uint32_t cpuid = 0; + cpuid_get(&cpuid); + return cpuid; +} + +#endif /* get_node_id */ #ifdef ENABLE_NAME From dc53b2fcde891da69eed69cb09d2dcbf9ec98473 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 2 Sep 2014 23:45:24 +0200 Subject: [PATCH 31/48] slist cleanup part 1 --- sys/include/slist.h | 28 ++++++++++++++-------------- sys/slist/slist.c | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/sys/include/slist.h b/sys/include/slist.h index 8194129e3708..47142005151f 100644 --- a/sys/include/slist.h +++ b/sys/include/slist.h @@ -76,8 +76,8 @@ struct simple_list_elem; * has to be the same name as the element in the list entry structure that is be used for comparison * @return pointer to the new element, NULL if no new list element could be allocated */ -#define simple_list_add_before(head, value) *(head) == 0 ? simple_list_add_head((head)) : \ - __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), value, (void*) &(*(head))->value - (void*) *(head)) +#define simple_list_add_before(head, value) *(head) == NULL ? simple_list_add_head((head)) : \ + __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), (value), (char*) &(*(head))->value - (char*) *(head)) /** * @brief adds an preallocated list element before an existing one. @@ -89,8 +89,8 @@ struct simple_list_elem; * @param node preallocated list element * @return the new list entry (node) */ -#define simple_list_set_before(head, node, value) *(head) == 0 ? simple_list_set_head((head), (node)) : \ - __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (void*) &(*(head))->value - (void*) *(head)) +#define simple_list_set_before(head, node, value) *(head) == NULL ? simple_list_set_head((head), (node)) : \ + __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (char*) &(*(head))->value - (char*) *(head)) /** * @brief searches for a list element by simple comparison of a struct value @@ -100,8 +100,8 @@ struct simple_list_elem; * has to be the same name as the value in the list element struct * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find(head, value) (head) == 0 ? NULL : \ - __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), 0) +#define simple_list_find(head, value) (head) == NULL ? NULL : \ + __simple_list_find((struct simple_list_elem*) (head), (value), (char*) &((head)->value) - (char*) (head), 0) /** * @brief searches for a list element by comparing a buffer in the list element struct @@ -111,8 +111,8 @@ struct simple_list_elem; * has to be the same name as the value in the list element struct * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find_memcmp(head, value) (head) == 0 ? NULL : \ - __simple_list_find((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), sizeof(*(value))) +#define simple_list_find_memcmp(head, value) (head) == NULL ? NULL : \ + __simple_list_find((struct simple_list_elem*) (head), (value), (char*) &((head)->value) - (char*) (head), sizeof(*(value))) /** * @brief searches for a list element by applying a comparator function to each list entry @@ -122,8 +122,8 @@ struct simple_list_elem; * @param comperator a function that takes (value, node) and returns 0 if they match * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find_cmp(head, value, comperator) (head) == 0 ? NULL : \ - __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (void*) &((head)->value) - (void*) (head), (comperator)) +#define simple_list_find_cmp(head, value, comperator) (head) == NULL ? NULL : \ + __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (char*) &((head)->value) - (char*) (head), (comperator)) /** * @brief removes an entry from the list and frees it's memory @@ -170,7 +170,7 @@ struct simple_list_elem; * @param skipped internal variable, integer - do not modify */ #define simple_list_for_each_safe(head, node, prev, skipped) \ - for ((skipped) = 0, (prev) = 0, (node) = (head); \ + for ((skipped) = 0, (prev) = NULL, (node) = (head); \ (node); \ (prev) = ((skipped) ? (prev) : (node)), \ (node) = ((skipped) ? (node) : (node)->next), (skipped) = 0) @@ -195,9 +195,9 @@ struct simple_list_elem; void *__simple_list_add_head(struct simple_list_elem **head, void *mem); void *__simple_list_add_tail(struct simple_list_elem **head, void *mem); -void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset); -void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size); -void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)); +void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, size_t offset); +void *__simple_list_find(struct simple_list_elem *head, void *needle, size_t offset, size_t size); +void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, size_t offset, int compare(void *, void *)); void *__simple_list_remove(struct simple_list_elem **head, struct simple_list_elem *node, int keep); void __simple_list_clear(struct simple_list_elem **head); diff --git a/sys/slist/slist.c b/sys/slist/slist.c index 884f987bddb2..f4ce8817eb20 100644 --- a/sys/slist/slist.c +++ b/sys/slist/slist.c @@ -57,7 +57,7 @@ void *__simple_list_add_head(struct simple_list_elem **head, void *mem) return *head; } -void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, int offset) +void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int needle, size_t offset) { struct simple_list_elem *_head = *head; struct simple_list_elem *prev = 0; @@ -73,7 +73,7 @@ void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int ne } while (_head != NULL) { - int *buff = (void *) _head + offset; + int *buff = (void *) ((char *) _head + offset); if (*buff > needle) { if (prev != NULL) { @@ -96,10 +96,10 @@ void *__simple_list_add_before(struct simple_list_elem **head, void *mem, int ne return _head; } -void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset, size_t size) +void *__simple_list_find(struct simple_list_elem *head, void *needle, size_t offset, size_t size) { while (head != NULL) { - void **buff = (void *) head + offset; + void **buff = (void *) ((char *) head + offset); if (size == 0 && *buff == needle) { return head; @@ -115,10 +115,10 @@ void *__simple_list_find(struct simple_list_elem *head, void *needle, int offset return 0; } -void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, int offset, int compare(void *, void *)) +void *__simple_list_find_cmp(struct simple_list_elem *head, void *needle, size_t offset, int compare(void *, void *)) { while (head != NULL) { - void **buff = (void *) head + offset; + void **buff = (void *) ((char *) head + offset); if (compare(*buff, needle) == 0) { return head; From d482de8d37893c7b658bb2c14244a9e46678be07 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 3 Sep 2014 16:04:16 +0200 Subject: [PATCH 32/48] slist cleanup pt2 --- sys/include/slist.h | 86 +++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/sys/include/slist.h b/sys/include/slist.h index 47142005151f..f1e7d3ba9f5e 100644 --- a/sys/include/slist.h +++ b/sys/include/slist.h @@ -36,7 +36,7 @@ struct simple_list_elem; * @param head pointer to the list * @return the new list entry, NULL if no new list entry could be allocated */ -#define simple_list_add_head(head) __simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) +#define simple_list_add_head(head) __simple_list_add_head((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) /** @@ -46,7 +46,7 @@ struct simple_list_elem; * @param node preallocated list element * @return the new list entry (node) */ -#define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) head, node) +#define simple_list_set_head(head, node) __simple_list_add_head((struct simple_list_elem**) (head), (node)) /** * @brief allocates memory for a new list entry and appends it at the end of the list. @@ -55,7 +55,7 @@ struct simple_list_elem; * @param head pointer to the list * @return the new list entry, NULL if no new list entry could be allocated */ -#define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) +#define simple_list_add_tail(head) __simple_list_add_tail((struct simple_list_elem**) (head), calloc(1, sizeof **(head))) /** * @brief appends a preallocated element to the end of the list. @@ -64,7 +64,7 @@ struct simple_list_elem; * @param node preallocated list element * @return the new list entry (node) */ -#define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) +#define simple_list_set_tail(head, node) __simple_list_add_tail((struct simple_list_elem**) (head), (node)) /** * @brief allocates memory for a new list entry and adds it before an existing entry. @@ -76,8 +76,14 @@ struct simple_list_elem; * has to be the same name as the element in the list entry structure that is be used for comparison * @return pointer to the new element, NULL if no new list element could be allocated */ -#define simple_list_add_before(head, value) *(head) == NULL ? simple_list_add_head((head)) : \ - __simple_list_add_before((struct simple_list_elem**) (head), calloc(1, sizeof **(head)), (value), (char*) &(*(head))->value - (char*) *(head)) +#define simple_list_add_before(head, value) \ + *(head) == NULL ? \ + simple_list_add_head((head)) \ + : \ + __simple_list_add_before((struct simple_list_elem**) (head), \ + calloc(1, sizeof **(head)), \ + (value), \ + (char*) &(*(head))->value - (char*) *(head)) \ /** * @brief adds an preallocated list element before an existing one. @@ -89,8 +95,14 @@ struct simple_list_elem; * @param node preallocated list element * @return the new list entry (node) */ -#define simple_list_set_before(head, node, value) *(head) == NULL ? simple_list_set_head((head), (node)) : \ - __simple_list_add_before((struct simple_list_elem**) (head), (node), (value), (char*) &(*(head))->value - (char*) *(head)) +#define simple_list_set_before(head, node, value) \ + *(head) == NULL ? \ + __simple_list_add_before((head)) \ + : \ + __simple_list_add_before((struct simple_list_elem**) (head), \ + (node), \ + (value), \ + (char*) &(*(head))->value - (char*) *(head)) \ /** * @brief searches for a list element by simple comparison of a struct value @@ -100,8 +112,14 @@ struct simple_list_elem; * has to be the same name as the value in the list element struct * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find(head, value) (head) == NULL ? NULL : \ - __simple_list_find((struct simple_list_elem*) (head), (value), (char*) &((head)->value) - (char*) (head), 0) +#define simple_list_find(head, value) \ + (head) == NULL ? \ + NULL \ + : \ + __simple_list_find( (struct simple_list_elem*) (head), \ + (value), \ + (char*) &((head)->value) - (char*) (head), \ + (0)) \ /** * @brief searches for a list element by comparing a buffer in the list element struct @@ -111,8 +129,14 @@ struct simple_list_elem; * has to be the same name as the value in the list element struct * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find_memcmp(head, value) (head) == NULL ? NULL : \ - __simple_list_find((struct simple_list_elem*) (head), (value), (char*) &((head)->value) - (char*) (head), sizeof(*(value))) +#define simple_list_find_memcmp(head, value) \ + (head) == NULL ? \ + NULL \ + : \ + __simple_list_find( (struct simple_list_elem*) (head), \ + (value), \ + (char*) &((head)->value) - (char*) (head), \ + sizeof(*(value))) /** * @brief searches for a list element by applying a comparator function to each list entry @@ -122,8 +146,14 @@ struct simple_list_elem; * @param comperator a function that takes (value, node) and returns 0 if they match * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find_cmp(head, value, comperator) (head) == NULL ? NULL : \ - __simple_list_find_cmp((struct simple_list_elem*) (head), (value), (char*) &((head)->value) - (char*) (head), (comperator)) +#define simple_list_find_cmp(head, value, comperator) \ + (head) == NULL ? \ + NULL \ + : \ + __simple_list_find_cmp( (struct simple_list_elem*) (head), \ + (value), \ + (char*) &((head)->value) - (char*) (head), \ + (comperator)) /** * @brief removes an entry from the list and frees it's memory @@ -132,7 +162,7 @@ struct simple_list_elem; * @param node entry to be removed * @returns a non-zero value if the element was found and removed */ -#define simple_list_remove(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) +#define simple_list_remove(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 0) /** * @brief removes an entry from the list, doesn't free it's memory but returns the element @@ -141,14 +171,14 @@ struct simple_list_elem; * @param node entry to be extracted * @returns pointer to the element, NULL if it couldn't be found */ -#define simple_list_extract(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) +#define simple_list_extract(head, node) __simple_list_remove((struct simple_list_elem**) (head), (struct simple_list_elem*) (node), 1) /** * @brief removes all entries from the list and frees their memory * * @param head pointer to the list */ -#define simple_list_clear(head) __simple_list_clear((struct simple_list_elem**) (head)) +#define simple_list_clear(head) __simple_list_clear((struct simple_list_elem**) (head)) /** * @brief starts a loop to iterate over all list entries. Read-only list access only. @@ -157,7 +187,8 @@ struct simple_list_elem; * @param head pointer to the list * @param node to the current entry (loop variable) */ -#define simple_list_for_each(head, node) for ((node) = (head); (node); (node) = (node)->next) +#define simple_list_for_each(head, node) \ + for ((node) = (head); (node); (node) = (node)->next) /** * @brief starts a loop to iterate over all list elements with the possibility to remove elements @@ -182,15 +213,16 @@ struct simple_list_elem; * @param node pointer to the current entry (loop variable) * @param prev internal variable, provided by simple_list_for_each_safe */ -#define simple_list_for_each_remove(head, node, prev) do { \ - if (!prev) { \ - (skipped) = 1; \ - *(head) = (*(head))->next; \ - } else { \ - (prev)->next = (node)->next; \ - } \ - free(node); \ - (node) = (prev) ? (prev) : *(head); \ +#define simple_list_for_each_remove(head, node, prev) \ + do { \ + if (!(prev)) { \ + (skipped) = 1; \ + *(head) = (*(head))->next; \ + } else { \ + (prev)->next = (node)->next; \ + } \ + free(node); \ + (node) = (prev) ? (prev) : *(head); \ } while (0) void *__simple_list_add_head(struct simple_list_elem **head, void *mem); From 9a04eade3c8359f636f3205e6565698a4b660d40 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 3 Sep 2014 23:53:02 +0200 Subject: [PATCH 33/48] slist cleanup pt3 --- sys/include/slist.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sys/include/slist.h b/sys/include/slist.h index f1e7d3ba9f5e..a523d6e2d832 100644 --- a/sys/include/slist.h +++ b/sys/include/slist.h @@ -76,14 +76,14 @@ struct simple_list_elem; * has to be the same name as the element in the list entry structure that is be used for comparison * @return pointer to the new element, NULL if no new list element could be allocated */ -#define simple_list_add_before(head, value) \ +#define simple_list_add_before(head, value) (\ *(head) == NULL ? \ simple_list_add_head((head)) \ : \ __simple_list_add_before((struct simple_list_elem**) (head), \ calloc(1, sizeof **(head)), \ (value), \ - (char*) &(*(head))->value - (char*) *(head)) \ + (char*) &(*(head))->value - (char*) *(head)) ) /** * @brief adds an preallocated list element before an existing one. @@ -95,14 +95,14 @@ struct simple_list_elem; * @param node preallocated list element * @return the new list entry (node) */ -#define simple_list_set_before(head, node, value) \ +#define simple_list_set_before(head, node, value) (\ *(head) == NULL ? \ __simple_list_add_before((head)) \ : \ __simple_list_add_before((struct simple_list_elem**) (head), \ (node), \ (value), \ - (char*) &(*(head))->value - (char*) *(head)) \ + (char*) &(*(head))->value - (char*) *(head)) ) /** * @brief searches for a list element by simple comparison of a struct value @@ -112,14 +112,14 @@ struct simple_list_elem; * has to be the same name as the value in the list element struct * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find(head, value) \ +#define simple_list_find(head, value) (\ (head) == NULL ? \ NULL \ : \ __simple_list_find( (struct simple_list_elem*) (head), \ (value), \ (char*) &((head)->value) - (char*) (head), \ - (0)) \ + (0)) ) /** * @brief searches for a list element by comparing a buffer in the list element struct @@ -129,14 +129,14 @@ struct simple_list_elem; * has to be the same name as the value in the list element struct * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find_memcmp(head, value) \ +#define simple_list_find_memcmp(head, value) (\ (head) == NULL ? \ NULL \ : \ __simple_list_find( (struct simple_list_elem*) (head), \ (value), \ (char*) &((head)->value) - (char*) (head), \ - sizeof(*(value))) + sizeof(*(value))) ) /** * @brief searches for a list element by applying a comparator function to each list entry @@ -146,15 +146,14 @@ struct simple_list_elem; * @param comperator a function that takes (value, node) and returns 0 if they match * @return pointer the list entry if found, otherwise NULL */ -#define simple_list_find_cmp(head, value, comperator) \ +#define simple_list_find_cmp(head, value, comperator) (\ (head) == NULL ? \ NULL \ : \ __simple_list_find_cmp( (struct simple_list_elem*) (head), \ (value), \ (char*) &((head)->value) - (char*) (head), \ - (comperator)) - + (comperator)) ) /** * @brief removes an entry from the list and frees it's memory * From c9b2f5a1ab03912f6c7a51ae175172d04c64d407 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 7 Oct 2014 01:49:00 +0200 Subject: [PATCH 34/48] adapt to net api change --- Makefile.dep | 3 ++- examples/olsr2/main.c | 2 +- sys/net/routing/olsr2/olsr_init.c | 13 ++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.dep b/Makefile.dep index fc98313728e6..6f1d5323c55d 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -4,7 +4,8 @@ endif ifneq (,$(filter olsr2,$(USEMODULE))) USEMODULE += vtimer - USEMODULE += destiny + USEMODULE += socket_base + USEMODULE += udp USEMODULE += sixlowpan USEMODULE += slist USEMODULE += oonf_common diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c index f02c6d101fc3..815e9f3b482e 100644 --- a/examples/olsr2/main.c +++ b/examples/olsr2/main.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index f81e37870c03..e4d0a6d923cb 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -19,13 +19,12 @@ #include #include #include -#include +#include #include #include #include #include #include -#include #include #include #include @@ -82,7 +81,7 @@ static void write_packet(struct rfc5444_writer *wr __attribute__((unused)), #ifdef ENABLE_LEDS LED_GREEN_TOGGLE; #endif - int bytes_send = destiny_socket_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); + int bytes_send = socket_base_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); DEBUG("write_packet(%d bytes), %d bytes sent", length, bytes_send); } @@ -95,9 +94,9 @@ static void olsr_receiver_thread(void) sa.sin6_family = AF_INET6; sa.sin6_port = HTONS(MANET_PORT); - if (destiny_socket_bind(sock, &sa, sizeof sa) < 0) { + if (socket_base_bind(sock, &sa, sizeof sa) < 0) { printf("Error bind failed!\n"); - destiny_socket_close(sock); + socket_base_close(sock); } int32_t recsize; @@ -108,7 +107,7 @@ static void olsr_receiver_thread(void) _src._prefix_len = 128; while (1) { - recsize = destiny_socket_recvfrom(sock, &buffer, sizeof buffer, 0, &sa, &fromlen); + recsize = socket_base_recvfrom(sock, &buffer, sizeof buffer, 0, &sa, &fromlen); #ifdef ENABLE_LEDS LED_RED_TOGGLE; #endif @@ -193,7 +192,7 @@ void olsr_init(void) ipv6_addr_set_all_nodes_addr(&sa_bcast.sin6_addr); /* enable receive */ - sock = destiny_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + sock = socket_base_socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); thread_create(receive_thread_stack, sizeof receive_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_receiver_thread, NULL, "olsr_rec"); /* set get_local_addr() */ From ad03d1236411a64a6a06b6d9f9b8d89f68bd66d3 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 10 Oct 2014 01:30:17 +0200 Subject: [PATCH 35/48] routing.h -> routing_table.h --- sys/net/routing/olsr2/nhdp.c | 2 +- sys/net/routing/olsr2/olsr.c | 2 +- sys/net/routing/olsr2/reader.c | 2 +- sys/net/routing/olsr2/{routing.c => routing_table.c} | 2 +- sys/net/routing/olsr2/{routing.h => routing_table.h} | 0 sys/net/routing/olsr2/writer.c | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename sys/net/routing/olsr2/{routing.c => routing_table.c} (99%) rename sys/net/routing/olsr2/{routing.h => routing_table.h} (100%) diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 9150645613a3..2458dff95da3 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -17,7 +17,7 @@ #include "util.h" #include "debug.h" #include "node.h" -#include "routing.h" +#include "routing_table.h" #include "constants.h" #include "common/avl.h" diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 3d88056db53c..23da70a47a77 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -24,7 +24,7 @@ #include "olsr.h" #include "util.h" #include "debug.h" -#include "routing.h" +#include "routing_table.h" #include "constants.h" #include diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index bd0cd764e8df..44b3452e0502 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -34,7 +34,7 @@ struct netaddr_str nbuf[1]; #include "reader.h" #include "writer.h" #include "constants.h" -#include "routing.h" +#include "routing_table.h" static struct rfc5444_reader reader; static struct netaddr *current_src; diff --git a/sys/net/routing/olsr2/routing.c b/sys/net/routing/olsr2/routing_table.c similarity index 99% rename from sys/net/routing/olsr2/routing.c rename to sys/net/routing/olsr2/routing_table.c index 4e5fab5db8d1..252cb7cb2943 100644 --- a/sys/net/routing/olsr2/routing.c +++ b/sys/net/routing/olsr2/routing_table.c @@ -22,7 +22,7 @@ struct netaddr_str nbuf[3]; #include #include "debug.h" #include "util.h" -#include "routing.h" +#include "routing_table.h" #include "constants.h" #include "rfc5444/rfc5444.h" diff --git a/sys/net/routing/olsr2/routing.h b/sys/net/routing/olsr2/routing_table.h similarity index 100% rename from sys/net/routing/olsr2/routing.h rename to sys/net/routing/olsr2/routing_table.h diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index 7b71c2358dfd..94de61e7c096 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -31,7 +31,7 @@ #include "nhdp.h" #include "olsr.h" #include "debug.h" -#include "routing.h" +#include "routing_table.h" uint8_t msg_buffer[256]; uint8_t msg_addrtlvs[512]; From ad42160b7907ccf2993816037b348eef6895ca61 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 10 Oct 2014 01:32:12 +0200 Subject: [PATCH 36/48] introduce new Makefile options --- examples/olsr2/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/olsr2/Makefile b/examples/olsr2/Makefile index 6d7333ae0fd7..98099c878855 100644 --- a/examples/olsr2/Makefile +++ b/examples/olsr2/Makefile @@ -6,6 +6,14 @@ export RIOTBASE ?= $(CURDIR)/../.. # other toolchains lack assert.h used by oonf_api BOARD_WHITELIST := avsextrem msba2 native +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +CFLAGS += -DDEVELHELP + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + USEPKG += oonf_api export CFLAGS = -DRIOT -DENABLE_NAME From cc25083b9d2475e6978b4a5b1f95a118dc50a9af Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 10 Oct 2014 02:00:41 +0200 Subject: [PATCH 37/48] silence warnings --- examples/olsr2/main.c | 8 ++++++-- sys/net/routing/olsr2/olsr_init.c | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c index 815e9f3b482e..3c656dea6df5 100644 --- a/examples/olsr2/main.c +++ b/examples/olsr2/main.c @@ -34,7 +34,7 @@ static uint32_t get_node_id(void) { } #else /* CPU ID availiable */ -#include "cpu-conf.h" +#include static uint32_t get_node_id(void) { uint32_t cpuid = 0; @@ -93,6 +93,10 @@ static void set_id(int argc, char **argv) { config_save(); } +static void print_routes(__attribute__((unused)) int argc, __attribute__((unused)) char **argv) { + print_topology_set(); +} + static void init(void) { ipv6_addr_t tmp; @@ -115,7 +119,7 @@ static void init(void) { } const shell_command_t shell_commands[] = { - {"routes", "print all known nodes and routes", print_topology_set}, + {"routes", "print all known nodes and routes", print_routes}, {"set_id", "set node ID and name", set_id}, #ifdef ENABLE_NAME {"ping", "send packets to a node", ping}, diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index e4d0a6d923cb..985e5d00f172 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -53,8 +53,8 @@ struct timer_msg { void (*func)(void); }; -static struct timer_msg msg_hello = { .timer = {0}, .interval = { .seconds = OLSR2_HELLO_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_hello }; -static struct timer_msg msg_tc = { .timer = {0}, .interval = { .seconds = OLSR2_TC_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_tc }; +static struct timer_msg msg_hello = { .interval = { .seconds = OLSR2_HELLO_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_hello }; +static struct timer_msg msg_tc = { .interval = { .seconds = OLSR2_TC_REFRESH_INTERVAL_SECONDS - 1, .microseconds = 0}, .func = writer_send_tc }; static int sock; static sockaddr6_t sa_bcast; @@ -64,7 +64,7 @@ static mutex_t olsr_data; static char _name[5]; static char *gen_name(char *dest, const size_t len) { - for (int i = 0; i < len - 1; ++i) { + for (unsigned int i = 0; i < len - 1; ++i) { dest[i] = 'A' + (genrand_uint32() % ('Z' - 'A')); } @@ -81,12 +81,15 @@ static void write_packet(struct rfc5444_writer *wr __attribute__((unused)), #ifdef ENABLE_LEDS LED_GREEN_TOGGLE; #endif - int bytes_send = socket_base_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); +#ifdef ENABLE_DEBUG + int bytes_send = +#endif + socket_base_sendto(sock, buffer, length, 0, &sa_bcast, sizeof sa_bcast); DEBUG("write_packet(%d bytes), %d bytes sent", length, bytes_send); } -static void olsr_receiver_thread(void) +static void* olsr_receiver_thread(void *ctx __attribute__((unused))) { char buffer[256]; @@ -118,9 +121,11 @@ static void olsr_receiver_thread(void) reader_handle_packet(&buffer, recsize, &_src, 1); // TODO: proper metric mutex_unlock(&olsr_data); } + + return NULL; } -static void olsr_sender_thread(void) +static void* olsr_sender_thread(void *ctx __attribute__((unused))) { DEBUG("olsr_sender_thread, pid %d\n", thread_getpid()); @@ -144,6 +149,7 @@ static void olsr_sender_thread(void) DEBUG("vtimer_set_msg failed, stopped sending"); } } + return NULL; } static ipv6_addr_t *get_next_hop(ipv6_addr_t *dest) From ca235e4b851c7af65115454eae527f1a4eb5001d Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 30 Oct 2014 18:48:43 +0100 Subject: [PATCH 38/48] fix merge conflict --- core/include/kernel_macros.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/include/kernel_macros.h b/core/include/kernel_macros.h index 8e75797906c3..40379e8ceb0d 100644 --- a/core/include/kernel_macros.h +++ b/core/include/kernel_macros.h @@ -16,6 +16,9 @@ * @author René Kijewski */ +#ifndef KERNEL_MACROS_ +#define KERNEL_MACROS_ + #include #ifdef __cplusplus @@ -35,6 +38,7 @@ extern "C" { * @param[in] MEMBER name of the member of TYPE which PTR points to * @return Pointer to the container of PTR. */ +#ifndef container_of #if __STDC_VERSION__ >= 201112L # define container_of(PTR, TYPE, MEMBER) \ (_Generic((PTR), \ @@ -53,11 +57,11 @@ extern "C" { # define container_of(PTR, TYPE, MEMBER) \ ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))) #endif - +#endif #ifdef __cplusplus } #endif - /** * @} */ +#endif /* KERNEL_MACROS_ */ From 605f3b9b2e5868d0915dda278bf9a2278f43eed3 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 10 Oct 2014 02:11:24 +0200 Subject: [PATCH 39/48] fix warnings in oonf_api --- ...y-define-container_of-when-necessary.patch | 29 +++++++++++++++++++ pkg/oonf_api/0006-if_index-is-not-used.patch | 25 ++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 pkg/oonf_api/0005-only-define-container_of-when-necessary.patch create mode 100644 pkg/oonf_api/0006-if_index-is-not-used.patch diff --git a/pkg/oonf_api/0005-only-define-container_of-when-necessary.patch b/pkg/oonf_api/0005-only-define-container_of-when-necessary.patch new file mode 100644 index 000000000000..56de15cee36b --- /dev/null +++ b/pkg/oonf_api/0005-only-define-container_of-when-necessary.patch @@ -0,0 +1,29 @@ +From d81d24b9d4c897c508799cb390b13cb018758709 Mon Sep 17 00:00:00 2001 +From: Benjamin Valentin +Date: Fri, 10 Oct 2014 02:05:01 +0200 +Subject: [PATCH] only define container_of when necessary + +--- + src-api/common/container_of.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src-api/common/container_of.h b/src-api/common/container_of.h +index 9fd1893..fcb38fe 100644 +--- a/src-api/common/container_of.h ++++ b/src-api/common/container_of.h +@@ -58,10 +58,12 @@ + * @param member name of node inside struct + * @return pointer to surrounding struct + */ ++#ifndef container_of + #define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member ) *__tempptr = (ptr); \ + (type *)((char *)__tempptr - offsetof(type,member)); \ + }) ++#endif + + /** + * Helper function for NULL safe container_of macro +-- +1.9.1 + diff --git a/pkg/oonf_api/0006-if_index-is-not-used.patch b/pkg/oonf_api/0006-if_index-is-not-used.patch new file mode 100644 index 000000000000..1a26ea7a3833 --- /dev/null +++ b/pkg/oonf_api/0006-if_index-is-not-used.patch @@ -0,0 +1,25 @@ +From 40651f114bd6e1b4b2ebc89bdf8fb06d1243eb55 Mon Sep 17 00:00:00 2001 +From: Benjamin Valentin +Date: Fri, 10 Oct 2014 02:08:32 +0200 +Subject: [PATCH] if_index is not used + +--- + src-api/common/netaddr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src-api/common/netaddr.c b/src-api/common/netaddr.c +index ed44341..fa528ca 100644 +--- a/src-api/common/netaddr.c ++++ b/src-api/common/netaddr.c +@@ -319,7 +319,7 @@ netaddr_create_host_bin(struct netaddr *host, const struct netaddr *netmask, + */ + int + netaddr_socket_init(union netaddr_socket *combined, const struct netaddr *addr, +- uint16_t port, unsigned if_index) { ++ uint16_t port, unsigned if_index __attribute__((unused))) { + /* initialize memory block */ + memset(combined, 0, sizeof(*combined)); + +-- +1.9.1 + From 68cc3580b57d4447ebdc9a7144843424ed484e46 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 10 Oct 2014 02:27:05 +0200 Subject: [PATCH 40/48] fix warning about printf type --- sys/net/routing/olsr2/olsr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 23da70a47a77..26f7866159b7 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -467,12 +467,12 @@ void print_topology_set(void) #ifdef ENABLE_NAME printf("(%s)", node->name); #endif - printf("\t=> %s; %d hops, metric: %d, next: %s (%d), %lds ", + printf("\t=> %s; %d hops, metric: %u, next: %s (%u), %lds ", netaddr_to_str_s(&nbuf[1], node->last_addr), node->distance, - node->path_metric, + (unsigned int) node->path_metric, netaddr_to_str_s(&nbuf[2], node->next_addr), - node->link_metric, + (unsigned int) node->link_metric, node->expires - time_now()); if (node->type == NODE_TYPE_NHDP) { @@ -495,9 +495,9 @@ void print_topology_set(void) puts(""); simple_list_for_each(node->other_routes, route) { - printf("\t\t\t=> %s (%d); %ld s\n", + printf("\t\t\t=> %s (%u); %ld s\n", netaddr_to_str_s(&nbuf[0], route->last_addr), - route->link_metric, + (unsigned int) route->link_metric, route->expires - time_now()); } } From a8e2b50838ced310afc82dbecb6aa0cbd68a68ee Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sat, 11 Oct 2014 02:41:38 +0200 Subject: [PATCH 41/48] explain IF_ID --- examples/olsr2/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c index 3c656dea6df5..006b806833e9 100644 --- a/examples/olsr2/main.c +++ b/examples/olsr2/main.c @@ -24,6 +24,7 @@ #include +/* Interface ID */ #define IF_ID (0) #ifdef HAVE_NO_CPUID From 1efb0f58088310967e76663c00713ce2ae299bbf Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Sat, 11 Oct 2014 02:44:07 +0200 Subject: [PATCH 42/48] make nbuf static --- sys/net/routing/olsr2/nhdp.c | 2 +- sys/net/routing/olsr2/node.c | 2 +- sys/net/routing/olsr2/olsr.c | 4 ++-- sys/net/routing/olsr2/olsr_init.c | 2 +- sys/net/routing/olsr2/reader.c | 2 +- sys/net/routing/olsr2/routing_table.c | 2 +- sys/net/routing/olsr2/util.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/net/routing/olsr2/nhdp.c b/sys/net/routing/olsr2/nhdp.c index 2458dff95da3..b452a12531e4 100644 --- a/sys/net/routing/olsr2/nhdp.c +++ b/sys/net/routing/olsr2/nhdp.c @@ -23,7 +23,7 @@ #include "common/avl.h" #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[1]; +static struct netaddr_str nbuf[1]; #endif static struct olsr_node *_node_replace(struct olsr_node *old_n) diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index 546d21eaa322..0f5801e30c9e 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -24,7 +24,7 @@ static struct netaddr_rc local_addr; static struct avl_tree olsr_head; #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[2]; +static struct netaddr_str nbuf[2]; #endif #ifdef ENABLE_NAME diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index 26f7866159b7..fa292fdbcc2c 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -29,7 +29,7 @@ #include #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[3]; +static struct netaddr_str nbuf[3]; #endif static struct olsr_node *_new_olsr_node(struct netaddr *addr, @@ -448,7 +448,7 @@ void print_routing_graph(void) {} void print_topology_set(void) { #ifndef ENABLE_DEBUG - struct netaddr_str nbuf[3]; + struct netaddr_str nbuf[3]; #endif struct alt_route *route; struct olsr_node *node; diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 985e5d00f172..098570b1a0d1 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -41,7 +41,7 @@ #include #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[1]; +static struct netaddr_str nbuf[1]; #endif static char receive_thread_stack[KERNEL_CONF_STACKSIZE_MAIN]; diff --git a/sys/net/routing/olsr2/reader.c b/sys/net/routing/olsr2/reader.c index 44b3452e0502..1533124a4b8e 100644 --- a/sys/net/routing/olsr2/reader.c +++ b/sys/net/routing/olsr2/reader.c @@ -21,7 +21,7 @@ #include "rfc5444/rfc5444_reader.h" #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[1]; +static struct netaddr_str nbuf[1]; #endif #ifdef RIOT diff --git a/sys/net/routing/olsr2/routing_table.c b/sys/net/routing/olsr2/routing_table.c index 252cb7cb2943..e7d632d68e96 100644 --- a/sys/net/routing/olsr2/routing_table.c +++ b/sys/net/routing/olsr2/routing_table.c @@ -15,7 +15,7 @@ #include #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[3]; +static struct netaddr_str nbuf[3]; #endif #include "olsr.h" diff --git a/sys/net/routing/olsr2/util.c b/sys/net/routing/olsr2/util.c index 2099b1fc2e4a..5eb63a2ec3b5 100644 --- a/sys/net/routing/olsr2/util.c +++ b/sys/net/routing/olsr2/util.c @@ -22,7 +22,7 @@ #endif #ifdef ENABLE_DEBUG -struct netaddr_str nbuf[1]; +static struct netaddr_str nbuf[1]; #endif #include "constants.h" From 173bd7d782044d7a68006d480c0f73fac57feab9 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 13 Oct 2014 04:56:17 +0200 Subject: [PATCH 43/48] prefix local_name --- sys/net/routing/olsr2/node.c | 2 +- sys/net/routing/olsr2/node.h | 3 ++- sys/net/routing/olsr2/olsr.c | 8 ++++---- sys/net/routing/olsr2/olsr_init.c | 6 +++--- sys/net/routing/olsr2/writer.c | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/sys/net/routing/olsr2/node.c b/sys/net/routing/olsr2/node.c index 0f5801e30c9e..1cec09030eef 100644 --- a/sys/net/routing/olsr2/node.c +++ b/sys/net/routing/olsr2/node.c @@ -28,7 +28,7 @@ static struct netaddr_str nbuf[2]; #endif #ifdef ENABLE_NAME -char *local_name; +char *olsr2_local_name; #endif static void _decrease_mpr_neigh(struct olsr_node *node) diff --git a/sys/net/routing/olsr2/node.h b/sys/net/routing/olsr2/node.h index d4375fcde1f3..9484f7fee035 100644 --- a/sys/net/routing/olsr2/node.h +++ b/sys/net/routing/olsr2/node.h @@ -19,8 +19,9 @@ #include "util.h" +/* nodes can have a name (hostname) for easier debugging */ #ifdef ENABLE_NAME -extern char *local_name; +extern char *olsr2_local_name; #endif /* if a connection is lost, the loss will be reported LOST_ITER_MAX times in HELLO and TC messages. */ diff --git a/sys/net/routing/olsr2/olsr.c b/sys/net/routing/olsr2/olsr.c index fa292fdbcc2c..bbb5bd61213a 100644 --- a/sys/net/routing/olsr2/olsr.c +++ b/sys/net/routing/olsr2/olsr.c @@ -411,7 +411,7 @@ void print_routing_graph(void) avl_for_each_element(get_olsr_head(), node, node) { if (node->addr != NULL && node->last_addr != NULL) { tmp = get_node(node->last_addr); - printf("\t%s -> %s\n", tmp ? tmp->name : local_name, node->name); + printf("\t%s -> %s\n", tmp ? tmp->name : olsr2_local_name, node->name); } } puts("}"); @@ -421,7 +421,7 @@ void print_routing_graph(void) puts("// BEGIN FLOODING MPR"); avl_for_each_element(get_olsr_head(), node, node) { if (node->type == NODE_TYPE_NHDP && h1_deriv(node)->mpr_slctr_flood) { - printf("\t%s -> %s\n", node->name, local_name); + printf("\t%s -> %s\n", node->name, olsr2_local_name); } } puts("// END FLOODING MPR"); @@ -432,7 +432,7 @@ void print_routing_graph(void) puts("// BEGIN ROUTING MPR"); avl_for_each_element(get_olsr_head(), node, node) { if (node->distance == 1 && h1_deriv(node)->mpr_slctr_route) { - printf("\t%s -> %s\n", node->name, local_name); + printf("\t%s -> %s\n", node->name, olsr2_local_name); } } puts("// END ROUTING MPR"); @@ -456,7 +456,7 @@ void print_topology_set(void) puts(""); puts("---[ Topology Set ]--"); #ifdef ENABLE_NAME - printf(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), local_name); + printf(" [ %s | %s ]\n", netaddr_to_str_s(&nbuf[0], get_local_addr()), olsr2_local_name); #else printf(" [%s]\n", netaddr_to_str_s(&nbuf[0], get_local_addr())); #endif diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 098570b1a0d1..5e9f6b2744ee 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -182,9 +182,9 @@ void olsr_init(void) #ifdef ENABLE_NAME #ifdef BOARD_NATIVE - local_name = gen_name(_name, sizeof _name); + olsr2_local_name = gen_name(_name, sizeof _name); #else - local_name = sysconfig.name; + olsr2_local_name = sysconfig.name; #endif #endif mutex_init(&olsr_data); @@ -209,7 +209,7 @@ void olsr_init(void) /* register olsr for routing */ ipv6_iface_set_routing_provider(get_next_hop); - DEBUG("This is node %s with IP %s", local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); + DEBUG("This is node %s with IP %s", olsr2_local_name, netaddr_to_str_s(&nbuf[0], get_local_addr())); /* enable sending */ int pid = thread_create(sender_thread_stack, sizeof sender_thread_stack, PRIORITY_MAIN - 1, CREATE_STACKTEST, olsr_sender_thread, NULL, "olsr_snd"); diff --git a/sys/net/routing/olsr2/writer.c b/sys/net/routing/olsr2/writer.c index 94de61e7c096..750392d32704 100644 --- a/sys/net/routing/olsr2/writer.c +++ b/sys/net/routing/olsr2/writer.c @@ -86,7 +86,7 @@ _cb_add_nhdp_message_TLVs(struct rfc5444_writer *wr) rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); #ifdef ENABLE_NAME - rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); + rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, olsr2_local_name, strlen(olsr2_local_name) + 1); #endif } @@ -173,7 +173,7 @@ _cb_add_olsr_message_TLVs(struct rfc5444_writer *wr) rfc5444_writer_add_messagetlv(wr, RFC5444_MSGTLV_VALIDITY_TIME, 0, &time_encoded, sizeof(time_encoded)); #ifdef ENABLE_NAME - rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, local_name, strlen(local_name) + 1); + rfc5444_writer_add_messagetlv(wr, RFC5444_TLV_NODE_NAME, 0, olsr2_local_name, strlen(olsr2_local_name) + 1); #endif } From 82ef757d49e2c5e2f853a726131d75585cb9ae9b Mon Sep 17 00:00:00 2001 From: Hinnerk van Bruinehsen Date: Wed, 29 Oct 2014 11:43:40 +0100 Subject: [PATCH 44/48] pkg: copy Kijewski's container_of implementation --- ...e-RIOT-s-container_of-implementation.patch | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 pkg/oonf_api/0007-Use-RIOT-s-container_of-implementation.patch diff --git a/pkg/oonf_api/0007-Use-RIOT-s-container_of-implementation.patch b/pkg/oonf_api/0007-Use-RIOT-s-container_of-implementation.patch new file mode 100644 index 000000000000..94f41df128f4 --- /dev/null +++ b/pkg/oonf_api/0007-Use-RIOT-s-container_of-implementation.patch @@ -0,0 +1,45 @@ +From b2ad2073ac282f1bc6315e47ffbd12c3f6a9ae1a Mon Sep 17 00:00:00 2001 +From: Hinnerk van Bruinehsen +Date: Wed, 29 Oct 2014 11:37:05 +0100 +Subject: [PATCH] Use RIOT's container_of implementation + +--- + src-api/common/container_of.h | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/src-api/common/container_of.h b/src-api/common/container_of.h +index fcb38fe..b49d836 100644 +--- a/src-api/common/container_of.h ++++ b/src-api/common/container_of.h +@@ -59,10 +59,24 @@ + * @return pointer to surrounding struct + */ + #ifndef container_of +-#define container_of(ptr, type, member) ({ \ +- const typeof(((type *)0)->member ) *__tempptr = (ptr); \ +- (type *)((char *)__tempptr - offsetof(type,member)); \ +- }) ++#if __STDC_VERSION__ >= 201112L ++# define container_of(PTR, TYPE, MEMBER) \ ++ (_Generic((PTR), \ ++ const __typeof__ (((TYPE *) 0)->MEMBER) *: \ ++ ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))), \ ++ __typeof__ (((TYPE *) 0)->MEMBER) *: \ ++ ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))) \ ++ )) ++#elif defined __GNUC__ ++# define container_of(PTR, TYPE, MEMBER) \ ++ (__extension__ ({ \ ++ __extension__ const __typeof__ (((TYPE *) 0)->MEMBER) *__m____ = (PTR); \ ++ ((TYPE *) ((char *) __m____ - offsetof(TYPE, MEMBER))); \ ++ })) ++#else ++# define container_of(PTR, TYPE, MEMBER) \ ++ ((TYPE *) ((char *) (PTR) - offsetof(TYPE, MEMBER))) ++#endif + #endif + + /** +-- +2.1.2 + From 98cfc0300a5ba811b2c138ce0492a26f7a6e1b9a Mon Sep 17 00:00:00 2001 From: Hinnerk van Bruinehsen Date: Wed, 29 Oct 2014 12:14:33 +0100 Subject: [PATCH 45/48] Add patches to fix the rest of the warnings --- ...08-Dissolve-enum-into-single-defines.patch | 54 +++++++++++++++++++ pkg/oonf_api/0009-Add-missing-include.patch | 24 +++++++++ ...10-Change-index-of-array-from-0-to-1.patch | 25 +++++++++ 3 files changed, 103 insertions(+) create mode 100644 pkg/oonf_api/0008-Dissolve-enum-into-single-defines.patch create mode 100644 pkg/oonf_api/0009-Add-missing-include.patch create mode 100644 pkg/oonf_api/0010-Change-index-of-array-from-0-to-1.patch diff --git a/pkg/oonf_api/0008-Dissolve-enum-into-single-defines.patch b/pkg/oonf_api/0008-Dissolve-enum-into-single-defines.patch new file mode 100644 index 000000000000..536df16007bf --- /dev/null +++ b/pkg/oonf_api/0008-Dissolve-enum-into-single-defines.patch @@ -0,0 +1,54 @@ +From e590e6f26b115da34a943fd4ed6d4c93fd2c64d0 Mon Sep 17 00:00:00 2001 +From: Hinnerk van Bruinehsen +Date: Wed, 29 Oct 2014 12:05:11 +0100 +Subject: [PATCH] Dissolve enum into single defines + +--- + src-api/rfc5444/rfc5444.h | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +diff --git a/src-api/rfc5444/rfc5444.h b/src-api/rfc5444/rfc5444.h +index c5d6420..6b5576e 100644 +--- a/src-api/rfc5444/rfc5444.h ++++ b/src-api/rfc5444/rfc5444.h +@@ -43,25 +43,23 @@ + + #include "common/common_types.h" + +-enum { +- /* timetlv_max = 14 * 2^28 * 1000 / 1024 = 14000 << 18 = 3 670 016 000 ms */ +- RFC5444_TIMETLV_MAX = 0xdac00000, ++/* timetlv_max = 14 * 2^28 * 1000 / 1024 = 14000 << 18 = 3 670 016 000 ms */ ++#define RFC5444_TIMETLV_MAX 0xdac00000 + +- /* timetlv_min = 1000/1024 ms */ +- RFC5444_TIMETLV_MIN = 0x00000001, ++/* timetlv_min = 1000/1024 ms */ ++#define RFC5444_TIMETLV_MIN 0x00000001 + +- /* metric_max = 1<<24 - 256 */ +- RFC5444_METRIC_MAX = 0xffff00, ++/* metric_max = 1<<24 - 256 */ ++#define RFC5444_METRIC_MAX 0xffff00 + +- /* metric_min = 1 */ +- RFC5444_METRIC_MIN = 0x000001, ++/* metric_min = 1 */ ++#define RFC5444_METRIC_MIN 0x000001 + +- /* larger than possible metric value */ +- RFC5444_METRIC_INFINITE = 0xffffff, ++/* larger than possible metric value */ ++#define RFC5444_METRIC_INFINITE 0xffffff + +- /* infinite path cost */ +- RFC5444_METRIC_INFINITE_PATH = 0xffffffff, +-}; ++/* infinite path cost */ ++#define RFC5444_METRIC_INFINITE_PATH 0xffffffff + + EXPORT uint8_t rfc5444_timetlv_get_from_vector( + uint8_t *vector, size_t vector_length, uint8_t hopcount); +-- +2.1.2 + diff --git a/pkg/oonf_api/0009-Add-missing-include.patch b/pkg/oonf_api/0009-Add-missing-include.patch new file mode 100644 index 000000000000..444bfcd4bffa --- /dev/null +++ b/pkg/oonf_api/0009-Add-missing-include.patch @@ -0,0 +1,24 @@ +From 21202804f26b194607a412476a96f03d3df30688 Mon Sep 17 00:00:00 2001 +From: Hinnerk van Bruinehsen +Date: Wed, 29 Oct 2014 12:11:29 +0100 +Subject: [PATCH 9/9] Add missing include + +--- + src-api/rfc5444/rfc5444_tlv_writer.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src-api/rfc5444/rfc5444_tlv_writer.h b/src-api/rfc5444/rfc5444_tlv_writer.h +index ace7313..8d0ce3a 100644 +--- a/src-api/rfc5444/rfc5444_tlv_writer.h ++++ b/src-api/rfc5444/rfc5444_tlv_writer.h +@@ -43,6 +43,7 @@ + #define RFC5444_TLV_WRITER_H_ + + #include "common/common_types.h" ++#include "rfc5444_context.h" + + struct rfc5444_tlv_writer_data { + uint8_t *buffer; +-- +2.1.2 + diff --git a/pkg/oonf_api/0010-Change-index-of-array-from-0-to-1.patch b/pkg/oonf_api/0010-Change-index-of-array-from-0-to-1.patch new file mode 100644 index 000000000000..3deebdab4e85 --- /dev/null +++ b/pkg/oonf_api/0010-Change-index-of-array-from-0-to-1.patch @@ -0,0 +1,25 @@ +From 0ecbb8a8b896ac4aff57d94d678a4a95084a095c Mon Sep 17 00:00:00 2001 +From: Hinnerk van Bruinehsen +Date: Wed, 29 Oct 2014 12:13:27 +0100 +Subject: [PATCH 10/10] Change index of array from 0 to 1 + +--- + src-api/common/template.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src-api/common/template.h b/src-api/common/template.h +index d98fe77..7ca75a8 100644 +--- a/src-api/common/template.h ++++ b/src-api/common/template.h +@@ -64,7 +64,7 @@ struct abuf_template_storage_entry { + + struct abuf_template_storage { + size_t count; +- struct abuf_template_storage_entry indices[0]; ++ struct abuf_template_storage_entry indices[1]; + }; + + EXPORT struct abuf_template_storage *abuf_template_init ( +-- +2.1.2 + From d6c6214bba99cdebcdfa209673f06f7dccf2d3d4 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 30 Oct 2014 18:53:22 +0100 Subject: [PATCH 46/48] use msg_try_send --- sys/net/routing/olsr2/olsr_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net/routing/olsr2/olsr_init.c b/sys/net/routing/olsr2/olsr_init.c index 5e9f6b2744ee..c8114ea278ac 100644 --- a/sys/net/routing/olsr2/olsr_init.c +++ b/sys/net/routing/olsr2/olsr_init.c @@ -217,12 +217,12 @@ void olsr_init(void) msg_t m; DEBUG("setting up HELLO timer"); m.content.ptr = (char *) &msg_hello; - msg_send(&m, pid, false); + msg_try_send(&m, pid); sleep_s(1); DEBUG("setting up TC timer"); m.content.ptr = (char *) &msg_tc; - msg_send(&m, pid, false); + msg_try_send(&m, pid); } #endif /* RIOT */ From d44adc9f46d5b97b3536becb0c45af2ee27f9788 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 30 Oct 2014 19:28:42 +0100 Subject: [PATCH 47/48] set address mode --- examples/olsr2/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/olsr2/main.c b/examples/olsr2/main.c index 006b806833e9..78a6d9316aa0 100644 --- a/examples/olsr2/main.c +++ b/examples/olsr2/main.c @@ -103,6 +103,7 @@ static void init(void) { rtc_enable(); genrand_init(get_node_id()); + net_if_set_src_address_mode(IF_ID, NET_IF_TRANS_ADDR_M_SHORT); net_if_set_hardware_address(IF_ID, get_node_id()); ipv6_addr_set_link_local_prefix(&tmp); From 15b66ba32a5ae5e3c95d245d887798bc86ba3fe2 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 30 Oct 2014 22:49:32 +0100 Subject: [PATCH 48/48] should be += --- examples/olsr2/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/olsr2/Makefile b/examples/olsr2/Makefile index 98099c878855..98fa29d1d69d 100644 --- a/examples/olsr2/Makefile +++ b/examples/olsr2/Makefile @@ -16,7 +16,7 @@ QUIET ?= 1 USEPKG += oonf_api -export CFLAGS = -DRIOT -DENABLE_NAME +export CFLAGS += -DRIOT -DENABLE_NAME # Modules to include. USEMODULE += rtc