Revision: 539
http://vde.svn.sourceforge.net/vde/?rev=539&view=rev
Author: danielel
Date: 2012-01-29 02:59:45 +0000 (Sun, 29 Jan 2012)
Log Message:
-----------
Olsr: refactoring of messages. still TODO: timing implementation, message
forwarding, evaluate link quality
Modified Paths:
--------------
branches/vde-router/vde-2/src/vde_router/vder_olsr.c
branches/vde-router/vde-2/src/vde_router/vder_olsr.h
Modified: branches/vde-router/vde-2/src/vde_router/vder_olsr.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_olsr.c 2012-01-23
12:41:31 UTC (rev 538)
+++ branches/vde-router/vde-2/src/vde_router/vder_olsr.c 2012-01-29
02:59:45 UTC (rev 539)
@@ -9,202 +9,316 @@
#define OLSR_MSG_INTERVAL 2000
#define HOST_NETMASK (htonl(0xFFFFFFFF))
-#define MAX_HOPS 256
+#ifndef MIN
+# define MIN(a,b) (a<b?a:b)
+#endif
+static struct vder_udp_socket *udpsock;
+static struct olsr_setup *settings;
+uint16_t my_ansn = 0;
+
struct olsr_route_entry
{
struct olsr_route_entry *next;
- unsigned long time_left;
+ long time_left;
uint32_t destination;
- uint32_t gateway;
+ struct olsr_route_entry *gateway;
struct vder_iface *iface;
uint16_t metric;
uint8_t link_type;
+ struct olsr_route_entry *children;
+ uint16_t ansn;
+ uint8_t lq, nlq;
+ uint8_t *advertised_tc;
};
-static struct olsr_route_entry *Routes[MAX_HOPS] = {};
-static struct vder_udp_socket *udpsock;
-static struct olsr_setup *settings;
+static struct olsr_route_entry *Local_interfaces;
-static struct olsr_route_entry *get_route_by_address(uint32_t ip)
+struct olsr_route_entry *olsr_get_ethentry(struct vder_iface *vif)
{
- struct olsr_route_entry *cur;
- int i;
+ struct olsr_route_entry *cur = Local_interfaces;
+ while(cur) {
+ if (cur->iface == vif)
+ return cur;
+ cur = cur->next;
+ }
+ return NULL;
+}
- for (i = 0; i < MAX_HOPS; i++) {
- cur = Routes[i];
- while(cur) {
- if (cur->destination == ip)
- return cur;
- cur = cur->next;
- }
+static struct olsr_route_entry *get_next_hop(struct olsr_route_entry *dst)
+{
+ struct olsr_route_entry *hop = dst;
+ while(hop) {
+ if(hop->metric <= 1)
+ return hop;
+ hop = hop->gateway;
}
return NULL;
}
-static void route_change_metric(struct olsr_route_entry *r, int new_metric,
uint32_t new_gateway)
+static inline void olsr_route_add(struct olsr_route_entry *el)
{
- struct olsr_route_entry *cur, *prev;
- cur = Routes[r->metric], prev = NULL;
+ struct olsr_route_entry *nexthop;
+ if (el->gateway) {
+ /* 2-hops route or more */
+ el->next = el->gateway->children;
+ el->gateway->children = el;
+ nexthop = get_next_hop(el);
+ vder_route_add(el->destination, HOST_NETMASK,
nexthop->destination, el->metric, NULL);
+ el->link_type = OLSRLINK_MPR;
+ } else if (el->iface) {
+ /* neighbor */
+ struct olsr_route_entry *ei = olsr_get_ethentry(el->iface);
+ el->link_type = OLSRLINK_SYMMETRIC;
+ if (ei) {
+ el->next = ei->children;
+ ei->children = el;
+ }
+ }
+}
+
+static inline void olsr_route_del(struct olsr_route_entry *r)
+{
+ struct olsr_route_entry *cur, *prev = NULL, *lst;
+ if (r->gateway) {
+ lst = r->gateway->children;
+ } else if (r->iface) {
+ lst = olsr_get_ethentry(r->iface);
+ } else {
+ lst = Local_interfaces;
+ }
+ cur = lst, prev = NULL;
while(cur) {
if (cur == r) {
/* found */
- if (!prev)
- Routes[r->metric] = cur->next;
- else
- prev->next = cur->next;
+ if (r->gateway) {
+ vder_route_del(r->destination, HOST_NETMASK,
r->metric);
- if (r->metric > 1)
- vder_route_del(cur->destination, HOST_NETMASK,
r->metric);
+ if (!prev)
+ r->gateway->children = r->next;
+ else
+ prev->next = r->next;
+ }
- r->metric = new_metric;
- r->gateway = new_gateway;
-
- if (r->metric > 1) {
- vder_route_add(cur->destination, HOST_NETMASK,
new_gateway, new_metric, NULL);
- r->next = Routes[r->metric];
- Routes[r->metric] = r;
+ while (r->children) {
+ olsr_route_del(r->children);
+ /* Orphans must die. */
+ free(r->children);
}
return;
}
-
prev = cur;
cur = cur->next;
}
}
+static struct olsr_route_entry *get_route_by_address(struct olsr_route_entry
*lst, uint32_t ip)
+{
+ struct olsr_route_entry *found;
+ if(lst) {
+ if (lst->destination == ip) {
+ return lst;
+ }
+ found = get_route_by_address(lst->children, ip);
+ if (found)
+ return found;
+ found = get_route_by_address(lst->next, ip);
+ if (found)
+ return found;
+ }
+ return NULL;
+}
static void refresh_neighbors(struct vder_iface *iface)
{
- struct olsr_route_entry *cur;
uint32_t neighbors[256];
int i;
- unsigned char found = 0;
+ struct olsr_route_entry *found = NULL, *ancestor = NULL;
int n_vec_size = vder_arp_get_neighbors(iface, neighbors, 256);
+
+ ancestor = olsr_get_ethentry(iface);
+ if (!ancestor)
+ return;
+
for (i = 0; i < n_vec_size; i++) {
- cur = Routes[1];
- while(cur) {
- if (cur->destination == neighbors[i]) {
- cur->time_left = (OLSR_MSG_INTERVAL << 2);
- found = 1;
- break;
+ found = get_route_by_address(Local_interfaces, neighbors[i]);
+ if (found) {
+ if (found->metric > 1) { /* Reposition among neighbors
*/
+ olsr_route_del(found);
+ found->gateway = olsr_get_ethentry(iface);
+ found->iface = iface;
+ found->metric = 1;
+ found->lq = 0xFF;
+ found->nlq = 0xFF;
+ olsr_route_add(found);
}
- cur = cur->next;
- }
- if (!found) {
- /* look on bigger metrics */
- struct olsr_route_entry *e =
get_route_by_address(neighbors[i]);
- if (e) {
- route_change_metric(e, 0U, 1);
- } else {
- e = malloc(sizeof (struct olsr_route_entry));
- if (!e) {
- perror("olsr: adding local route
entry");
- return;
- }
+ found->link_type = OLSRLINK_SYMMETRIC;
+ found->time_left = (OLSR_MSG_INTERVAL << 2);
+ } else {
+ struct olsr_route_entry *e = malloc(sizeof (struct
olsr_route_entry));
+ if (!e) {
+ perror("olsr: adding local route entry");
+ return;
}
+ memset(e, 0, sizeof(struct olsr_route_entry));
e->destination = neighbors[i];
e->link_type = OLSRLINK_SYMMETRIC;
e->time_left = (OLSR_MSG_INTERVAL << 2);
- e->gateway = 0U;
+ e->gateway = olsr_get_ethentry(iface);
e->iface = iface;
e->metric = 1;
- e->next = Routes[1];
- Routes[1] = e;
+ e->lq = 0xFF;
+ e->nlq = 0xFF;
+ olsr_route_add(e);
}
}
}
+static void olsr_garbage_collector(struct olsr_route_entry *sublist)
+{
+ if(!sublist)
+ return;
+ if ((sublist->time_left--) <= 0) {
+ olsr_route_del(sublist);
+ free(sublist);
+ return;
+ }
+ olsr_garbage_collector(sublist->children);
+ olsr_garbage_collector(sublist->next);
+}
+
static void refresh_routes(void)
{
int i;
- struct olsr_route_entry *cur, *prev = NULL;
+ struct olsr_route_entry *local, *neighbor = NULL;
/* Refresh local entries */
/* Step 1: set zero expire time for local addresses and neighbors*/
- for (i = 0; i < 2; i++) {
- cur = Routes[i];
- while(cur) {
- cur->time_left = (OLSR_MSG_INTERVAL << 2);
- cur = cur->next;
+ local = Local_interfaces;
+ while(local) {
+ local->time_left = 0;
+ neighbor = local->children;
+ while (neighbor && (neighbor->metric < 2)) {
+ //printf("Setting to zero. Neigh: %08x metric %d\n",
neighbor->destination, neighbor->metric);
+ neighbor->time_left = 0;
+ neighbor = neighbor->next;
}
+ local = local->next;
}
-
/* Step 2: refresh timer for entries that are still valid.
* Add new entries.
*/
for (i = 0; i < settings->n_ifaces; i++) {
struct vder_iface *icur = settings->ifaces[i];
- struct vder_ip4address *addr = icur->address_list;
- while (addr) {
- unsigned char found = 0;
- cur = Routes[0];
- while(cur) {
- if (cur->destination == addr->address) {
- cur->time_left = (OLSR_MSG_INTERVAL <<
2);
- found = 1;
- break;
- }
- cur = cur->next;
+ local = olsr_get_ethentry(icur);
+ if (local) {
+ local->time_left = (OLSR_MSG_INTERVAL << 2);
+ } else if (icur->address_list) {
+ struct olsr_route_entry *e = malloc(sizeof (struct
olsr_route_entry));
+ if (!e) {
+ perror("olsr: adding local route entry");
+ return;
}
- if (!found) {
- struct olsr_route_entry *e = malloc(sizeof
(struct olsr_route_entry));
- if (!e) {
- perror("olsr: adding local route
entry");
- return;
- }
- e->destination = addr->address;
- e->time_left = (OLSR_MSG_INTERVAL << 2);
- e->gateway = 0U;
- e->iface = icur;
- e->metric = 0;
- e->next = Routes[0];
- Routes[0] = e;
- }
- refresh_neighbors(icur);
- addr = addr->next;
+ memset(e, 0, sizeof(struct olsr_route_entry));
+ e->destination = icur->address_list->address; /* Always
pick the first address */
+ e->time_left = (OLSR_MSG_INTERVAL << 2);
+ e->iface = icur;
+ e->metric = 0;
+ e->lq = 0xFF;
+ e->nlq = 0xFF;
+ e->next = Local_interfaces;
+ Local_interfaces = e;
}
+ refresh_neighbors(icur);
}
- /* Remove expired entries */
+}
- for (i = 0; i < MAX_HOPS; i++) {
- cur = Routes[i], prev = NULL;
- while(cur) {
- if (cur->time_left < OLSR_MSG_INTERVAL) {
- if (!prev)
- Routes[i] = cur->next;
- else
- prev->next = cur->next;
- printf("Route expired!\n");
- if (i > 1)
- vder_route_del(cur->destination,
HOST_NETMASK, i);
- free(cur);
- } else {
- prev = cur;
- }
- cur = cur->next;
+static int olsr_build_hello_neighbors(uint8_t *buf, int size)
+{
+ int ret = 0;
+ struct olsr_route_entry *local, *neighbor;
+ struct olsr_neighbor *dst = (struct olsr_neighbor *) buf;
+ local = Local_interfaces;
+ while (local) {
+ neighbor = local->children;
+ while (neighbor) {
+ struct olsr_link *li = (struct olsr_link *) (buf + ret);
+ li->link_code = neighbor->link_type;
+ li->reserved = 0;
+ li->link_msg_size = htons(sizeof(struct olsr_neighbor)
+ sizeof(struct olsr_link));
+ ret += sizeof(struct olsr_link);
+ dst = (struct olsr_neighbor *) (buf+ret);
+ dst->addr = neighbor->destination;
+ dst->nlq = neighbor->nlq;
+ dst->lq = neighbor->lq;
+ dst->reserved = 0;
+ ret += sizeof(struct olsr_neighbor);
+ if (ret >= size)
+ return ret - sizeof(struct olsr_neighbor) -
sizeof(struct olsr_link);
+ neighbor = neighbor->next;
}
+ local = local->next;
}
+ return ret;
}
+static int olsr_build_tc_neighbors(uint8_t *buf, int size)
+{
+ int ret = 0;
+ struct olsr_route_entry *local, *neighbor;
+ struct olsr_neighbor *dst = (struct olsr_neighbor *) buf;
+ local = Local_interfaces;
+ while (local) {
+ neighbor = local->children;
+ while (neighbor) {
+ dst->addr = neighbor->destination;
+ dst->nlq = neighbor->nlq;
+ dst->lq = neighbor->lq;
+ dst->reserved = 0;
+ ret += sizeof(struct olsr_neighbor);
+ dst = (struct olsr_neighbor *) (buf + ret);
+ if (ret >= size)
+ return ret - sizeof(struct olsr_neighbor);
+ neighbor = neighbor->next;
+ }
+ local = local->next;
+ }
+ return ret;
+}
+
+static int olsr_build_mid(uint8_t *buf, int size, struct vder_iface *excluded)
+{
+ int ret = 0;
+ struct olsr_route_entry *local;
+ uint32_t *dst = (uint32_t *) buf;
+ local = Local_interfaces;
+ while (local) {
+ if (local->iface != excluded) {
+ *dst = local->destination;
+ ret += sizeof(uint32_t);
+ dst = (uint32_t *) (buf + ret);
+ if (ret >= size)
+ return ret - sizeof(uint32_t);
+ }
+ local = local->next;
+ }
+ return ret;
+}
+
static void olsr_make_dgram(struct vder_iface *vif)
{
uint8_t dgram[2000];
- int size = 0;
+ int size = 0, r;
struct vder_ip4address *ep;
struct olsrhdr *ohdr;
uint32_t netmask, bcast;
- struct olsrmsg *msg_hello, *msg_mid;
+ struct olsrmsg *msg_hello, *msg_mid, *msg_tc;
struct olsr_hmsg_hello *hello;
-
- struct olsr_link *hlink;
- struct olsr_route_entry *entry;
- int n_vec_size, i, mid_count = 0;
-
+ struct olsr_hmsg_tc *tc;
static uint8_t hello_counter = 0, mid_counter = 0, tc_counter = 0;
static uint16_t pkt_counter = 0;
@@ -224,44 +338,26 @@
msg_hello = (struct olsrmsg *) (dgram + size);
size += sizeof(struct olsrmsg);
msg_hello->type = OLSRMSG_HELLO;
- msg_hello->vtime = 60; /* one hot minute */
+ msg_hello->vtime = 0x2c;
msg_hello->orig = ep->address;
msg_hello->ttl = 1;
msg_hello->hop = 0;
msg_hello->seq = htons(hello_counter++);
-
hello = (struct olsr_hmsg_hello *)(dgram + size);
size += sizeof(struct olsr_hmsg_hello);
hello->reserved = 0;
hello->htime = 0x05; /* Todo: find and define values */
hello->willingness = 0x07;
-
-
- entry = Routes[1];
- n_vec_size = 0;
- while(entry) {
- struct olsr_neighbor *neigh;
- hlink = (struct olsr_link *) (dgram + size);
- size += (sizeof(struct olsr_link));
- hlink->reserved = 0;
- hlink->link_code = entry->link_type;
- hlink->link_msg_size = htons(sizeof(struct olsr_link) +
sizeof(struct olsr_neighbor));
- neigh = (struct olsr_neighbor *) (dgram + size);
- size += (sizeof(struct olsr_neighbor));
- neigh->addr = entry->destination;
- neigh->lq = 0xFF;
- neigh->nlq = 0xFF;
- n_vec_size++;
- entry = entry->next;
+ r = olsr_build_hello_neighbors(dgram + size, 2000 - size);
+ if (r < 0) {
+ perror("Building hello message");
+ return;
}
- msg_hello->size = htons(sizeof(struct olsrmsg) +
- sizeof(struct olsr_hmsg_hello) + n_vec_size * ((sizeof(struct
olsr_link) + sizeof(struct olsr_neighbor))));
+ size += r;
+ msg_hello->size = htons(sizeof(struct olsrmsg) + sizeof(struct
olsr_hmsg_hello) + r);
-
-
/* MID Message */
- entry = Routes[0];
msg_mid = (struct olsrmsg *)(dgram + size);
size += sizeof(struct olsrmsg);
msg_mid->type = OLSRMSG_MID;
@@ -269,28 +365,38 @@
msg_mid->orig = ep->address;
msg_mid->ttl = 0xFF;
msg_mid->hop = 0;
-
- while(entry) {
- uint32_t mid_address;
- if (entry->iface != vif) {
- mid_address = entry->destination;
- memcpy(dgram + size, &mid_address, sizeof(uint32_t));
- size += sizeof(uint32_t);
- mid_count++;
- }
- entry = entry->next;
+ msg_mid->seq = htons(mid_counter++);
+ r = olsr_build_mid(dgram + size, 2000 - size, vif);
+ if (r < 0) {
+ perror("Building mid message");
+ return;
}
- if (mid_count == 0) {
- size -= (sizeof(struct olsrmsg));
+ if (r == 0) {
+ size -= sizeof(struct olsrmsg);
} else {
- msg_mid->seq = htons(mid_counter++);
- msg_mid->size = htons(sizeof(struct olsrmsg) + sizeof(uint32_t)
* mid_count);
+ size += r;
+ msg_mid->size = htons(sizeof(struct olsrmsg) + r);
}
- /* TODO: Add TC msg */
-
+ msg_tc = (struct olsrmsg *) (dgram + size);
+ size += sizeof(struct olsrmsg);
+ msg_tc->type = OLSRMSG_TC;
+ msg_tc->vtime = 0x2c;
+ msg_tc->orig = ep->address;
+ msg_tc->ttl = 0xFF;
+ msg_tc->hop = 0;
+ msg_tc->seq = htons(tc_counter++);
+ tc = (struct olsr_hmsg_tc *)(dgram + size);
+ size += sizeof(struct olsr_hmsg_tc);
+ tc->ansn = htons(my_ansn);
+ r = olsr_build_tc_neighbors(dgram + size, 2000 - size);
+ if (r < 0) {
+ perror("Building tc message");
+ return;
+ }
+ size += r;
+ msg_tc->size = htons(sizeof(struct olsrmsg) + sizeof(struct
olsr_hmsg_tc) + r);
-
/* Finalize olsr packet */
ohdr->len = htons(size);
ohdr->seq = htons(pkt_counter++);
@@ -309,71 +415,190 @@
}
}
-static void recv_hello(uint8_t *buffer, int len, uint32_t origin)
+static void recv_mid(uint8_t *buffer, int len, struct olsr_route_entry
*origin)
{
- struct olsr_link *li;
+ int parsed = 0;
uint32_t *address;
struct olsr_route_entry *e;
+
+ if (len % sizeof(uint32_t)) /*drop*/
+ return;
+
+ while (len > parsed) {
+ address = (uint32_t *)(buffer + parsed);
+ e = get_route_by_address(Local_interfaces, *address);
+ if (!e) {
+ e = malloc(sizeof(struct olsr_route_entry));
+ if (!e) {
+ perror("olsr allocating route");
+ return;
+ }
+ memset(e, 0, sizeof(struct olsr_route_entry));
+ e->time_left = (OLSR_MSG_INTERVAL << 2);
+ e->destination = *address;
+ e->gateway = origin;
+ e->iface = origin->iface;
+ e->metric = origin->metric + 1;
+ e->lq = origin->lq;
+ e->nlq = origin->nlq;
+ olsr_route_add(e);
+ arp_storm(e->destination);
+ } else if (e->metric > (origin->metric + 1)) {
+ olsr_route_del(e);
+ e->metric = origin->metric;
+ e->gateway = origin;
+ olsr_route_add(e);
+ }
+ parsed += sizeof(uint32_t);
+ }
+}
+
+static void recv_hello(uint8_t *buffer, int len, struct olsr_route_entry
*origin)
+{
+ struct olsr_link *li;
+ struct olsr_route_entry *e;
int parsed = 0;
+ struct olsr_neighbor *neigh;
+ if (!origin)
+ return;
+
while (len > parsed) {
li = (struct olsr_link *) buffer;
- address = (uint32_t *)(buffer + parsed + sizeof(struct
olsr_link));
+ neigh = (struct olsr_neighbor *)(buffer + parsed +
sizeof(struct olsr_link));
parsed += ntohs(li->link_msg_size);
- e = get_route_by_address(*address);
+ e = get_route_by_address(Local_interfaces, neigh->addr);
if (!e) {
e = malloc(sizeof(struct olsr_route_entry));
if (!e) {
perror("olsr allocating route");
return;
}
+ memset(e, 0, sizeof(struct olsr_route_entry));
e->time_left = (OLSR_MSG_INTERVAL << 2);
- e->destination = *address;
+ e->destination = neigh->addr;
e->gateway = origin;
- e->iface = NULL;
- e->metric = 2;
- e->next = Routes[2];
- Routes[2] = e;
+ e->iface = origin->iface;
+ e->metric = origin->metric + 1;
+ e->link_type = OLSRLINK_UNKNOWN;
+ e->lq = MIN(origin->lq, neigh->lq);
+ e->nlq = MIN(origin->nlq, neigh->nlq);
+ olsr_route_add(e);
arp_storm(e->destination);
- vder_route_add(*address, HOST_NETMASK, origin, 2, NULL);
- } else if (e->metric > 2) {
- route_change_metric(e, origin, 2);
+ } else if ((e->gateway != origin) && (e->metric >
(origin->metric + 1))) {
+ olsr_route_del(e);
+ e->metric = origin->metric + 1;
+ e->gateway = origin;
+ olsr_route_add(e);
}
}
}
+static int reconsider_topology(uint8_t *buf, int size, struct olsr_route_entry
*e)
+{
+ struct olsr_hmsg_tc *tc = (struct olsr_hmsg_tc *) buf;
+ uint16_t new_ansn = ntohs(tc->ansn);
+ int parsed = sizeof(struct olsr_hmsg_tc);
+ struct olsr_route_entry *rt;
+ struct olsr_neighbor *n;
+
+ if (e->advertised_tc && ((new_ansn > e->ansn) || ((e->ansn - new_ansn)
> 32768)))
+ {
+ free(e->advertised_tc);
+ e->advertised_tc = NULL;
+ }
+
+ if (!e->advertised_tc) {
+ e->advertised_tc = malloc(size);
+ if (!e) {
+ perror("Allocating forward packet");
+ return -1;
+ }
+ memcpy(e->advertised_tc, buf, size);
+ e->ansn = new_ansn;
+ while (parsed < size) {
+ n = (struct olsr_neighbor *) (buf + parsed);
+ parsed += sizeof(struct olsr_neighbor);
+ rt = get_route_by_address(Local_interfaces, n->addr);
+ if (rt && (rt->gateway == e)) {
+ /* Refresh existing node */
+ rt->time_left = e->time_left;
+ } else if (!rt || (rt->metric > (e->metric + 1)) ||
(rt->nlq < n->nlq)) {
+ if (!rt) {
+ rt = malloc(sizeof (struct
olsr_route_entry));
+ memset(rt, 0, sizeof(struct
olsr_route_entry));
+ rt->destination = n->addr;
+ } else {
+ olsr_route_del(rt);
+ }
+ rt->link_type = OLSRLINK_UNKNOWN;
+ rt->iface = e->iface;
+ rt->gateway = e;
+ rt->metric = e->metric + 1;
+ rt->lq = n->lq;
+ rt->nlq = n->nlq;
+ //rt->time_left = e->time_left;
+ rt->time_left = 289;
+ olsr_route_add(rt);
+ }
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
static void olsr_recv(uint8_t *buffer, int len)
{
+ struct olsrmsg *msg;
+ struct olsr_hmsg_tc *msg_tc;
struct olsrhdr *oh = (struct olsrhdr *) buffer;
+ struct olsr_route_entry *ancestor;
int parsed = 0;
if (len != ntohs(oh->len)) {
return;
}
parsed += sizeof(struct olsrhdr);
- struct olsrmsg *msg;
while (len > parsed) {
struct olsr_route_entry *origin;
msg = (struct olsrmsg *) (buffer + parsed);
- origin = get_route_by_address(msg->orig);
+ origin = get_route_by_address(Local_interfaces, msg->orig);
if (!origin) {
+ /* Discard this msg while it is not from known host */
arp_storm(msg->orig);
- } else {
- origin->link_type = OLSRLINK_MPR;
+ parsed += ntohs(msg->size);
+ continue;
}
+ /* We know this is a Master host and a neighbor */
+ origin->link_type = OLSRLINK_MPR;
+ origin->time_left = 288; /* TODO: get from msg->vtime */
switch(msg->type) {
case OLSRMSG_HELLO:
+ ancestor = olsr_get_ethentry(origin->iface);
+ if ((origin->metric > 1) && ancestor) {
+ olsr_route_del(origin);
+ origin->gateway = ancestor;
+ origin->metric = 1;
+ olsr_route_add(origin);
+ }
recv_hello(buffer + parsed + sizeof(struct
olsrmsg) + sizeof(struct olsr_hmsg_hello),
ntohs(msg->size) - (sizeof(struct
olsrmsg)) - sizeof(struct olsr_hmsg_hello),
- msg->orig);
+ origin);
break;
case OLSRMSG_MID:
+ recv_mid(buffer + parsed + sizeof(struct
olsrmsg), ntohs(msg->size) - (sizeof(struct olsrmsg)), origin);
break;
case OLSRMSG_TC:
+ msg_tc = (struct olsr_hmsg_tc *) (buffer +
parsed);
+ reconsider_topology(buffer + parsed +
sizeof(struct olsrmsg), ntohs(msg->size) - (sizeof(struct olsrmsg)), origin);
break;
default:
return;
}
+ if ((--msg->ttl) > 0) {
+ /*TODO: Fwd */
+ }
parsed += ntohs(msg->size);
}
}
@@ -396,6 +621,28 @@
if (!udpsock)
return NULL;
+ for (i = 0; i < settings->n_ifaces; i++) {
+ struct vder_ip4address *a = settings->ifaces[i]->address_list;
+ while(a) {
+ struct olsr_route_entry *e = malloc(sizeof(struct
olsr_route_entry));
+ if (!e) {
+ perror("initializing interfaces");
+ return NULL;
+ }
+ memset(e, 0, sizeof(struct olsr_route_entry));
+ e->destination = a->address;
+ e->link_type = OLSRLINK_SYMMETRIC;
+ e->time_left = (OLSR_MSG_INTERVAL << 2);
+ e->gateway = NULL;
+ e->iface = settings->ifaces[i];
+ e->metric = 0;
+ e->lq = 0xFF;
+ e->nlq = 0xFF;
+ e->next = Local_interfaces;
+ Local_interfaces = e;
+ a = a->next;
+ }
+ }
gettimeofday(&last_out, NULL);
refresh_routes();
@@ -409,8 +656,12 @@
if ((len > 0) && (from_port == OLSR_PORT)) {
olsr_recv(buffer, len);
}
- usleep(500000);
+ usleep(200000);
gettimeofday(&now, NULL);
+ if (last_out.tv_sec == now.tv_sec)
+ continue;
+ /* Remove expired entries */
+ olsr_garbage_collector(Local_interfaces);
refresh_routes();
last_out = now;
for (i = 0; i < settings->n_ifaces; i++)
Modified: branches/vde-router/vde-2/src/vde_router/vder_olsr.h
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_olsr.h 2012-01-23
12:41:31 UTC (rev 538)
+++ branches/vde-router/vde-2/src/vde_router/vder_olsr.h 2012-01-29
02:59:45 UTC (rev 539)
@@ -11,6 +11,7 @@
#define OLSRMSG_TC 0xca
#define OLSRLINK_SYMMETRIC 0x06
+#define OLSRLINK_UNKNOWN 0x08
#define OLSRLINK_MPR 0x0a
struct __attribute__((packed)) olsr_link
@@ -38,9 +39,6 @@
struct __attribute__((packed)) olsr_hmsg_tc
{
uint16_t ansn;
- uint32_t addr;
- uint8_t lq;
- uint8_t nlq;
uint16_t reserved;
};
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2
_______________________________________________
vde-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users