nl80211: add a parameter for using 4-address frames on virtual interfaces
Subsystems (2)
PATCH 1/2 nl80211: add a parameter for using 4-address frames on virtual interfaces
---
include/linux/nl80211.h +4 -0
@@ -584,6 +584,8 @@ enum nl80211_commands {* changed then the list changed and the dump should be repeated * completely from scratch. * +* @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface +* * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */
@@ -714,6 +716,8 @@ enum nl80211_attrs {NL80211_ATTR_PID , +NL80211_ATTR_4ADDR , +/* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST,
include/net/cfg80211.h +2 -0
@@ -207,10 +207,12 @@ struct ieee80211_supported_band {* struct vif_params - describes virtual interface parameters * @mesh_id: mesh ID to use * @mesh_id_len: length of the mesh ID +* @use_4addr: use 4-address frames */ struct vif_params {u8 *mesh_id;int mesh_id_len; +int use_4addr; };/**
net/wireless/nl80211.c +11 -0
@@ -140,6 +140,7 @@ static struct nla_policy nl80211_policy[ [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, [NL80211_ATTR_PID] = { .type = NLA_U32 }, + [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, };/* policy for the attributes */
@@ -989,6 +990,13 @@ static int nl80211_set_interface(struct change = true; } +if (info->attrs[NL80211_ATTR_4ADDR ]) { + params.use_4addr = !!nla_get_u8 (info->attrs[NL80211_ATTR_4ADDR ]); + change = true; + }else { + params.use_4addr =-1 ; + } +if (info->attrs[NL80211_ATTR_MNTR_FLAGS ]) {if (ntype !=NL80211_IFTYPE_MONITOR ) { err = -EINVAL ;
@@ -1055,6 +1063,9 @@ static int nl80211_new_interface(struct params.mesh_id_len =nla_len (info->attrs[NL80211_ATTR_MESH_ID ]); } +if (info->attrs[NL80211_ATTR_4ADDR ]) + params.use_4addr = !!nla_get_u8 (info->attrs[NL80211_ATTR_4ADDR ]); + err =parse_monitor_flags (type ==NL80211_IFTYPE_MONITOR ? info->attrs[NL80211_ATTR_MNTR_FLAGS ] :NULL , &flags);
PATCH 2/2 mac80211: implement support for 4-address frames for AP and client mode
In some situations it might be useful to run a network with an Access Point and multiple clients, but with each client bridged to a network behind it. For this to work, both the client and the AP need to transmit 4-address frames, containing both source and destination MAC addresses.
With this patch, you can configure a client to communicate using only 4-address frames for data traffic.
On the AP side you can enable 4-address frames for individual clients by isolating them in separate AP VLANs which are configured in 4-address mode.
Such an AP VLAN will be limited to one client only, and this client will be used as the destination for all traffic on its interface, regardless of the destination MAC address in the packet headers. The advantage of this mode compared to regular WDS mode is that it's easier to configure and does not require a static list of peer MAC addresses on any side.
---
net/mac80211/ieee80211_i.h +5 -0
@@ -208,6 +208,9 @@ struct ieee80211_if_wds {struct ieee80211_if_vlan {struct list_head list; + +/* used for all tx if the VLAN is configured to 4-addr mode */ +struct sta_info *sta; };struct mesh_stats {
@@ -457,6 +460,8 @@ struct ieee80211_sub_if_data {int force_unicast_rateidx;/* forced TX rateidx for unicast frames */ int max_ratectrl_rateidx;/* max TX rateidx for rate control */ +bool use_4addr;/* use 4-address frames */ +union {struct ieee80211_if_ap ap;struct ieee80211_if_wds wds;
net/mac80211/cfg.c +10 -0
@@ -89,6 +89,9 @@ static int ieee80211_change_iface(struct params->mesh_id_len, params->mesh_id); +if (params->use_4addr >=0 ) + sdata->use_4addr = !!params->use_4addr; +if (sdata->vif.type !=NL80211_IFTYPE_MONITOR || !flags)return 0 ;
@@ -806,6 +809,13 @@ static int ieee80211_change_station(strureturn -EINVAL ; } +if (vlansdata->use_4addr) { +if (vlansdata->u.vlan.sta) +return -EEXIST ; + +rcu_assign_pointer (vlansdata->u.vlan.sta, sta); + } + sta->sdata = vlansdata;ieee80211_send_layer2_update (sta); }
net/mac80211/sta_info.c +5 -0
@@ -489,6 +489,11 @@ static void __sta_info_unlink(struct sta local->num_sta--; local->sta_generation++; +if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) { +if (sdata->u.vlan.sta) +rcu_assign_pointer (sdata->u.vlan.sta,NULL ); + } +if (local->ops->sta_notify) {if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) sdata = container_of(sdata->bss,
net/mac80211/tx.c +37 -8
71 lines not on this page · raw message
net/mac80211/iface.c +3 -0
@@ -853,6 +853,9 @@ int ieee80211_if_add(struct ieee80211_lo params->mesh_id_len, params->mesh_id); +if (params && params->use_4addr >=0 ) + sdata->use_4addr = !!params->use_4addr; +mutex_lock (&local->iflist_mtx);list_add_tail_rcu (&sdata->list, &local->interfaces);mutex_unlock (&local->iflist_mtx);
net/mac80211/rx.c +16 -1
@@ -1237,6 +1237,13 @@ __ieee80211_data_to_8023(struct ieee8021 {struct net_device *dev = rx->dev;struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + +if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && +ieee80211_has_a4 (hdr->frame_control)) +return -1 ; +if (sdata->use_4addr &&is_multicast_ether_addr (hdr->addr1)) +return -1 ;return ieee80211_data_to_8023 (rx->skb, dev->dev_addr, sdata->vif.type); }
@@ -1590,6 +1597,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ {struct net_device *dev = rx->dev;struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev);__le16 fc = hdr->frame_control;int err;
@@ -1599,6 +1607,13 @@ ieee80211_rx_h_data(struct ieee80211_rx_if (unlikely (!ieee80211_is_data_present (hdr->frame_control)))return RX_DROP_MONITOR ; +/* Allow the cooked monitor interface of an AP to see 4-addr frames so +* that a 4-addr station can be detected and moved into a separate VLAN +*/ +if (ieee80211_has_a4 (hdr->frame_control) && + sdata->vif.type ==NL80211_IFTYPE_AP ) +return RX_DROP_MONITOR ; + err =__ieee80211_data_to_8023 (rx);if (unlikely (err))return RX_DROP_UNUSABLE ;
@@ -2039,7 +2054,7 @@ static int prepare_for_handlers(struct iswitch (sdata->vif.type) {case NL80211_IFTYPE_STATION : -if (!bssid) +if (!bssid && !sdata->use_4addr)return 0 ;if (!multicast &&compare_ether_addr (sdata->dev->dev_addr, hdr->addr1) !=0 ) {
net/wireless/util.c +3 -1
@@ -320,7 +320,9 @@ int ieee80211_data_to_8023(struct sk_bufbreak ;case cpu_to_le16 (IEEE80211_FCTL_TODS |IEEE80211_FCTL_FROMDS ):if (unlikely (iftype !=NL80211_IFTYPE_WDS && - iftype !=NL80211_IFTYPE_MESH_POINT )) + iftype !=NL80211_IFTYPE_MESH_POINT && + iftype !=NL80211_IFTYPE_AP_VLAN && + iftype !=NL80211_IFTYPE_STATION ))return -1 ;if (iftype ==NL80211_IFTYPE_MESH_POINT ) { struct ieee80211s_hdr *meshdr =
PATCH v2 2/2 mac80211: implement support for 4-address frames for AP and client mode
In some situations it might be useful to run a network with an Access Point and multiple clients, but with each client bridged to a network behind it. For this to work, both the client and the AP need to transmit 4-address frames, containing both source and destination MAC addresses.
With this patch, you can configure a client to communicate using only 4-address frames for data traffic.
On the AP side you can enable 4-address frames for individual clients by isolating them in separate AP VLANs which are configured in 4-address mode.
Such an AP VLAN will be limited to one client only, and this client will be used as the destination for all traffic on its interface, regardless of the destination MAC address in the packet headers. The advantage of this mode compared to regular WDS mode is that it's easier to configure and does not require a static list of peer MAC addresses on any side.
---
v2:
- minor coding style cleanups
- better return code when trying to add a sta to a used 4-addr vlan
- check interface type before setting 4-addr mode and reset the mode on interface type changes
net/mac80211/ieee80211_i.h +5 -0
@@ -208,6 +208,9 @@ struct ieee80211_if_wds {struct ieee80211_if_vlan {struct list_head list; + +/* used for all tx if the VLAN is configured to 4-addr mode */ +struct sta_info *sta; };struct mesh_stats {
@@ -457,6 +460,8 @@ struct ieee80211_sub_if_data {int force_unicast_rateidx;/* forced TX rateidx for unicast frames */ int max_ratectrl_rateidx;/* max TX rateidx for rate control */ +bool use_4addr;/* use 4-address frames */ +union {struct ieee80211_if_ap ap;struct ieee80211_if_wds wds;
net/mac80211/cfg.c +30 -2
@@ -36,6 +36,24 @@ static bool nl80211_type_check(enum nl80 } } +static bool nl80211_params_check (enum nl80211_iftype type, +struct vif_params *params) +{ +if (!nl80211_type_check (type)) +return false; + +if (params->use_4addr >0 ) { +switch (type) { +case NL80211_IFTYPE_AP_VLAN : +case NL80211_IFTYPE_STATION : +break ; +default : +return false; + } + } +return true; +} +static int ieee80211_add_iface (struct wiphy *wiphy,char *name,enum nl80211_iftype type,u32 *flags,struct vif_params *params)
@@ -45,7 +63,7 @@ static int ieee80211_add_iface(struct wistruct ieee80211_sub_if_data *sdata;int err; -if (!nl80211_type_check (type)) +if (!nl80211_params_check (type, params))return -EINVAL ; err =ieee80211_if_add (local, name, &dev, type, params);
@@ -75,7 +93,7 @@ static int ieee80211_change_iface(structif (netif_running (dev))return -EBUSY ; -if (!nl80211_type_check (type)) +if (!nl80211_params_check (type, params))return -EINVAL ; sdata =IEEE80211_DEV_TO_SUB_IF (dev);
@@ -89,6 +107,9 @@ static int ieee80211_change_iface(struct params->mesh_id_len, params->mesh_id); +if (params->use_4addr >=0 ) + sdata->use_4addr = !!params->use_4addr; +if (sdata->vif.type !=NL80211_IFTYPE_MONITOR || !flags)return 0 ;
@@ -806,6 +827,13 @@ static int ieee80211_change_station(strureturn -EINVAL ; } +if (vlansdata->use_4addr) { +if (vlansdata->u.vlan.sta) +return -EBUSY ; + +rcu_assign_pointer (vlansdata->u.vlan.sta, sta); + } + sta->sdata = vlansdata;ieee80211_send_layer2_update (sta); }
net/mac80211/sta_info.c +3 -0
@@ -489,6 +489,9 @@ static void __sta_info_unlink(struct sta local->num_sta--; local->sta_generation++; +if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) +rcu_assign_pointer (sdata->u.vlan.sta,NULL ); +if (local->ops->sta_notify) {if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) sdata = container_of(sdata->bss,
net/mac80211/tx.c +37 -8
71 lines not on this page · raw message
net/mac80211/iface.c +4 -0
@@ -772,6 +772,7 @@ int ieee80211_if_change_type(struct ieeeieee80211_mandatory_rates (sdata->local, sdata->local->hw.conf.channel->band); sdata->drop_unencrypted =0 ; + sdata->use_4addr =0 ;return 0 ; }
@@ -853,6 +854,9 @@ int ieee80211_if_add(struct ieee80211_lo params->mesh_id_len, params->mesh_id); +if (params && params->use_4addr >=0 ) + sdata->use_4addr = !!params->use_4addr; +mutex_lock (&local->iflist_mtx);list_add_tail_rcu (&sdata->list, &local->interfaces);mutex_unlock (&local->iflist_mtx);
net/mac80211/rx.c +17 -1
@@ -1237,6 +1237,13 @@ __ieee80211_data_to_8023(struct ieee8021 {struct net_device *dev = rx->dev;struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + +if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && +ieee80211_has_a4 (hdr->frame_control)) +return -1 ; +if (sdata->use_4addr &&is_multicast_ether_addr (hdr->addr1)) +return -1 ;return ieee80211_data_to_8023 (rx->skb, dev->dev_addr, sdata->vif.type); }
@@ -1590,6 +1597,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ {struct net_device *dev = rx->dev;struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev);__le16 fc = hdr->frame_control;int err;
@@ -1599,6 +1607,14 @@ ieee80211_rx_h_data(struct ieee80211_rx_if (unlikely (!ieee80211_is_data_present (hdr->frame_control)))return RX_DROP_MONITOR ; +/* +* Allow the cooked monitor interface of an AP to see 4-addr frames so +* that a 4-addr station can be detected and moved into a separate VLAN +*/ +if (ieee80211_has_a4 (hdr->frame_control) && + sdata->vif.type ==NL80211_IFTYPE_AP ) +return RX_DROP_MONITOR ; + err =__ieee80211_data_to_8023 (rx);if (unlikely (err))return RX_DROP_UNUSABLE ;
@@ -2039,7 +2055,7 @@ static int prepare_for_handlers(struct iswitch (sdata->vif.type) {case NL80211_IFTYPE_STATION : -if (!bssid) +if (!bssid && !sdata->use_4addr)return 0 ;if (!multicast &&compare_ether_addr (sdata->dev->dev_addr, hdr->addr1) !=0 ) {
net/wireless/util.c +3 -1
@@ -320,7 +320,9 @@ int ieee80211_data_to_8023(struct sk_bufbreak ;case cpu_to_le16 (IEEE80211_FCTL_TODS |IEEE80211_FCTL_FROMDS ):if (unlikely (iftype !=NL80211_IFTYPE_WDS && - iftype !=NL80211_IFTYPE_MESH_POINT )) + iftype !=NL80211_IFTYPE_MESH_POINT && + iftype !=NL80211_IFTYPE_AP_VLAN && + iftype !=NL80211_IFTYPE_STATION ))return -1 ;if (iftype ==NL80211_IFTYPE_MESH_POINT ) { struct ieee80211s_hdr *meshdr =
Johannes Berg
maintainerRe: [PATCH v2 2/2] mac80211: implement support for 4-address frames for AP and client mode
Quoted 8 lines · Felix Fietkau
In some situations it might be useful to run a network with an Access Point and multiple clients, but with each client bridged to a network behind it. For this to work, both the client and the AP need to transmit 4-address frames, containing both source and destination MAC addresses.
With this patch, you can configure a client to communicate using only 4-address frames for data traffic.
On the AP side you can enable 4-address frames for individual
Quoted 8 lines
clients by isolating them in separate AP VLANs which are configured in 4-address mode.
Such an AP VLAN will be limited to one client only, and this client will be used as the destination for all traffic on its interface, regardless of the destination MAC address in the packet headers. The advantage of this mode compared to regular WDS mode is that it's easier to configure and does not require a static list of peer MAC addresses on any side.
Looks good, thanks.
johannes
PATCH v3 2/2 mac80211: implement support for 4-address frames for AP and client mode
In reply to Felix FietkauIn some situations it might be useful to run a network with an Access Point and multiple clients, but with each client bridged to a network behind it. For this to work, both the client and the AP need to transmit 4-address frames, containing both source and destination MAC addresses.
With this patch, you can configure a client to communicate using only 4-address frames for data traffic.
On the AP side you can enable 4-address frames for individual clients by isolating them in separate AP VLANs which are configured in 4-address mode.
Such an AP VLAN will be limited to one client only, and this client will be used as the destination for all traffic on its interface, regardless of the destination MAC address in the packet headers. The advantage of this mode compared to regular WDS mode is that it's easier to configure and does not require a static list of peer MAC addresses on any side.
---
v2:
- minor coding style cleanups
- better return code when trying to add a sta to a used 4-addr vlan
- check interface type before setting 4-addr mode and reset the mode on interface type changes
v3:
- fix a bug that led to broadcast frames being reflected back from the ap to the wds sta
net/mac80211/ieee80211_i.h +5 -0
@@ -208,6 +208,9 @@ struct ieee80211_if_wds {struct ieee80211_if_vlan {struct list_head list; + +/* used for all tx if the VLAN is configured to 4-addr mode */ +struct sta_info *sta; };struct mesh_stats {
@@ -457,6 +460,8 @@ struct ieee80211_sub_if_data {int force_unicast_rateidx;/* forced TX rateidx for unicast frames */ int max_ratectrl_rateidx;/* max TX rateidx for rate control */ +bool use_4addr;/* use 4-address frames */ +union {struct ieee80211_if_ap ap;struct ieee80211_if_wds wds;
net/mac80211/cfg.c +30 -2
@@ -36,6 +36,24 @@ static bool nl80211_type_check(enum nl80 } } +static bool nl80211_params_check (enum nl80211_iftype type, +struct vif_params *params) +{ +if (!nl80211_type_check (type)) +return false; + +if (params->use_4addr >0 ) { +switch (type) { +case NL80211_IFTYPE_AP_VLAN : +case NL80211_IFTYPE_STATION : +break ; +default : +return false; + } + } +return true; +} +static int ieee80211_add_iface (struct wiphy *wiphy,char *name,enum nl80211_iftype type,u32 *flags,struct vif_params *params)
@@ -45,7 +63,7 @@ static int ieee80211_add_iface(struct wistruct ieee80211_sub_if_data *sdata;int err; -if (!nl80211_type_check (type)) +if (!nl80211_params_check (type, params))return -EINVAL ; err =ieee80211_if_add (local, name, &dev, type, params);
@@ -75,7 +93,7 @@ static int ieee80211_change_iface(structif (netif_running (dev))return -EBUSY ; -if (!nl80211_type_check (type)) +if (!nl80211_params_check (type, params))return -EINVAL ; sdata =IEEE80211_DEV_TO_SUB_IF (dev);
@@ -89,6 +107,9 @@ static int ieee80211_change_iface(struct params->mesh_id_len, params->mesh_id); +if (params->use_4addr >=0 ) + sdata->use_4addr = !!params->use_4addr; +if (sdata->vif.type !=NL80211_IFTYPE_MONITOR || !flags)return 0 ;
@@ -806,6 +827,13 @@ static int ieee80211_change_station(strureturn -EINVAL ; } +if (vlansdata->use_4addr) { +if (vlansdata->u.vlan.sta) +return -EBUSY ; + +rcu_assign_pointer (vlansdata->u.vlan.sta, sta); + } + sta->sdata = vlansdata;ieee80211_send_layer2_update (sta); }
net/mac80211/sta_info.c +3 -0
@@ -489,6 +489,9 @@ static void __sta_info_unlink(struct sta local->num_sta--; local->sta_generation++; +if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) +rcu_assign_pointer (sdata->u.vlan.sta,NULL ); +if (local->ops->sta_notify) {if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) sdata = container_of(sdata->bss,
net/mac80211/tx.c +37 -8
71 lines not on this page · raw message
net/mac80211/iface.c +4 -0
@@ -772,6 +772,7 @@ int ieee80211_if_change_type(struct ieeeieee80211_mandatory_rates (sdata->local, sdata->local->hw.conf.channel->band); sdata->drop_unencrypted =0 ; + sdata->use_4addr =0 ;return 0 ; }
@@ -853,6 +854,9 @@ int ieee80211_if_add(struct ieee80211_lo params->mesh_id_len, params->mesh_id); +if (params && params->use_4addr >=0 ) + sdata->use_4addr = !!params->use_4addr; +mutex_lock (&local->iflist_mtx);list_add_tail_rcu (&sdata->list, &local->interfaces);mutex_unlock (&local->iflist_mtx);
net/mac80211/rx.c +18 -2
@@ -1237,6 +1237,13 @@ __ieee80211_data_to_8023(struct ieee8021 {struct net_device *dev = rx->dev;struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + +if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN && !sdata->use_4addr && +ieee80211_has_a4 (hdr->frame_control)) +return -1 ; +if (sdata->use_4addr &&is_multicast_ether_addr (hdr->addr1)) +return -1 ;return ieee80211_data_to_8023 (rx->skb, dev->dev_addr, sdata->vif.type); }
@@ -1285,7 +1292,7 @@ ieee80211_deliver_skb(struct ieee80211_rif ((sdata->vif.type ==NL80211_IFTYPE_AP || sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) && !(sdata->flags &IEEE80211_SDATA_DONT_BRIDGE_PACKETS ) && - (rx->flags &IEEE80211_RX_RA_MATCH )) { + (rx->flags &IEEE80211_RX_RA_MATCH ) && !rx->sdata->use_4addr) {if (is_multicast_ether_addr (ehdr->h_dest)) {/* * send multicast frames both to higher layers in
@@ -1590,6 +1597,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ {struct net_device *dev = rx->dev;struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev);__le16 fc = hdr->frame_control;int err;
@@ -1599,6 +1607,14 @@ ieee80211_rx_h_data(struct ieee80211_rx_if (unlikely (!ieee80211_is_data_present (hdr->frame_control)))return RX_DROP_MONITOR ; +/* +* Allow the cooked monitor interface of an AP to see 4-addr frames so +* that a 4-addr station can be detected and moved into a separate VLAN +*/ +if (ieee80211_has_a4 (hdr->frame_control) && + sdata->vif.type ==NL80211_IFTYPE_AP ) +return RX_DROP_MONITOR ; + err =__ieee80211_data_to_8023 (rx);if (unlikely (err))return RX_DROP_UNUSABLE ;
@@ -2039,7 +2055,7 @@ static int prepare_for_handlers(struct iswitch (sdata->vif.type) {case NL80211_IFTYPE_STATION : -if (!bssid) +if (!bssid && !sdata->use_4addr)return 0 ;if (!multicast &&compare_ether_addr (sdata->dev->dev_addr, hdr->addr1) !=0 ) {
net/wireless/util.c +3 -1
@@ -320,7 +320,9 @@ int ieee80211_data_to_8023(struct sk_bufbreak ;case cpu_to_le16 (IEEE80211_FCTL_TODS |IEEE80211_FCTL_FROMDS ):if (unlikely (iftype !=NL80211_IFTYPE_WDS && - iftype !=NL80211_IFTYPE_MESH_POINT )) + iftype !=NL80211_IFTYPE_MESH_POINT && + iftype !=NL80211_IFTYPE_AP_VLAN && + iftype !=NL80211_IFTYPE_STATION ))return -1 ;if (iftype ==NL80211_IFTYPE_MESH_POINT ) { struct ieee80211s_hdr *meshdr =