From patchwork Mon Jan 4 15:46:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Lindner X-Patchwork-Id: 5217 Return-Path: Received: from smtp122.mail.ukl.yahoo.com (smtp122.mail.ukl.yahoo.com [77.238.184.53]) by open-mesh.net (Postfix) with SMTP id BAFD9154258 for ; Mon, 4 Jan 2010 17:08:32 +0100 (CET) Received: (qmail 8159 invoked from network); 4 Jan 2010 15:50:15 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.de; h=Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Cc:Subject:Date:Message-Id:X-Mailer:In-Reply-To:References; b=TpRpEDHYE/KdqPmRMpa+SJwIFJrysgd3XwvEXuk9dSznKI5U2qi7pVqDIPc8KP9xVbMMXgFdqZXXF7SorDNA/1ToVXvdXiB0CJD/pChIghrSv/twq28XY0BXGo2ooyJ/JpGAKcOAsZk77zr0ZyBaGrT0zGXFWDBdTEPNLijT/vg= ; Received: from p57952625.dip.t-dialin.net (lindner_marek@87.149.38.37 with plain) by smtp122.mail.ukl.yahoo.com with SMTP; 04 Jan 2010 15:50:14 +0000 GMT X-Yahoo-SMTP: tW.h3tiswBBMXO2coYcbPigGD5Lt6zY_.Zc- X-YMail-OSG: uiwTYJgVM1nm7SesDw.GCRYlgZKXaZ3VIuizSeRhtLGftgyHUosNcJLCPWyIlxu1cnWYNrIDlwn4wR2xNs6UXff5BEMxYrWqDlZwn6GY_z5SqATl1xf4oim7z6gPNM0phEcYW9wWeEls9MF7sAECoEBZwhii271P_DaImbsXsieSQJ4oVH7tFmx3JL_QhXYdnhWgaDQ1X4RH0ktEHIjZEh_xZr0jaidVeP6VFwSf6_e.qRBcOFLpyyTtg9.055EyYUbJxIW6hQL7BQ-- X-Yahoo-Newman-Property: ymail-3 From: Marek Lindner To: b.a.t.m.a.n@lists.open-mesh.net Date: Mon, 4 Jan 2010 23:46:16 +0800 Message-Id: <1262619976-5632-3-git-send-email-lindner_marek@yahoo.de> X-Mailer: git-send-email 1.6.5.7 In-Reply-To: <1262619976-5632-2-git-send-email-lindner_marek@yahoo.de> References: <201001042344.02273.lindner_marek@yahoo.de> <1262619976-5632-1-git-send-email-lindner_marek@yahoo.de> <1262619976-5632-2-git-send-email-lindner_marek@yahoo.de> Cc: Marek Lindner Subject: [B.A.T.M.A.N.] [PATCH 3/3] batman-adv: send DHCP requests directly to the chosen gw X-BeenThere: b.a.t.m.a.n@lists.open-mesh.net X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Jan 2010 16:08:33 -0000 If the gateway client mode is active batman-adv will send the broadcasted DHCP requests via unicast to the currently selected best gateway. Therefore attached clients can profit from batman's knowledge about the network topology. Signed-off-by: Marek Lindner --- batman-adv-kernelland/gateway_client.c | 45 ++++++++++++++++++++++++++++++++ batman-adv-kernelland/gateway_client.h | 2 + batman-adv-kernelland/soft-interface.c | 17 ++++++++++-- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/batman-adv-kernelland/gateway_client.c b/batman-adv-kernelland/gateway_client.c index 55789ad..434af2b 100644 --- a/batman-adv-kernelland/gateway_client.c +++ b/batman-adv-kernelland/gateway_client.c @@ -20,6 +20,8 @@ #include "main.h" #include "gateway_client.h" #include "gateway_common.h" +#include +#include LIST_HEAD(gw_list); DEFINE_SPINLOCK(curr_gw_lock); @@ -27,6 +29,20 @@ DEFINE_SPINLOCK(gw_list_lock); atomic_t gw_clnt_class; static struct gw_node *curr_gateway; +void *gw_get_selected(void) +{ + struct gw_node *curr_gateway_tmp = NULL; + + spin_lock(&curr_gw_lock); + curr_gateway_tmp = curr_gateway; + spin_unlock(&curr_gw_lock); + + if (!curr_gateway_tmp) + return NULL; + + return curr_gateway_tmp->orig_node; +} + void gw_deselect(void) { spin_lock(&curr_gw_lock); @@ -333,3 +349,32 @@ int gw_client_fill_buffer_text(unsigned char *buff, int buff_len) return bytes_written; } + +bool gw_is_target(struct sk_buff *skb) +{ + struct ethhdr *ethhdr; + struct iphdr *iphdr; + struct udphdr *udphdr; + + if (atomic_read(&gw_mode) != GW_MODE_CLIENT) + return false; + + if (!curr_gateway) + return false; + + ethhdr = (struct ethhdr *)skb->data; + if (ntohs(ethhdr->h_proto) != ETH_P_IP) + return false; + + iphdr = (struct iphdr *)(skb->data + ETH_HLEN); + + if (iphdr->protocol != IPPROTO_UDP) + return false; + + udphdr = (struct udphdr *)(skb->data + ETH_HLEN + (iphdr->ihl * 4)); + + if (ntohs(udphdr->dest) != 67) + return false; + + return true; +} diff --git a/batman-adv-kernelland/gateway_client.h b/batman-adv-kernelland/gateway_client.h index 5eb1e4c..fc7a0df 100644 --- a/batman-adv-kernelland/gateway_client.h +++ b/batman-adv-kernelland/gateway_client.h @@ -21,9 +21,11 @@ extern atomic_t gw_clnt_class; void gw_deselect(void); void gw_election(void); +void *gw_get_selected(void); void gw_check_election(struct orig_node *orig_node); void gw_node_update(struct orig_node *orig_node, uint8_t new_gwflags); void gw_node_delete(struct orig_node *orig_node); void gw_node_purge_deleted(void); void gw_node_list_free(void); int gw_client_fill_buffer_text(unsigned char *buff, int buff_len); +bool gw_is_target(struct sk_buff *skb); diff --git a/batman-adv-kernelland/soft-interface.c b/batman-adv-kernelland/soft-interface.c index ee9aa39..80f7a23 100644 --- a/batman-adv-kernelland/soft-interface.c +++ b/batman-adv-kernelland/soft-interface.c @@ -26,6 +26,7 @@ #include "translation-table.h" #include "types.h" #include "hash.h" +#include "gateway_client.h" #include #include #include "compat.h" @@ -181,6 +182,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) uint8_t dstaddr[6]; int data_len = skb->len; unsigned long flags; + bool bcast_dst = false, do_bcast = true; if (atomic_read(&module_state) != MODULE_ACTIVE) goto dropped; @@ -189,9 +191,14 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) /* TODO: check this for locks */ hna_local_add(ethhdr->h_source); - /* ethernet packet should be broadcasted */ - if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { + if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) + bcast_dst = true; + + if ((bcast_dst) && gw_is_target(skb)) + do_bcast = false; + /* ethernet packet should be broadcasted */ + if (bcast_dst && do_bcast) { if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0) goto dropped; @@ -219,8 +226,12 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev) /* unicast packet */ } else { spin_lock_irqsave(&orig_hash_lock, flags); + /* get routing information */ - orig_node = ((struct orig_node *)hash_find(orig_hash, + if (bcast_dst) + orig_node = (struct orig_node *)gw_get_selected(); + else + orig_node = ((struct orig_node *)hash_find(orig_hash, ethhdr->h_dest)); /* check for hna host */