Revision: 536
http://vde.svn.sourceforge.net/vde/?rev=536&view=rev
Author: danielel
Date: 2012-01-21 15:46:56 +0000 (Sat, 21 Jan 2012)
Log Message:
-----------
Vde router
- implemented olsr parser (hello only)
- fixed bug in locally generated packet routing
Modified Paths:
--------------
branches/vde-router/vde-2/src/vde_router/vder_arp.c
branches/vde-router/vde-2/src/vde_router/vder_datalink.c
branches/vde-router/vde-2/src/vde_router/vder_olsr.c
branches/vde-router/vde-2/src/vde_router/vder_packet.c
Modified: branches/vde-router/vde-2/src/vde_router/vder_arp.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_arp.c 2012-01-20 06:44:59 UTC
(rev 535)
+++ branches/vde-router/vde-2/src/vde_router/vder_arp.c 2012-01-21 15:46:56 UTC
(rev 536)
@@ -82,6 +82,12 @@
ah->opcode = htons(ARP_REQUEST);
memcpy(ah->s_mac, oif->macaddr,6);
ah->s_addr = vder_get_right_localip(oif, tgt);
+ if (ah->s_addr == 0) {
+ if (oif->address_list)
+ ah->s_addr = oif->address_list->address;
+ else
+ return -1;
+ }
memset(ah->d_mac,0,6);
ah->d_addr = tgt;
vdb->priority = PRIO_ARP;
Modified: branches/vde-router/vde-2/src/vde_router/vder_datalink.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_datalink.c 2012-01-20
06:44:59 UTC (rev 535)
+++ branches/vde-router/vde-2/src/vde_router/vder_datalink.c 2012-01-21
15:46:56 UTC (rev 536)
@@ -197,7 +197,16 @@
ro->netmask = netmask;
ro->gateway = gateway;
ro->metric = metric;
- ro->iface = dst;
+ if (dst)
+ ro->iface = dst;
+ else {
+ struct vder_route *next_hop = vder_get_route(gateway);
+ if (!next_hop) {
+ errno = EHOSTUNREACH;
+ goto out_unlock;
+ }
+ ro->iface = next_hop->iface;
+ }
/* Is this route already there? */
cur = Router.routing_table;
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-20
06:44:59 UTC (rev 535)
+++ branches/vde-router/vde-2/src/vde_router/vder_olsr.c 2012-01-21
15:46:56 UTC (rev 536)
@@ -16,9 +16,10 @@
struct olsr_route_entry *next;
unsigned long time_left;
uint32_t destination;
- struct olsr_route *gateway;
+ uint32_t gateway;
struct vder_iface *iface;
uint16_t metric;
+ uint8_t link_type;
};
static struct olsr_route_entry *Routes[MAX_HOPS] = {};
@@ -41,6 +42,38 @@
return NULL;
}
+static void route_change_metric(struct olsr_route_entry *r, int new_metric,
uint32_t new_gateway)
+{
+ struct olsr_route_entry *cur, *prev;
+ cur = Routes[r->metric], prev = NULL;
+ while(cur) {
+ if (cur == r) {
+ /* found */
+ if (!prev)
+ Routes[r->metric] = cur->next;
+ else
+ prev->next = cur->next;
+
+ if (r->metric > 1)
+ vder_route_del(cur->destination, HOST_NETMASK,
r->metric);
+
+ 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;
+ }
+ return;
+ }
+
+ prev = cur;
+ cur = cur->next;
+ }
+}
+
+
static void refresh_neighbors(struct vder_iface *iface)
{
struct olsr_route_entry *cur;
@@ -59,14 +92,21 @@
cur = cur->next;
}
if (!found) {
- struct olsr_route_entry *e = malloc(sizeof (struct
olsr_route_entry));
- if (!e) {
- perror("olsr: adding local route entry");
- return;
+ /* 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;
+ }
}
e->destination = neighbors[i];
+ e->link_type = OLSRLINK_SYMMETRIC;
e->time_left = (OLSR_MSG_INTERVAL << 2);
- e->gateway = NULL;
+ e->gateway = 0U;
e->iface = iface;
e->metric = 1;
e->next = Routes[1];
@@ -118,7 +158,7 @@
}
e->destination = addr->address;
e->time_left = (OLSR_MSG_INTERVAL << 2);
- e->gateway = NULL;
+ e->gateway = 0U;
e->iface = icur;
e->metric = 0;
e->next = Routes[0];
@@ -139,6 +179,7 @@
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);
@@ -258,14 +299,79 @@
}
}
+static inline void arp_storm(uint32_t addr)
+{
+ int i;
+ for (i = 0; i < settings->n_ifaces; i++) {
+ vder_arp_query(settings->ifaces[i], addr);
+ }
+}
+
+static void recv_hello(uint8_t *buffer, int len, uint32_t origin)
+{
+ struct olsr_link *li;
+ uint32_t *address;
+ struct olsr_route_entry *e;
+ int parsed = 0;
+
+ while (len > parsed) {
+ li = (struct olsr_link *) buffer;
+ address = (uint32_t *)(buffer + parsed + sizeof(struct
olsr_link));
+ parsed += ntohs(li->link_msg_size);
+ e = get_route_by_address(*address);
+ if (!e) {
+ e = malloc(sizeof(struct olsr_route_entry));
+ if (!e) {
+ perror("olsr allocating route");
+ return;
+ }
+ e->time_left = (OLSR_MSG_INTERVAL << 2);
+ e->destination = *address;
+ e->gateway = origin;
+ e->iface = NULL;
+ e->metric = 2;
+ e->next = Routes[2];
+ Routes[2] = 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);
+ }
+ }
+}
+
static void olsr_recv(uint8_t *buffer, int len)
{
struct olsrhdr *oh = (struct olsrhdr *) buffer;
- if (len != oh->len) {
- /* Invalid packet size, silently discard */
+ int parsed = 0;
+ if (len != ntohs(oh->len)) {
return;
}
- /* TODO: Implement parser. */
+ 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);
+ if (!origin) {
+ arp_storm(msg->orig);
+ }
+ switch(msg->type) {
+ case OLSRMSG_HELLO:
+ 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);
+ break;
+ case OLSRMSG_MID:
+ break;
+ case OLSRMSG_TC:
+ break;
+ default:
+ return;
+ }
+ parsed += ntohs(msg->size);
+ }
}
@@ -288,6 +394,7 @@
gettimeofday(&last_out, NULL);
+ refresh_routes();
while(1) {
len = vder_udpsocket_recvfrom(udpsock, buffer,
(OLSR_MSG_INTERVAL >> 1), &from_ip, &from_port, -1);
Modified: branches/vde-router/vde-2/src/vde_router/vder_packet.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_packet.c 2012-01-20
06:44:59 UTC (rev 535)
+++ branches/vde-router/vde-2/src/vde_router/vder_packet.c 2012-01-21
15:46:56 UTC (rev 536)
@@ -102,6 +102,8 @@
struct vder_route *ro;
struct vder_arp_entry *ae;
+ uint32_t destination = dst_ip;
+
eth->buftype = htons(PTYPE_IP);
memset(iph,0x45,1);
@@ -115,11 +117,15 @@
ro = vder_get_route(dst_ip);
if (!ro)
return -1;
- iph->saddr = vder_get_right_localip(ro->iface, iph->daddr);
+
+ if (ro->gateway != 0) {
+ destination = ro->gateway;
+ }
+ iph->saddr = vder_get_right_localip(ro->iface, destination);
iph->check = htons(vder_ip_checksum(iph));
- ae = vder_get_arp_entry(ro->iface, iph->daddr);
+ ae = vder_get_arp_entry(ro->iface, destination);
if (!ae) {
- vder_arp_query(ro->iface, iph->daddr);
+ vder_arp_query(ro->iface, destination);
return -1;
}
return vder_sendto(ro->iface, vdb, ae->macaddr);
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