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