mac80211: make master netdev handling sane
[safe/jmp/linux-2.6] / net / mac80211 / iface.c
1 /*
2  * Copyright 2002-2005, Instant802 Networks, Inc.
3  * Copyright 2005-2006, Devicescape Software, Inc.
4  * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/kernel.h>
11 #include <linux/if_arp.h>
12 #include <linux/netdevice.h>
13 #include <linux/rtnetlink.h>
14 #include <net/mac80211.h>
15 #include "ieee80211_i.h"
16 #include "sta_info.h"
17 #include "debugfs_netdev.h"
18 #include "mesh.h"
19
20 void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
21 {
22         int i;
23
24         /* Default values for sub-interface parameters */
25         sdata->drop_unencrypted = 0;
26         for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
27                 skb_queue_head_init(&sdata->fragments[i].skb_list);
28
29         INIT_LIST_HEAD(&sdata->key_list);
30
31         sdata->force_unicast_rateidx = -1;
32         sdata->max_ratectrl_rateidx = -1;
33 }
34
35 static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata)
36 {
37         int i;
38
39         for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
40                 __skb_queue_purge(&sdata->fragments[i].skb_list);
41 }
42
43 /* Must be called with rtnl lock held. */
44 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
45                      struct net_device **new_dev, int type,
46                      struct vif_params *params)
47 {
48         struct net_device *ndev;
49         struct ieee80211_sub_if_data *sdata = NULL;
50         int ret;
51
52         ASSERT_RTNL();
53         ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size,
54                             name, ieee80211_if_setup);
55         if (!ndev)
56                 return -ENOMEM;
57
58         ndev->needed_headroom = local->tx_headroom +
59                                 4*6 /* four MAC addresses */
60                                 + 2 + 2 + 2 + 2 /* ctl, dur, seq, qos */
61                                 + 6 /* mesh */
62                                 + 8 /* rfc1042/bridge tunnel */
63                                 - ETH_HLEN /* ethernet hard_header_len */
64                                 + IEEE80211_ENCRYPT_HEADROOM;
65         ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM;
66
67         ret = dev_alloc_name(ndev, ndev->name);
68         if (ret < 0)
69                 goto fail;
70
71         memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
72         SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
73
74         /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
75         sdata = netdev_priv(ndev);
76         ndev->ieee80211_ptr = &sdata->wdev;
77         sdata->wdev.wiphy = local->hw.wiphy;
78         sdata->vif.type = IEEE80211_IF_TYPE_AP;
79         sdata->dev = ndev;
80         sdata->local = local;
81         ieee80211_if_sdata_init(sdata);
82
83         ret = register_netdevice(ndev);
84         if (ret)
85                 goto fail;
86
87         ieee80211_debugfs_add_netdev(sdata);
88         ieee80211_if_set_type(ndev, type);
89
90         if (ieee80211_vif_is_mesh(&sdata->vif) &&
91             params && params->mesh_id_len)
92                 ieee80211_if_sta_set_mesh_id(&sdata->u.sta,
93                                              params->mesh_id_len,
94                                              params->mesh_id);
95
96         /* we're under RTNL so all this is fine */
97         if (unlikely(local->reg_state == IEEE80211_DEV_UNREGISTERED)) {
98                 __ieee80211_if_del(local, sdata);
99                 return -ENODEV;
100         }
101         list_add_tail_rcu(&sdata->list, &local->interfaces);
102
103         if (new_dev)
104                 *new_dev = ndev;
105
106         return 0;
107
108 fail:
109         free_netdev(ndev);
110         return ret;
111 }
112
113 void ieee80211_if_set_type(struct net_device *dev, int type)
114 {
115         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
116         int oldtype = sdata->vif.type;
117
118         /*
119          * Called even when register_netdevice fails, it would
120          * oops if assigned before initialising the rest.
121          */
122         dev->uninit = ieee80211_if_reinit;
123
124         /* most have no BSS pointer */
125         sdata->bss = NULL;
126         sdata->vif.type = type;
127
128         sdata->basic_rates = 0;
129
130         switch (type) {
131         case IEEE80211_IF_TYPE_WDS:
132         case IEEE80211_IF_TYPE_VLAN:
133                 /* nothing special */
134                 break;
135         case IEEE80211_IF_TYPE_AP:
136                 skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
137                 INIT_LIST_HEAD(&sdata->u.ap.vlans);
138                 break;
139         case IEEE80211_IF_TYPE_MESH_POINT:
140         case IEEE80211_IF_TYPE_STA:
141         case IEEE80211_IF_TYPE_IBSS: {
142                 struct ieee80211_if_sta *ifsta;
143
144                 ifsta = &sdata->u.sta;
145                 INIT_WORK(&ifsta->work, ieee80211_sta_work);
146                 setup_timer(&ifsta->timer, ieee80211_sta_timer,
147                             (unsigned long) sdata);
148                 skb_queue_head_init(&ifsta->skb_queue);
149
150                 ifsta->capab = WLAN_CAPABILITY_ESS;
151                 ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
152                         IEEE80211_AUTH_ALG_SHARED_KEY;
153                 ifsta->flags |= IEEE80211_STA_CREATE_IBSS |
154                         IEEE80211_STA_AUTO_BSSID_SEL |
155                         IEEE80211_STA_AUTO_CHANNEL_SEL;
156                 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
157                         ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
158
159                 if (ieee80211_vif_is_mesh(&sdata->vif))
160                         ieee80211_mesh_init_sdata(sdata);
161                 break;
162         }
163         case IEEE80211_IF_TYPE_MNTR:
164                 dev->type = ARPHRD_IEEE80211_RADIOTAP;
165                 dev->hard_start_xmit = ieee80211_monitor_start_xmit;
166                 sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
167                                       MONITOR_FLAG_OTHER_BSS;
168                 break;
169         case IEEE80211_IF_TYPE_INVALID:
170                 BUG();
171                 break;
172         }
173         ieee80211_debugfs_change_if_type(sdata, oldtype);
174 }
175
176 /* Must be called with rtnl lock held. */
177 void ieee80211_if_reinit(struct net_device *dev)
178 {
179         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
180         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
181         struct sk_buff *skb;
182         int flushed;
183
184         ASSERT_RTNL();
185
186         ieee80211_free_keys(sdata);
187
188         ieee80211_if_sdata_deinit(sdata);
189
190         /* Need to handle mesh specially to allow eliding the function call */
191         if (ieee80211_vif_is_mesh(&sdata->vif))
192                 mesh_rmc_free(dev);
193
194         switch (sdata->vif.type) {
195         case IEEE80211_IF_TYPE_INVALID:
196                 /* cannot happen */
197                 WARN_ON(1);
198                 break;
199         case IEEE80211_IF_TYPE_AP: {
200                 struct beacon_data *beacon;
201
202                 beacon = sdata->u.ap.beacon;
203                 rcu_assign_pointer(sdata->u.ap.beacon, NULL);
204                 synchronize_rcu();
205                 kfree(beacon);
206
207                 while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
208                         local->total_ps_buffered--;
209                         dev_kfree_skb(skb);
210                 }
211
212                 break;
213         }
214         case IEEE80211_IF_TYPE_WDS:
215         case IEEE80211_IF_TYPE_VLAN:
216                 /* nothing to do */
217                 break;
218         case IEEE80211_IF_TYPE_MESH_POINT:
219         case IEEE80211_IF_TYPE_STA:
220         case IEEE80211_IF_TYPE_IBSS:
221                 kfree(sdata->u.sta.extra_ie);
222                 sdata->u.sta.extra_ie = NULL;
223                 kfree(sdata->u.sta.assocreq_ies);
224                 sdata->u.sta.assocreq_ies = NULL;
225                 kfree(sdata->u.sta.assocresp_ies);
226                 sdata->u.sta.assocresp_ies = NULL;
227                 if (sdata->u.sta.probe_resp) {
228                         dev_kfree_skb(sdata->u.sta.probe_resp);
229                         sdata->u.sta.probe_resp = NULL;
230                 }
231
232                 break;
233         case IEEE80211_IF_TYPE_MNTR:
234                 dev->type = ARPHRD_ETHER;
235                 break;
236         }
237
238         flushed = sta_info_flush(local, sdata);
239         WARN_ON(flushed);
240
241         memset(&sdata->u, 0, sizeof(sdata->u));
242         ieee80211_if_sdata_init(sdata);
243 }
244
245 /* Must be called with rtnl lock held. */
246 void __ieee80211_if_del(struct ieee80211_local *local,
247                         struct ieee80211_sub_if_data *sdata)
248 {
249         struct net_device *dev = sdata->dev;
250
251         ieee80211_debugfs_remove_netdev(sdata);
252         unregister_netdevice(dev);
253         /*
254          * The net_device will be freed by its destructor,
255          * i.e. ieee80211_if_free.
256          */
257 }
258
259 /* Must be called with rtnl lock held. */
260 int ieee80211_if_remove(struct net_device *dev, const char *name, int id)
261 {
262         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
263         struct ieee80211_sub_if_data *sdata, *n;
264
265         ASSERT_RTNL();
266
267         list_for_each_entry_safe(sdata, n, &local->interfaces, list) {
268                 if ((sdata->vif.type == id || id == -1) &&
269                     strcmp(name, sdata->dev->name) == 0) {
270                         list_del_rcu(&sdata->list);
271                         synchronize_rcu();
272                         __ieee80211_if_del(local, sdata);
273                         return 0;
274                 }
275         }
276         return -ENODEV;
277 }
278
279 void ieee80211_if_free(struct net_device *dev)
280 {
281         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
282
283         ieee80211_if_sdata_deinit(sdata);
284         free_netdev(dev);
285 }