diff options
Diffstat (limited to 'net/ipv6/sit.c')
-rw-r--r-- | net/ipv6/sit.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b6b16264b305..2362a3397e91 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -1145,16 +1145,19 @@ static struct xfrm_tunnel sit_handler = { | |||
1145 | .priority = 1, | 1145 | .priority = 1, |
1146 | }; | 1146 | }; |
1147 | 1147 | ||
1148 | static void sit_destroy_tunnels(struct sit_net *sitn) | 1148 | static void sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) |
1149 | { | 1149 | { |
1150 | int prio; | 1150 | int prio; |
1151 | 1151 | ||
1152 | for (prio = 1; prio < 4; prio++) { | 1152 | for (prio = 1; prio < 4; prio++) { |
1153 | int h; | 1153 | int h; |
1154 | for (h = 0; h < HASH_SIZE; h++) { | 1154 | for (h = 0; h < HASH_SIZE; h++) { |
1155 | struct ip_tunnel *t; | 1155 | struct ip_tunnel *t = sitn->tunnels[prio][h]; |
1156 | while ((t = sitn->tunnels[prio][h]) != NULL) | 1156 | |
1157 | unregister_netdevice(t->dev); | 1157 | while (t != NULL) { |
1158 | unregister_netdevice_queue(t->dev, head); | ||
1159 | t = t->next; | ||
1160 | } | ||
1158 | } | 1161 | } |
1159 | } | 1162 | } |
1160 | } | 1163 | } |
@@ -1208,11 +1211,13 @@ err_alloc: | |||
1208 | static void sit_exit_net(struct net *net) | 1211 | static void sit_exit_net(struct net *net) |
1209 | { | 1212 | { |
1210 | struct sit_net *sitn; | 1213 | struct sit_net *sitn; |
1214 | LIST_HEAD(list); | ||
1211 | 1215 | ||
1212 | sitn = net_generic(net, sit_net_id); | 1216 | sitn = net_generic(net, sit_net_id); |
1213 | rtnl_lock(); | 1217 | rtnl_lock(); |
1214 | sit_destroy_tunnels(sitn); | 1218 | sit_destroy_tunnels(sitn, &list); |
1215 | unregister_netdevice(sitn->fb_tunnel_dev); | 1219 | unregister_netdevice_queue(sitn->fb_tunnel_dev, &list); |
1220 | unregister_netdevice_many(&list); | ||
1216 | rtnl_unlock(); | 1221 | rtnl_unlock(); |
1217 | kfree(sitn); | 1222 | kfree(sitn); |
1218 | } | 1223 | } |