diff options
-rw-r--r-- | include/net/cfg80211.h | 11 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 21 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 12 | ||||
-rw-r--r-- | net/mac80211/main.c | 4 | ||||
-rw-r--r-- | net/mac80211/rx.c | 14 | ||||
-rw-r--r-- | net/mac80211/tx.c | 7 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 34 | ||||
-rw-r--r-- | net/wireless/util.c | 5 |
9 files changed, 82 insertions, 30 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index eca36abca8f5..d1e05aeb0c09 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1134,6 +1134,9 @@ struct cfg80211_ops { | |||
1134 | * by default -- this flag will be set depending on the kernel's default | 1134 | * by default -- this flag will be set depending on the kernel's default |
1135 | * on wiphy_new(), but can be changed by the driver if it has a good | 1135 | * on wiphy_new(), but can be changed by the driver if it has a good |
1136 | * reason to override the default | 1136 | * reason to override the default |
1137 | * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station | ||
1138 | * on a VLAN interface) | ||
1139 | * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station | ||
1137 | */ | 1140 | */ |
1138 | enum wiphy_flags { | 1141 | enum wiphy_flags { |
1139 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 1142 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
@@ -1141,6 +1144,8 @@ enum wiphy_flags { | |||
1141 | WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), | 1144 | WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), |
1142 | WIPHY_FLAG_NETNS_OK = BIT(3), | 1145 | WIPHY_FLAG_NETNS_OK = BIT(3), |
1143 | WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), | 1146 | WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), |
1147 | WIPHY_FLAG_4ADDR_AP = BIT(5), | ||
1148 | WIPHY_FLAG_4ADDR_STATION = BIT(6), | ||
1144 | }; | 1149 | }; |
1145 | 1150 | ||
1146 | /** | 1151 | /** |
@@ -1366,6 +1371,10 @@ struct cfg80211_cached_keys; | |||
1366 | * @ssid_len: (private) Used by the internal configuration code | 1371 | * @ssid_len: (private) Used by the internal configuration code |
1367 | * @wext: (private) Used by the internal wireless extensions compat code | 1372 | * @wext: (private) Used by the internal wireless extensions compat code |
1368 | * @wext_bssid: (private) Used by the internal wireless extensions compat code | 1373 | * @wext_bssid: (private) Used by the internal wireless extensions compat code |
1374 | * @use_4addr: indicates 4addr mode is used on this interface, must be | ||
1375 | * set by driver (if supported) on add_interface BEFORE registering the | ||
1376 | * netdev and may otherwise be used by driver read-only, will be update | ||
1377 | * by cfg80211 on change_interface | ||
1369 | */ | 1378 | */ |
1370 | struct wireless_dev { | 1379 | struct wireless_dev { |
1371 | struct wiphy *wiphy; | 1380 | struct wiphy *wiphy; |
@@ -1379,6 +1388,8 @@ struct wireless_dev { | |||
1379 | 1388 | ||
1380 | struct work_struct cleanup_work; | 1389 | struct work_struct cleanup_work; |
1381 | 1390 | ||
1391 | bool use_4addr; | ||
1392 | |||
1382 | /* currently used for IBSS and SME - might be rearranged later */ | 1393 | /* currently used for IBSS and SME - might be rearranged later */ |
1383 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 1394 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
1384 | u8 ssid_len; | 1395 | u8 ssid_len; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7d591816ed10..c484a882140e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -42,15 +42,6 @@ static bool nl80211_params_check(enum nl80211_iftype type, | |||
42 | if (!nl80211_type_check(type)) | 42 | if (!nl80211_type_check(type)) |
43 | return false; | 43 | return false; |
44 | 44 | ||
45 | if (params->use_4addr > 0) { | ||
46 | switch(type) { | ||
47 | case NL80211_IFTYPE_AP_VLAN: | ||
48 | case NL80211_IFTYPE_STATION: | ||
49 | break; | ||
50 | default: | ||
51 | return false; | ||
52 | } | ||
53 | } | ||
54 | return true; | 45 | return true; |
55 | } | 46 | } |
56 | 47 | ||
@@ -107,12 +98,16 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
107 | params->mesh_id_len, | 98 | params->mesh_id_len, |
108 | params->mesh_id); | 99 | params->mesh_id); |
109 | 100 | ||
110 | if (params->use_4addr >= 0) | ||
111 | sdata->use_4addr = !!params->use_4addr; | ||
112 | |||
113 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) | 101 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) |
114 | return 0; | 102 | return 0; |
115 | 103 | ||
104 | if (type == NL80211_IFTYPE_AP_VLAN && | ||
105 | params && params->use_4addr == 0) | ||
106 | rcu_assign_pointer(sdata->u.vlan.sta, NULL); | ||
107 | else if (type == NL80211_IFTYPE_STATION && | ||
108 | params && params->use_4addr >= 0) | ||
109 | sdata->u.mgd.use_4addr = params->use_4addr; | ||
110 | |||
116 | sdata->u.mntr_flags = *flags; | 111 | sdata->u.mntr_flags = *flags; |
117 | return 0; | 112 | return 0; |
118 | } | 113 | } |
@@ -827,7 +822,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
827 | return -EINVAL; | 822 | return -EINVAL; |
828 | } | 823 | } |
829 | 824 | ||
830 | if (vlansdata->use_4addr) { | 825 | if (params->vlan->ieee80211_ptr->use_4addr) { |
831 | if (vlansdata->u.vlan.sta) | 826 | if (vlansdata->u.vlan.sta) |
832 | return -EBUSY; | 827 | return -EBUSY; |
833 | 828 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 87d27f450a05..f13d76c9b575 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -312,6 +312,8 @@ struct ieee80211_if_managed { | |||
312 | } mfp; /* management frame protection */ | 312 | } mfp; /* management frame protection */ |
313 | 313 | ||
314 | int wmm_last_param_set; | 314 | int wmm_last_param_set; |
315 | |||
316 | u8 use_4addr; | ||
315 | }; | 317 | }; |
316 | 318 | ||
317 | enum ieee80211_ibss_request { | 319 | enum ieee80211_ibss_request { |
@@ -459,8 +461,6 @@ struct ieee80211_sub_if_data { | |||
459 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | 461 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ |
460 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | 462 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ |
461 | 463 | ||
462 | bool use_4addr; /* use 4-address frames */ | ||
463 | |||
464 | union { | 464 | union { |
465 | struct ieee80211_if_ap ap; | 465 | struct ieee80211_if_ap ap; |
466 | struct ieee80211_if_wds wds; | 466 | struct ieee80211_if_wds wds; |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 1f02b0610e82..1bf12a26b45e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -752,7 +752,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
752 | ieee80211_mandatory_rates(sdata->local, | 752 | ieee80211_mandatory_rates(sdata->local, |
753 | sdata->local->hw.conf.channel->band); | 753 | sdata->local->hw.conf.channel->band); |
754 | sdata->drop_unencrypted = 0; | 754 | sdata->drop_unencrypted = 0; |
755 | sdata->use_4addr = 0; | 755 | if (type == NL80211_IFTYPE_STATION) |
756 | sdata->u.mgd.use_4addr = false; | ||
756 | 757 | ||
757 | return 0; | 758 | return 0; |
758 | } | 759 | } |
@@ -810,6 +811,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
810 | /* setup type-dependent data */ | 811 | /* setup type-dependent data */ |
811 | ieee80211_setup_sdata(sdata, type); | 812 | ieee80211_setup_sdata(sdata, type); |
812 | 813 | ||
814 | if (params) { | ||
815 | ndev->ieee80211_ptr->use_4addr = params->use_4addr; | ||
816 | if (type == NL80211_IFTYPE_STATION) | ||
817 | sdata->u.mgd.use_4addr = params->use_4addr; | ||
818 | } | ||
819 | |||
813 | ret = register_netdevice(ndev); | 820 | ret = register_netdevice(ndev); |
814 | if (ret) | 821 | if (ret) |
815 | goto fail; | 822 | goto fail; |
@@ -820,9 +827,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
820 | params->mesh_id_len, | 827 | params->mesh_id_len, |
821 | params->mesh_id); | 828 | params->mesh_id); |
822 | 829 | ||
823 | if (params && params->use_4addr >= 0) | ||
824 | sdata->use_4addr = !!params->use_4addr; | ||
825 | |||
826 | mutex_lock(&local->iflist_mtx); | 830 | mutex_lock(&local->iflist_mtx); |
827 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 831 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
828 | mutex_unlock(&local->iflist_mtx); | 832 | mutex_unlock(&local->iflist_mtx); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8084b622e97e..dd8ec8d5e8b2 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -328,7 +328,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
328 | if (!wiphy) | 328 | if (!wiphy) |
329 | return NULL; | 329 | return NULL; |
330 | 330 | ||
331 | wiphy->flags |= WIPHY_FLAG_NETNS_OK; | 331 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
332 | WIPHY_FLAG_4ADDR_AP | | ||
333 | WIPHY_FLAG_4ADDR_STATION; | ||
332 | wiphy->privid = mac80211_wiphy_privid; | 334 | wiphy->privid = mac80211_wiphy_privid; |
333 | 335 | ||
334 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | 336 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 775365f856c9..96f13ad05d3c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1192,10 +1192,13 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1192 | struct net_device *dev = sdata->dev; | 1192 | struct net_device *dev = sdata->dev; |
1193 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 1193 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
1194 | 1194 | ||
1195 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && | 1195 | if (ieee80211_has_a4(hdr->frame_control) && |
1196 | ieee80211_has_a4(hdr->frame_control)) | 1196 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta) |
1197 | return -1; | 1197 | return -1; |
1198 | if (sdata->use_4addr && is_multicast_ether_addr(hdr->addr1)) | 1198 | |
1199 | if (is_multicast_ether_addr(hdr->addr1) && | ||
1200 | ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN && sdata->u.vlan.sta) || | ||
1201 | (sdata->vif.type == NL80211_IFTYPE_STATION && sdata->u.mgd.use_4addr))) | ||
1199 | return -1; | 1202 | return -1; |
1200 | 1203 | ||
1201 | return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); | 1204 | return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type); |
@@ -1245,7 +1248,8 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1245 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1248 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
1246 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 1249 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
1247 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 1250 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
1248 | (rx->flags & IEEE80211_RX_RA_MATCH) && !rx->sdata->use_4addr) { | 1251 | (rx->flags & IEEE80211_RX_RA_MATCH) && |
1252 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { | ||
1249 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 1253 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
1250 | /* | 1254 | /* |
1251 | * send multicast frames both to higher layers in | 1255 | * send multicast frames both to higher layers in |
@@ -2007,7 +2011,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
2007 | 2011 | ||
2008 | switch (sdata->vif.type) { | 2012 | switch (sdata->vif.type) { |
2009 | case NL80211_IFTYPE_STATION: | 2013 | case NL80211_IFTYPE_STATION: |
2010 | if (!bssid && !sdata->use_4addr) | 2014 | if (!bssid && !sdata->u.mgd.use_4addr) |
2011 | return 0; | 2015 | return 0; |
2012 | if (!multicast && | 2016 | if (!multicast && |
2013 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { | 2017 | compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b3c1faeb5927..5af2f40ea4db 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1051,7 +1051,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1051 | 1051 | ||
1052 | hdr = (struct ieee80211_hdr *) skb->data; | 1052 | hdr = (struct ieee80211_hdr *) skb->data; |
1053 | 1053 | ||
1054 | if ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && sdata->use_4addr) | 1054 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | 1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); |
1056 | if (!tx->sta) | 1056 | if (!tx->sta) |
1057 | tx->sta = sta_info_get(local, hdr->addr1); | 1057 | tx->sta = sta_info_get(local, hdr->addr1); |
@@ -1632,8 +1632,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1632 | switch (sdata->vif.type) { | 1632 | switch (sdata->vif.type) { |
1633 | case NL80211_IFTYPE_AP_VLAN: | 1633 | case NL80211_IFTYPE_AP_VLAN: |
1634 | rcu_read_lock(); | 1634 | rcu_read_lock(); |
1635 | if (sdata->use_4addr) | 1635 | sta = rcu_dereference(sdata->u.vlan.sta); |
1636 | sta = rcu_dereference(sdata->u.vlan.sta); | ||
1637 | if (sta) { | 1636 | if (sta) { |
1638 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1637 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1639 | /* RA TA DA SA */ | 1638 | /* RA TA DA SA */ |
@@ -1727,7 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1727 | #endif | 1726 | #endif |
1728 | case NL80211_IFTYPE_STATION: | 1727 | case NL80211_IFTYPE_STATION: |
1729 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1728 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1730 | if (sdata->use_4addr && ethertype != ETH_P_PAE) { | 1729 | if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { |
1731 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1730 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1732 | /* RA TA DA SA */ | 1731 | /* RA TA DA SA */ |
1733 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1732 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6634188f9453..b7b0f67b0c61 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -968,6 +968,28 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) | |||
968 | return 0; | 968 | return 0; |
969 | } | 969 | } |
970 | 970 | ||
971 | static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, | ||
972 | u8 use_4addr, enum nl80211_iftype iftype) | ||
973 | { | ||
974 | if (!use_4addr) | ||
975 | return 0; | ||
976 | |||
977 | switch (iftype) { | ||
978 | case NL80211_IFTYPE_AP_VLAN: | ||
979 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP) | ||
980 | return 0; | ||
981 | break; | ||
982 | case NL80211_IFTYPE_STATION: | ||
983 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION) | ||
984 | return 0; | ||
985 | break; | ||
986 | default: | ||
987 | break; | ||
988 | } | ||
989 | |||
990 | return -EOPNOTSUPP; | ||
991 | } | ||
992 | |||
971 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | 993 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) |
972 | { | 994 | { |
973 | struct cfg80211_registered_device *rdev; | 995 | struct cfg80211_registered_device *rdev; |
@@ -1011,6 +1033,9 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
1011 | if (info->attrs[NL80211_ATTR_4ADDR]) { | 1033 | if (info->attrs[NL80211_ATTR_4ADDR]) { |
1012 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); | 1034 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); |
1013 | change = true; | 1035 | change = true; |
1036 | err = nl80211_valid_4addr(rdev, params.use_4addr, ntype); | ||
1037 | if (err) | ||
1038 | goto unlock; | ||
1014 | } else { | 1039 | } else { |
1015 | params.use_4addr = -1; | 1040 | params.use_4addr = -1; |
1016 | } | 1041 | } |
@@ -1034,6 +1059,9 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
1034 | else | 1059 | else |
1035 | err = 0; | 1060 | err = 0; |
1036 | 1061 | ||
1062 | if (!err && params.use_4addr != -1) | ||
1063 | dev->ieee80211_ptr->use_4addr = params.use_4addr; | ||
1064 | |||
1037 | unlock: | 1065 | unlock: |
1038 | dev_put(dev); | 1066 | dev_put(dev); |
1039 | cfg80211_unlock_rdev(rdev); | 1067 | cfg80211_unlock_rdev(rdev); |
@@ -1081,8 +1109,12 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1081 | params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); | 1109 | params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); |
1082 | } | 1110 | } |
1083 | 1111 | ||
1084 | if (info->attrs[NL80211_ATTR_4ADDR]) | 1112 | if (info->attrs[NL80211_ATTR_4ADDR]) { |
1085 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); | 1113 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); |
1114 | err = nl80211_valid_4addr(rdev, params.use_4addr, type); | ||
1115 | if (err) | ||
1116 | goto unlock; | ||
1117 | } | ||
1086 | 1118 | ||
1087 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 1119 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
1088 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 1120 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 5aa39f7cf9b9..17a7a4cfc617 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -659,6 +659,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
659 | return -EOPNOTSUPP; | 659 | return -EOPNOTSUPP; |
660 | 660 | ||
661 | if (ntype != otype) { | 661 | if (ntype != otype) { |
662 | dev->ieee80211_ptr->use_4addr = false; | ||
663 | |||
662 | switch (otype) { | 664 | switch (otype) { |
663 | case NL80211_IFTYPE_ADHOC: | 665 | case NL80211_IFTYPE_ADHOC: |
664 | cfg80211_leave_ibss(rdev, dev, false); | 666 | cfg80211_leave_ibss(rdev, dev, false); |
@@ -682,5 +684,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
682 | 684 | ||
683 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); | 685 | WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype); |
684 | 686 | ||
687 | if (!err && params && params->use_4addr != -1) | ||
688 | dev->ieee80211_ptr->use_4addr = params->use_4addr; | ||
689 | |||
685 | return err; | 690 | return err; |
686 | } | 691 | } |