]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.22-tun-new-style.patch
- [2.4.2x, 2.6.x] don't recursively crash in die() on CHRP/PReP machines
[packages/kernel.git] / linux-2.4.22-tun-new-style.patch
1
2   "new style" netdevice allocation patch for TUN driver (2.4.18 kernel)
3
4 From: Jacek Konieczny (jajcus@pld.org.pl)
5 Date: Thu Aug 01 2002 - 08:35:06 EST
6
7 I had a lot of problem with tun devices created with both openvpn and
8 vtund. When I wanted to shut down my system when the devices were in
9 use (eg. TCP connection established on tun0 interface), even if the
10 tunneling daemon was killed, it stopped while trying to deconfigure
11 network. And "unregister_netdevice: waiting for tun0 to become free"
12 message was displayed again and again. I tried to resolve this problem
13 using Google, but I have only found out, that this is behaviour of 2.4
14 kernels, and that it is proper. After further investigation, in kernel
15 sources, I found out, that there are "old style" and "new style" network
16 devices, and that only the "old style" devices have this problem.
17 I had similar problem with VLAN devices some time ago, so I checked VLAN
18 driver sources too. As I suspected, it was "new style" device now.
19 The patch below is my try to make tun device "new style" too. It seems
20 to work for me, but I am not sure if it is 100% proper. This is patch
21 against 2.4.18 sources.
22
23 Sorry, for spamming all those addresses, but I am not sure which one is
24 correct. Driver on URL given in MAINTAINERS file seems to be a bit
25 outdated.
26
27 Greets,
28         Jacek
29
30 diff -ur linux-2.4.22-up/drivers/net/tun.c linux-2.4.22-tun/drivers/net/tun.c
31 --- linux-2.4.22-up/drivers/net/tun.c   Sat Aug  3 02:39:44 2002
32 +++ linux-2.4.22-tun/drivers/net/tun.c  Sun Sep 21 00:08:08 2003
33 @@ -20,6 +20,14 @@
34   *    Modifications for 2.3.99-pre5 kernel.
35   */
36  
37 +/*
38 + * 01.08.2002
39 + * Jacek Konieczny <jajcus@pld.org.pl>
40 + * Modifications for "new style" device allocation
41 + * (fixes "wating for tunX to become free" problem)
42 + */
43 +
44 +
45  #define TUN_VER "1.5"
46  
47  #include <linux/config.h>
48 @@ -159,6 +167,17 @@
49         return 0;
50  }
51  
52 +void tun_net_destruct(struct net_device *dev)
53 +{
54 +       if (dev) {
55 +               if (dev->priv) {
56 +                       kfree(dev->priv);
57 +                       dev->priv=NULL;
58 +                       MOD_DEC_USE_COUNT;
59 +               }
60 +       }
61 +}
62 +
63  /* Character device part */
64  
65  /* Poll */
66 @@ -202,14 +221,14 @@
67         skb_reserve(skb, 2);
68         memcpy_fromiovec(skb_put(skb, len), iv, len);
69  
70 -       skb->dev = &tun->dev;
71 +       skb->dev = tun->dev;
72         switch (tun->flags & TUN_TYPE_MASK) {
73         case TUN_TUN_DEV:
74                 skb->mac.raw = skb->data;
75                 skb->protocol = pi.proto;
76                 break;
77         case TUN_TAP_DEV:
78 -               skb->protocol = eth_type_trans(skb, &tun->dev);
79 +               skb->protocol = eth_type_trans(skb, tun->dev);
80                 break;
81         };
82  
83 @@ -326,7 +345,7 @@
84                         schedule();
85                         continue;
86                 }
87 -               netif_start_queue(&tun->dev);
88 +               netif_start_queue(tun->dev);
89  
90                 ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
91  
92 @@ -378,8 +397,6 @@
93                 init_waitqueue_head(&tun->read_wait);
94  
95                 tun->owner = -1;
96 -               tun->dev.init = tun_net_init;
97 -               tun->dev.priv = tun;
98  
99                 err = -EINVAL;
100  
101 @@ -398,18 +415,24 @@
102                 if (*ifr->ifr_name)
103                         name = ifr->ifr_name;
104  
105 -               if ((err = dev_alloc_name(&tun->dev, name)) < 0)
106 +               dev = dev_alloc(name, &err);
107 +               if (!dev)
108                         goto failed;
109 -               if ((err = register_netdevice(&tun->dev)))
110 +
111 +               tun->dev=dev;
112 +               dev->init = tun_net_init;
113 +               dev->priv = tun;
114 +               dev->destructor = tun_net_destruct;
115 +               dev->features |= NETIF_F_DYNALLOC;
116 +               tun->name = dev->name;
117 +
118 +               err=register_netdevice(dev);
119 +               if (err<0)
120                         goto failed;
121 -       
122 -               MOD_INC_USE_COUNT;
123  
124 -               tun->name = tun->dev.name;
125 +               MOD_INC_USE_COUNT;
126         }
127  
128 -       DBG(KERN_INFO "%s: tun_set_iff\n", tun->name);
129 -
130         if (ifr->ifr_flags & IFF_NO_PI)
131                 tun->flags |= TUN_NO_PI;
132  
133 @@ -423,6 +446,7 @@
134         return 0;
135  
136  failed:
137 +       kfree(dev);
138         kfree(tun);
139         return err;
140  }
141 @@ -553,10 +577,8 @@
142         skb_queue_purge(&tun->readq);
143  
144         if (!(tun->flags & TUN_PERSIST)) {
145 -               dev_close(&tun->dev);
146 -               unregister_netdevice(&tun->dev);
147 -               kfree(tun);
148 -               MOD_DEC_USE_COUNT;
149 +               dev_close(tun->dev);
150 +               unregister_netdevice(tun->dev);
151         }
152  
153         rtnl_unlock();
154 diff -ur linux-2.4.22-up/include/linux/if_tun.h linux-2.4.22-tun/include/linux/if_tun.h
155 --- linux-2.4.22-up/include/linux/if_tun.h      Tue Jun 12 04:15:27 2001
156 +++ linux-2.4.22-tun/include/linux/if_tun.h     Sun Sep 21 00:08:08 2003
157 @@ -40,7 +40,7 @@
158         wait_queue_head_t       read_wait;
159         struct sk_buff_head     readq;
160  
161 -       struct net_device       dev;
162 +       struct net_device       *dev;
163         struct net_device_stats stats;
164  
165         struct fasync_struct    *fasync;
This page took 0.035321 seconds and 3 git commands to generate.