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 vde-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vde-users