]>
Commit | Line | Data |
---|---|---|
d18e3846 JR |
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; |