Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 171890
b: refs/heads/master
c: ad4bb6f
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Nov 19, 2009
1 parent f29261a commit 21ab062
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9bc383de37090ba7ca3ff32a12c9d809dc5867f0
refs/heads/master: ad4bb6f8883a13bb0f65b194dae36c62a02ac779
1 change: 1 addition & 0 deletions trunk/include/linux/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to
* release skb->dst
*/
#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */

#define IF_GET_IFACE 0x0001 /* for querying only */
#define IF_GET_PROTO 0x0002
Expand Down
4 changes: 4 additions & 0 deletions trunk/net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
if (dev->br_port != NULL)
return -EBUSY;

/* No bridging devices that dislike that (e.g. wireless) */
if (dev->priv_flags & IFF_DONT_BRIDGE)
return -EOPNOTSUPP;

p = new_nbp(br, dev);
if (IS_ERR(p))
return PTR_ERR(p);
Expand Down
4 changes: 4 additions & 0 deletions trunk/net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
#endif
if (!dev->ethtool_ops)
dev->ethtool_ops = &cfg80211_ethtool_ops;

if ((wdev->iftype == NL80211_IFTYPE_STATION ||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
dev->priv_flags |= IFF_DONT_BRIDGE;
break;
case NETDEV_GOING_DOWN:
switch (wdev->iftype) {
Expand Down
12 changes: 8 additions & 4 deletions trunk/net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -969,10 +969,14 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
}

static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
u8 use_4addr, enum nl80211_iftype iftype)
struct net_device *netdev, u8 use_4addr,
enum nl80211_iftype iftype)
{
if (!use_4addr)
if (!use_4addr) {
if (netdev && netdev->br_port)
return -EBUSY;
return 0;
}

switch (iftype) {
case NL80211_IFTYPE_AP_VLAN:
Expand Down Expand Up @@ -1033,7 +1037,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_4ADDR]) {
params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
change = true;
err = nl80211_valid_4addr(rdev, params.use_4addr, ntype);
err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
if (err)
goto unlock;
} else {
Expand Down Expand Up @@ -1111,7 +1115,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)

if (info->attrs[NL80211_ATTR_4ADDR]) {
params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
err = nl80211_valid_4addr(rdev, params.use_4addr, type);
err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
if (err)
goto unlock;
}
Expand Down
31 changes: 31 additions & 0 deletions trunk/net/wireless/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
!(rdev->wiphy.interface_modes & (1 << ntype)))
return -EOPNOTSUPP;

/* if it's part of a bridge, reject changing type to station/ibss */
if (dev->br_port && (ntype == NL80211_IFTYPE_ADHOC ||
ntype == NL80211_IFTYPE_STATION))
return -EBUSY;

if (ntype != otype) {
dev->ieee80211_ptr->use_4addr = false;

Expand Down Expand Up @@ -687,5 +692,31 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
if (!err && params && params->use_4addr != -1)
dev->ieee80211_ptr->use_4addr = params->use_4addr;

if (!err) {
dev->priv_flags &= ~IFF_DONT_BRIDGE;
switch (ntype) {
case NL80211_IFTYPE_STATION:
if (dev->ieee80211_ptr->use_4addr)
break;
/* fall through */
case NL80211_IFTYPE_ADHOC:
dev->priv_flags |= IFF_DONT_BRIDGE;
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_AP_VLAN:
case NL80211_IFTYPE_WDS:
case NL80211_IFTYPE_MESH_POINT:
/* bridging OK */
break;
case NL80211_IFTYPE_MONITOR:
/* monitor can't bridge anyway */
break;
case NL80211_IFTYPE_UNSPECIFIED:
case __NL80211_IFTYPE_AFTER_LAST:
/* not happening */
break;
}
}

return err;
}

0 comments on commit 21ab062

Please sign in to comment.