root/drivers/net/new_tunnel.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tunnel_open
  2. tunnel_close
  3. print_ip
  4. tunnel_xmit
  5. tunnel_get_stats
  6. tunnel_init
  7. tunnel_probe
  8. init_module
  9. cleanup_module

   1 /* tunnel.c: an IP tunnel driver
   2 
   3         The purpose of this driver is to provide an IP tunnel through
   4         which you can tunnel network traffic transparently across subnets.
   5 
   6         This was written by looking at Nick Holloway's dummy driver
   7         Thanks for the great code!
   8 
   9                 -Sam Lantinga   (slouken@cs.ucdavis.edu)  02/01/95
  10                 
  11         Minor tweaks:
  12                 Cleaned up the code a little and added some pre-1.3.0 tweaks.
  13                 dev->hard_header/hard_header_len changed to use no headers.
  14                 Comments/bracketing tweaked.
  15                 Made the tunnels use dev->name not tunnel: when error reporting.
  16                 Added tx_dropped stat
  17                 
  18                 -Alan Cox       (Alan.Cox@linux.org) 21 March 95
  19 
  20         Reworked:
  21                 Changed to tunnel to destination gateway instead of pointopoint
  22                 Almost completely rewritten
  23                 Note:  There is currently no firewall or ICMP handling done.
  24 
  25                 -Sam Lantinga   (slouken@cs.ucdavis.edu) 02/13/96
  26                 
  27         Note:
  28                 The old driver is in tunnel.c if you have funnies with the
  29                 new one.
  30 */
  31 
  32 /* Things I wish I had known when writing the tunnel driver:
  33 
  34         When the tunnel_xmit() function is called, the skb contains the
  35         packet to be sent (plus a great deal of extra info), and dev
  36         contains the tunnel device that _we_ are.
  37 
  38         When we are passed a packet, we are expected to fill in the
  39         source address with our source IP address.
  40 
  41         What is the proper way to allocate, copy and free a buffer?
  42         After you allocate it, it is a "0 length" chunk of memory
  43         starting at zero.  If you want to add headers to the buffer
  44         later, you'll have to call "skb_reserve(skb, amount)" with
  45         the amount of memory you want reserved.  Then, you call
  46         "skb_put(skb, amount)" with the amount of space you want in
  47         the buffer.  skb_put() returns a pointer to the top (#0) of
  48         that buffer.  skb->len is set to the amount of space you have
  49         "allocated" with skb_put().  You can then write up to skb->len
  50         bytes to that buffer.  If you need more, you can call skb_put()
  51         again with the additional amount of space you need.  You can
  52         find out how much more space you can allocate by calling 
  53         "skb_tailroom(skb)".
  54         Now, to add header space, call "skb_push(skb, header_len)".
  55         This creates space at the beginning of the buffer and returns
  56         a pointer to this new space.  If later you need to strip a
  57         header from a buffer, call "skb_pull(skb, header_len)".
  58         skb_headroom() will return how much space is left at the top
  59         of the buffer (before the main data).  Remember, this headroom
  60         space must be reserved before the skb_put() function is called.
  61 */
  62 
  63 #include <linux/module.h>
  64 
  65 /* Only two headers!! :-) */
  66 #include <net/ip.h>
  67 #include <linux/if_arp.h>
  68 
  69 
  70 /*#define TUNNEL_DEBUG*/
  71 
  72 /* 
  73  *      Our header is a simple IP packet with no options
  74  */
  75  
  76 #define tunnel_hlen     sizeof(struct iphdr)
  77 
  78 /*
  79  *      Okay, this needs to be high enough that we can fit a "standard"
  80  *      ethernet header and an IP tunnel header into the outgoing packet.
  81  *      [36 bytes]
  82  */
  83  
  84 #define TUNL_HLEN       (((ETH_HLEN+15)&~15)+tunl_hlen)
  85 
  86 
  87 #ifdef MODULE
  88 static int tunnel_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90         MOD_INC_USE_COUNT;
  91         return 0;
  92 }
  93 
  94 static int tunnel_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  95 {
  96         MOD_DEC_USE_COUNT;
  97         return 0;
  98 }
  99 
 100 #endif
 101 
 102 #ifdef TUNNEL_DEBUG
 103 void print_ip(struct iphdr *ip)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105         unsigned char *ipaddr;
 106 
 107         printk("IP packet:\n");
 108         printk("--- header len = %d\n", ip->ihl*4);
 109         printk("--- ip version: %d\n", ip->version);
 110         printk("--- ip protocol: %d\n", ip->protocol);
 111         ipaddr=(unsigned char *)&ip->saddr;
 112         printk("--- source address: %u.%u.%u.%u\n", 
 113                         *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
 114         ipaddr=(unsigned char *)&ip->daddr;
 115         printk("--- destination address: %u.%u.%u.%u\n", 
 116                         *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
 117         printk("--- total packet len: %d\n", ntohs(ip->tot_len));
 118 }
 119 #endif
 120 
 121 /*
 122  *      This function assumes it is being called from dev_queue_xmit()
 123  *      and that skb is filled properly by that function.
 124  */
 125 
 126 static int tunnel_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         struct enet_statistics *stats;          /* This device's statistics */
 129         struct rtable *rt;                      /* Route to the other host */
 130         struct device *tdev;                    /* Device to other host */
 131         struct iphdr  *iph;                     /* Our new IP header */
 132         __u32          target;                  /* The other host's IP address */
 133         int      max_headroom;                  /* The extra header space needed */
 134 
 135         /*
 136          *      Return if there is nothing to do.  (Does this ever happen?)
 137          */
 138         if (skb == NULL || dev == NULL) {
 139 #ifdef TUNNEL_DEBUG
 140                 printk ( KERN_INFO "tunnel: Nothing to do!\n" );
 141 #endif
 142                 return 0;
 143         }
 144 
 145         /* 
 146          *      Make sure we are not busy (check lock variable) 
 147          */
 148          
 149         stats = (struct enet_statistics *)dev->priv;
 150         cli();
 151         if (dev->tbusy != 0) 
 152         {
 153                 sti();
 154                 stats->tx_errors++;
 155                 return(1);
 156         }
 157         dev->tbusy = 1;
 158         sti();
 159   
 160         /*printk("-");*/
 161         /*
 162          *  First things first.  Look up the destination address in the 
 163          *  routing tables
 164          */
 165         iph = (struct iphdr *) skb->data;
 166         if ((rt = ip_rt_route(iph->daddr, 0)) == NULL)
 167         { 
 168                 /* No route to host */
 169                 /* Where did the packet come from? */
 170                 /*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
 171                 printk ( KERN_INFO "%s: Packet with no route!\n", dev->name );
 172                 dev->tbusy=0;
 173                 stats->tx_errors++;
 174                 return(1);
 175         }
 176 
 177         if (!(rt->rt_flags & RTF_GATEWAY))
 178         { 
 179                 /* No gateway to tunnel through? */
 180                 /* Where did the packet come from? */
 181                 /*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
 182                 printk ( KERN_INFO "%s: Packet with no target gateway!\n", dev->name);
 183                 ip_rt_put(rt);
 184                 dev->tbusy=0;
 185                 stats->tx_errors++;
 186                 return(1);
 187         }
 188         target = rt->rt_gateway;
 189         ip_rt_put(rt);
 190 
 191         if ((rt = ip_rt_route(target, 0)) == NULL)
 192         { 
 193                 /* No route to host */
 194                 /* Where did the packet come from? */
 195                 /*icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);*/
 196                 printk ( KERN_INFO "%s: Can't reach target gateway!\n", dev->name);
 197                 dev->tbusy=0;
 198                 stats->tx_errors++;
 199                 return(1);
 200         }
 201         tdev = rt->rt_dev;
 202 
 203         if (tdev == dev)
 204         { 
 205                 /* Tunnel to ourselves?  -- I don't think so. */
 206                 printk ( KERN_INFO "%s: Packet targetted at myself!\n" ,dev->name);
 207                 ip_rt_put(rt);
 208                 dev->tbusy=0;
 209                 stats->tx_errors++;
 210                 return(1);
 211         }
 212 
 213 #ifdef TUNNEL_DEBUG
 214         printk("Old IP Header....\n");
 215         print_ip(iph);
 216 #endif
 217 
 218         /*
 219          * Okay, now see if we can stuff it in the buffer as-is.
 220          */
 221         max_headroom = ((tunnel_hlen+tdev->hard_header_len+15)&~15);
 222 #ifdef TUNNEL_DEBUG
 223 printk("Room left at head: %d\n", skb_headroom(skb));
 224 printk("Room left at tail: %d\n", skb_tailroom(skb));
 225 printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
 226 #endif
 227         if (skb_headroom(skb) >= max_headroom) {
 228                 skb->h.iph = (struct iphdr *) skb_push(skb, tunnel_hlen);
 229         } else {
 230                 struct sk_buff *new_skb;
 231 
 232                 if ( !(new_skb = dev_alloc_skb(skb->len+max_headroom)) ) 
 233                 {
 234                         printk( KERN_INFO "%s: Out of memory, dropped packet\n",
 235                                 dev->name);
 236                         ip_rt_put(rt);
 237                         dev->tbusy = 0;
 238                         stats->tx_dropped++;
 239                         return(1);
 240                 }
 241                 new_skb->free = 1;
 242 
 243                 /*
 244                  * Reserve space for our header
 245                  */
 246                 skb_reserve(new_skb, tunnel_hlen);
 247                 new_skb->h.iph = (struct iphdr *) skb_push(new_skb, tunnel_hlen);
 248                 /*
 249                  * Copy the old packet to the new buffer.
 250                  * Note that new_skb->h.iph is our (tunnel driver's) header
 251                  * and new_skb->ip_hdr is the IP header of the old packet.
 252                  */
 253                 new_skb->ip_hdr = (struct iphdr *) skb_put(new_skb, skb->len);
 254                 memcpy(new_skb->ip_hdr, skb->data, skb->len);
 255                 /* Is this necessary? */
 256                 memcpy(new_skb->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
 257 
 258                 /* Free the old packet, we no longer need it */
 259                 kfree_skb(skb, FREE_WRITE);
 260                 skb = new_skb;
 261         }
 262 
 263         /*
 264          *      Push down and install the IPIP header.
 265          */
 266         iph = skb->h.iph;
 267         iph->version    =       4;
 268         iph->tos                =       skb->ip_hdr->tos;
 269         iph->ttl                =       skb->ip_hdr->ttl;
 270         iph->frag_off           =       0;
 271         iph->daddr              =       target;
 272         iph->saddr              =       tdev->pa_addr;
 273         iph->protocol           =       IPPROTO_IPIP;
 274         iph->ihl                =       5;
 275         iph->tot_len            =       htons(skb->len);
 276         iph->id                 =       htons(ip_id_count++);   /* Race condition here? */
 277         ip_send_check(iph);
 278         skb->ip_hdr = skb->h.iph;
 279 
 280 #ifdef TUNNEL_DEBUG
 281         printk("New IP Header....\n");
 282         print_ip(iph);
 283 #endif
 284 
 285         /*
 286          *      Send the packet on its way!
 287          *      Note that dev_queue_xmit() will eventually free the skb.
 288          *      If ip_forward() made a copy, it will return 1 so we can free.
 289          */
 290 
 291         if (ip_forward(skb, dev, 0, target) == 1)
 292                 kfree_skb(skb, FREE_WRITE);
 293 
 294         /*
 295          *      Clean up:  We're done with the route and the packet
 296          */
 297          
 298         ip_rt_put(rt);
 299  
 300 #ifdef TUNNEL_DEBUG
 301         printk("Packet sent through tunnel interface!\n");
 302 #endif
 303 /*printk(">");*/
 304         /* Record statistics and return */
 305         stats->tx_packets++;
 306         dev->tbusy=0;
 307         return 0;
 308 }
 309 
 310 static struct enet_statistics *
 311 tunnel_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313         return((struct enet_statistics*) dev->priv);
 314 }
 315 
 316 /*
 317  *      Called when a new tunnel device is initialized.
 318  *      The new tunnel device structure is passed to us.
 319  */
 320  
 321 int tunnel_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 322 {
 323         int i;
 324 
 325         /* Oh, just say we're here, in case anyone cares */
 326         static int tun_msg=0;
 327         if(!tun_msg)
 328         {
 329                 printk ( KERN_INFO "tunnel: version v0.2b\n" );
 330                 tun_msg=1;
 331         }
 332 
 333         /* Add our tunnel functions to the device */
 334 #ifdef MODULE
 335         dev->open               = tunnel_open;
 336         dev->stop               = tunnel_close;
 337 #endif
 338         dev->hard_start_xmit    = tunnel_xmit;
 339         dev->get_stats          = tunnel_get_stats;
 340         dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
 341         if (dev->priv == NULL)
 342                 return -ENOMEM;
 343         memset(dev->priv, 0, sizeof(struct enet_statistics));
 344 
 345         /* Initialize the tunnel device structure */
 346         for (i = 0; i < DEV_NUMBUFFS; i++)
 347                 skb_queue_head_init(&dev->buffs[i]);
 348 
 349         dev->hard_header        = NULL;
 350         dev->rebuild_header     = NULL;
 351         dev->set_mac_address    = NULL;
 352         dev->header_cache_bind  = NULL;
 353         dev->header_cache_update= NULL;
 354 
 355         dev->type                               = ARPHRD_TUNNEL;
 356         dev->hard_header_len    = (tunnel_hlen+ETH_HLEN);
 357         dev->mtu                = 1500-tunnel_hlen;     /* eth_mtu */
 358         dev->addr_len           = 0;            /* Is this only for ARP? */
 359         dev->tx_queue_len       = 2;            /* Small queue */
 360 
 361         /* it should all run through */
 362         memset(dev->broadcast,0xFF, ETH_ALEN);
 363 
 364         /* New-style flags. */
 365         dev->flags              = IFF_NOARP;    /* Don't use ARP on this device */
 366                                                 /* No broadcasting through a tunnel */
 367         dev->family             = AF_INET;
 368         dev->pa_addr            = 0;
 369         dev->pa_brdaddr         = 0;
 370         dev->pa_mask            = 0;
 371         dev->pa_alen            = 4;
 372 
 373         /* We're done.  Have I forgotten anything? */
 374         return 0;
 375 }
 376 
 377 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 378 /*  Module specific interface                                      */
 379 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 380 #ifdef MODULE
 381 
 382 static int tunnel_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 383 {
 384         tunnel_init(dev);
 385         return 0;
 386 }
 387 
 388 static struct device dev_tunnel = {
 389         "tunl0\0   ", 
 390         0, 0, 0, 0,
 391         0x0, 0,
 392         0, 0, 0, NULL, tunnel_probe };
 393 
 394 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 395 {
 396         /* Find a name for this unit */
 397         int ct= 1;
 398         
 399         while(dev_get(dev_tunnel.name)!=NULL && ct<100)
 400         {
 401                 sprintf(dev_tunnel.name,"tunl%d",ct);
 402                 ct++;
 403         }
 404         
 405 #ifdef TUNNEL_DEBUG
 406         printk("tunnel: registering device %s\n", dev_tunnel.name);
 407 #endif
 408         if (register_netdev(&dev_tunnel) != 0)
 409                 return -EIO;
 410         return 0;
 411 }
 412 
 413 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 414 {
 415         unregister_netdev(&dev_tunnel);
 416         kfree_s(dev_tunnel.priv,sizeof(struct enet_statistics));
 417         dev_tunnel.priv=NULL;
 418 }
 419 #endif /* MODULE */
 420 
 421 
 422 
 423 
 424  
 425 
 426 
 427 

/* [previous][next][first][last][top][bottom][index][help] */