diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-12-19 17:45:58 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-12-19 18:06:55 -0500 |
commit | bd37a78de91e1b67b540b43f10bbb2d552348cbd (patch) | |
tree | 885491af401b6f29f733ea8ca1adc2cb0ad20d0e /net/mac802154 | |
parent | 405a26110a735b88963875459efe63f4d274f49d (diff) |
mac802154: iface: check concurrent ifaces
This patch adds a check for concurrent interfaces while calling
interface up. This avoids to have different mac parameters on one phy.
Otherwise it could be that a interface can overwrite current phy mac
settings which is set by an another interface.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/mac802154')
-rw-r--r-- | net/mac802154/iface.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c index 9ae893057dd7..61f3ff00a508 100644 --- a/net/mac802154/iface.c +++ b/net/mac802154/iface.c | |||
@@ -175,6 +175,79 @@ err: | |||
175 | return res; | 175 | return res; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int | ||
179 | ieee802154_check_mac_settings(struct ieee802154_local *local, | ||
180 | struct wpan_dev *wpan_dev, | ||
181 | struct wpan_dev *nwpan_dev) | ||
182 | { | ||
183 | ASSERT_RTNL(); | ||
184 | |||
185 | if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { | ||
186 | if (wpan_dev->promiscuous_mode != nwpan_dev->promiscuous_mode) | ||
187 | return -EBUSY; | ||
188 | } | ||
189 | |||
190 | if (local->hw.flags & IEEE802154_HW_AFILT) { | ||
191 | if (wpan_dev->pan_id != nwpan_dev->pan_id) | ||
192 | return -EBUSY; | ||
193 | |||
194 | if (wpan_dev->short_addr != nwpan_dev->short_addr) | ||
195 | return -EBUSY; | ||
196 | |||
197 | if (wpan_dev->extended_addr != nwpan_dev->extended_addr) | ||
198 | return -EBUSY; | ||
199 | } | ||
200 | |||
201 | if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { | ||
202 | if (wpan_dev->min_be != nwpan_dev->min_be) | ||
203 | return -EBUSY; | ||
204 | |||
205 | if (wpan_dev->max_be != nwpan_dev->max_be) | ||
206 | return -EBUSY; | ||
207 | |||
208 | if (wpan_dev->csma_retries != nwpan_dev->csma_retries) | ||
209 | return -EBUSY; | ||
210 | } | ||
211 | |||
212 | if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) { | ||
213 | if (wpan_dev->frame_retries != nwpan_dev->frame_retries) | ||
214 | return -EBUSY; | ||
215 | } | ||
216 | |||
217 | if (local->hw.flags & IEEE802154_HW_LBT) { | ||
218 | if (wpan_dev->lbt != nwpan_dev->lbt) | ||
219 | return -EBUSY; | ||
220 | } | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int | ||
226 | ieee802154_check_concurrent_iface(struct ieee802154_sub_if_data *sdata, | ||
227 | enum nl802154_iftype iftype) | ||
228 | { | ||
229 | struct ieee802154_local *local = sdata->local; | ||
230 | struct wpan_dev *wpan_dev = &sdata->wpan_dev; | ||
231 | struct ieee802154_sub_if_data *nsdata; | ||
232 | |||
233 | /* we hold the RTNL here so can safely walk the list */ | ||
234 | list_for_each_entry(nsdata, &local->interfaces, list) { | ||
235 | if (nsdata != sdata && ieee802154_sdata_running(nsdata)) { | ||
236 | int ret; | ||
237 | |||
238 | /* check all phy mac sublayer settings are the same. | ||
239 | * We have only one phy, different values makes trouble. | ||
240 | */ | ||
241 | ret = ieee802154_check_mac_settings(local, wpan_dev, | ||
242 | &nsdata->wpan_dev); | ||
243 | if (ret < 0) | ||
244 | return ret; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
178 | static int mac802154_wpan_open(struct net_device *dev) | 251 | static int mac802154_wpan_open(struct net_device *dev) |
179 | { | 252 | { |
180 | int rc; | 253 | int rc; |
@@ -183,6 +256,10 @@ static int mac802154_wpan_open(struct net_device *dev) | |||
183 | struct wpan_dev *wpan_dev = &sdata->wpan_dev; | 256 | struct wpan_dev *wpan_dev = &sdata->wpan_dev; |
184 | struct wpan_phy *phy = sdata->local->phy; | 257 | struct wpan_phy *phy = sdata->local->phy; |
185 | 258 | ||
259 | rc = ieee802154_check_concurrent_iface(sdata, sdata->vif.type); | ||
260 | if (rc < 0) | ||
261 | return rc; | ||
262 | |||
186 | rc = mac802154_slave_open(dev); | 263 | rc = mac802154_slave_open(dev); |
187 | if (rc < 0) | 264 | if (rc < 0) |
188 | return rc; | 265 | return rc; |