diff options
Diffstat (limited to 'package/mac80211/patches/510-mac80211_4addr_vlan.patch')
-rw-r--r-- | package/mac80211/patches/510-mac80211_4addr_vlan.patch | 269 |
1 files changed, 0 insertions, 269 deletions
diff --git a/package/mac80211/patches/510-mac80211_4addr_vlan.patch b/package/mac80211/patches/510-mac80211_4addr_vlan.patch deleted file mode 100644 index d3d1e82..0000000 --- a/package/mac80211/patches/510-mac80211_4addr_vlan.patch +++ /dev/null @@ -1,269 +0,0 @@ ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -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; ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -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 wi - struct 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(struct - if (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(stru - return -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); - } ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -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, ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1046,7 +1046,10 @@ ieee80211_tx_prepare(struct ieee80211_su - - hdr = (struct ieee80211_hdr *) skb->data; - -- tx->sta = sta_info_get(local, hdr->addr1); -+ if ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && sdata->use_4addr) -+ tx->sta = rcu_dereference(sdata->u.vlan.sta); -+ if (!tx->sta) -+ tx->sta = sta_info_get(local, hdr->addr1); - - if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && - (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { -@@ -1608,7 +1611,7 @@ netdev_tx_t ieee80211_subif_start_xmit(s - const u8 *encaps_data; - int encaps_len, skip_header_bytes; - int nh_pos, h_pos; -- struct sta_info *sta; -+ struct sta_info *sta = NULL; - u32 sta_flags = 0; - - if (unlikely(skb->len < ETH_HLEN)) { -@@ -1625,8 +1628,25 @@ netdev_tx_t ieee80211_subif_start_xmit(s - fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); - - switch (sdata->vif.type) { -- case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: -+ rcu_read_lock(); -+ if (sdata->use_4addr) -+ sta = rcu_dereference(sdata->u.vlan.sta); -+ if (sta) { -+ fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); -+ /* RA TA DA SA */ -+ memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN); -+ memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); -+ memcpy(hdr.addr3, skb->data, ETH_ALEN); -+ memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); -+ hdrlen = 30; -+ sta_flags = get_sta_flags(sta); -+ } -+ rcu_read_unlock(); -+ if (sta) -+ break; -+ /* fall through */ -+ case NL80211_IFTYPE_AP: - fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); - /* DA BSSID SA */ - memcpy(hdr.addr1, skb->data, ETH_ALEN); -@@ -1700,12 +1720,21 @@ netdev_tx_t ieee80211_subif_start_xmit(s - break; - #endif - case NL80211_IFTYPE_STATION: -- fc |= cpu_to_le16(IEEE80211_FCTL_TODS); -- /* BSSID SA DA */ - memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); -- memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); -- memcpy(hdr.addr3, skb->data, ETH_ALEN); -- hdrlen = 24; -+ if (sdata->use_4addr && ethertype != ETH_P_PAE) { -+ fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); -+ /* RA TA DA SA */ -+ memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); -+ memcpy(hdr.addr3, skb->data, ETH_ALEN); -+ memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); -+ hdrlen = 30; -+ } else { -+ fc |= cpu_to_le16(IEEE80211_FCTL_TODS); -+ /* BSSID SA DA */ -+ memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); -+ memcpy(hdr.addr3, skb->data, ETH_ALEN); -+ hdrlen = 24; -+ } - break; - case NL80211_IFTYPE_ADHOC: - /* DA SA BSSID */ ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -772,6 +772,7 @@ int ieee80211_if_change_type(struct ieee - ieee80211_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); ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -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_r - if ((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 i - - switch (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) { ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -320,7 +320,9 @@ int ieee80211_data_to_8023(struct sk_buf - break; - 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 = |