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

Reply via email to