Changeset 1542

Show
Ignore:
Timestamp:
01/09/10 15:44:01 (7 months ago)
Author:
marek
Message:

batman-adv: send DHCP requests directly to the chosen gw

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 <lindner_marek@…>

Location:
trunk/batman-adv-kernelland
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/batman-adv-kernelland/gateway_client.c

    r1540 r1542  
    2121#include "gateway_client.h" 
    2222#include "gateway_common.h" 
     23#include <linux/ip.h> 
     24#include <linux/udp.h> 
    2325 
    2426LIST_HEAD(gw_list); 
     
    2729atomic_t gw_clnt_class; 
    2830static struct gw_node *curr_gateway; 
     31 
     32void *gw_get_selected(void) 
     33{ 
     34        struct gw_node *curr_gateway_tmp = NULL; 
     35 
     36        spin_lock(&curr_gw_lock); 
     37        curr_gateway_tmp = curr_gateway; 
     38        spin_unlock(&curr_gw_lock); 
     39 
     40        if (!curr_gateway_tmp) 
     41                return NULL; 
     42 
     43        return curr_gateway_tmp->orig_node; 
     44} 
    2945 
    3046void gw_deselect(void) 
     
    334350        return bytes_written; 
    335351} 
     352 
     353bool gw_is_target(struct sk_buff *skb) 
     354{ 
     355        struct ethhdr *ethhdr; 
     356        struct iphdr *iphdr; 
     357        struct udphdr *udphdr; 
     358 
     359        if (atomic_read(&gw_mode) != GW_MODE_CLIENT) 
     360                return false; 
     361 
     362        if (!curr_gateway) 
     363                return false; 
     364 
     365        ethhdr = (struct ethhdr *)skb->data; 
     366        if (ntohs(ethhdr->h_proto) != ETH_P_IP) 
     367                return false; 
     368 
     369        iphdr = (struct iphdr *)(skb->data + ETH_HLEN); 
     370 
     371        if (iphdr->protocol != IPPROTO_UDP) 
     372                return false; 
     373 
     374        udphdr = (struct udphdr *)(skb->data + ETH_HLEN + (iphdr->ihl * 4)); 
     375 
     376        if (ntohs(udphdr->dest) != 67) 
     377                return false; 
     378 
     379        return true; 
     380} 
  • trunk/batman-adv-kernelland/gateway_client.h

    r1540 r1542  
    2222void gw_deselect(void); 
    2323void gw_election(void); 
     24void *gw_get_selected(void); 
    2425void gw_check_election(struct orig_node *orig_node); 
    2526void gw_node_update(struct orig_node *orig_node, uint8_t new_gwflags); 
     
    2829void gw_node_list_free(void); 
    2930int gw_client_fill_buffer_text(unsigned char *buff, int buff_len); 
     31bool gw_is_target(struct sk_buff *skb); 
  • trunk/batman-adv-kernelland/soft-interface.c

    r1527 r1542  
    2727#include "types.h" 
    2828#include "hash.h" 
     29#include "gateway_client.h" 
    2930#include <linux/ethtool.h> 
    3031#include <linux/etherdevice.h> 
     
    182183        int data_len = skb->len; 
    183184        unsigned long flags; 
     185        bool bcast_dst = false, do_bcast = true; 
    184186 
    185187        if (atomic_read(&module_state) != MODULE_ACTIVE) 
     
    190192        hna_local_add(ethhdr->h_source); 
    191193 
     194        if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) 
     195                bcast_dst = true; 
     196 
     197        if ((bcast_dst) && gw_is_target(skb)) 
     198                do_bcast = false; 
     199 
    192200        /* ethernet packet should be broadcasted */ 
    193         if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { 
    194  
     201        if (bcast_dst && do_bcast) { 
    195202                if (my_skb_push(skb, sizeof(struct bcast_packet)) < 0) 
    196203                        goto dropped; 
     
    220227        } else { 
    221228                spin_lock_irqsave(&orig_hash_lock, flags); 
     229 
    222230                /* get routing information */ 
    223                 orig_node = ((struct orig_node *)hash_find(orig_hash, 
     231                if (bcast_dst) 
     232                        orig_node = (struct orig_node *)gw_get_selected(); 
     233                else 
     234                        orig_node = ((struct orig_node *)hash_find(orig_hash, 
    224235                                                           ethhdr->h_dest)); 
    225236