aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/util.c')
-rw-r--r--net/wireless/util.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 3fc2df86278f..59361fdcb5d0 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -320,7 +320,9 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
320 break; 320 break;
321 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): 321 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
322 if (unlikely(iftype != NL80211_IFTYPE_WDS && 322 if (unlikely(iftype != NL80211_IFTYPE_WDS &&
323 iftype != NL80211_IFTYPE_MESH_POINT)) 323 iftype != NL80211_IFTYPE_MESH_POINT &&
324 iftype != NL80211_IFTYPE_AP_VLAN &&
325 iftype != NL80211_IFTYPE_STATION))
324 return -1; 326 return -1;
325 if (iftype == NL80211_IFTYPE_MESH_POINT) { 327 if (iftype == NL80211_IFTYPE_MESH_POINT) {
326 struct ieee80211s_hdr *meshdr = 328 struct ieee80211s_hdr *meshdr =
@@ -656,7 +658,14 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
656 !(rdev->wiphy.interface_modes & (1 << ntype))) 658 !(rdev->wiphy.interface_modes & (1 << ntype)))
657 return -EOPNOTSUPP; 659 return -EOPNOTSUPP;
658 660
661 /* if it's part of a bridge, reject changing type to station/ibss */
662 if (dev->br_port && (ntype == NL80211_IFTYPE_ADHOC ||
663 ntype == NL80211_IFTYPE_STATION))
664 return -EBUSY;
665
659 if (ntype != otype) { 666 if (ntype != otype) {
667 dev->ieee80211_ptr->use_4addr = false;
668
660 switch (otype) { 669 switch (otype) {
661 case NL80211_IFTYPE_ADHOC: 670 case NL80211_IFTYPE_ADHOC:
662 cfg80211_leave_ibss(rdev, dev, false); 671 cfg80211_leave_ibss(rdev, dev, false);
@@ -680,5 +689,34 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
680 689
681 WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); 690 WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
682 691
692 if (!err && params && params->use_4addr != -1)
693 dev->ieee80211_ptr->use_4addr = params->use_4addr;
694
695 if (!err) {
696 dev->priv_flags &= ~IFF_DONT_BRIDGE;
697 switch (ntype) {
698 case NL80211_IFTYPE_STATION:
699 if (dev->ieee80211_ptr->use_4addr)
700 break;
701 /* fall through */
702 case NL80211_IFTYPE_ADHOC:
703 dev->priv_flags |= IFF_DONT_BRIDGE;
704 break;
705 case NL80211_IFTYPE_AP:
706 case NL80211_IFTYPE_AP_VLAN:
707 case NL80211_IFTYPE_WDS:
708 case NL80211_IFTYPE_MESH_POINT:
709 /* bridging OK */
710 break;
711 case NL80211_IFTYPE_MONITOR:
712 /* monitor can't bridge anyway */
713 break;
714 case NL80211_IFTYPE_UNSPECIFIED:
715 case __NL80211_IFTYPE_AFTER_LAST:
716 /* not happening */
717 break;
718 }
719 }
720
683 return err; 721 return err;
684} 722}