wireless fixes for v6.1
First set of fixes for v6.1. Quite a lot of fixes in stack but also for mt76. cfg80211/mac80211 * fix locking error in mac80211's hw addr change * fix TX queue stop for internal TXQs * handling of very small (e.g. STP TCN) packets * two memcpy() hardening fixes * fix probe request 6 GHz capability warning * fix various connection prints * fix decapsulation offload for AP VLAN mt76 * fix rate reporting, LLC packets and receive checksum offload on specific chipsets iwlwifi * fix crash due to list corruption ath11k * fix a compiler warning with GCC 11 and KASAN -----BEGIN PGP SIGNATURE----- iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmNFmekRHGt2YWxvQGtl cm5lbC5vcmcACgkQbhckVSbrbZvdswf/ZMyK5fTQBzOoAna360T8YIHqTaWtpLxt Uf4OrB0SlzHgEFPBdPqJHarVCoCaRvj31Y7iFc6bHtKpVgra170HQebbaKZWbLZ1 pKlL75mrwH2K+A+wJDEPnpyAXB1hCmswDApOfLc3RSLnFd3h2muLsJeAEny6Z1Ua 62Sz/IqbdpgTHeh0kJqOTNw50GBiUOAYQhnNeHTjoc4b76dRViAptGLZE1AueoPM mv8hIkMDgmoZA10sIg2cZJcTARfvLfh534rtZ2r0oml3d9TX2fpjVP6N+UQIEPgr lAkltywDtKWpgUCVsNTN82kRpVGa2QPUq8Ey/yTsNBqu9iuHSlgs3w== =b5ut -----END PGP SIGNATURE----- Merge tag 'wireless-2022-10-11' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless Kalle Valo says: ==================== wireless fixes for v6.1 First set of fixes for v6.1. Quite a lot of fixes in stack but also for mt76. cfg80211/mac80211 - fix locking error in mac80211's hw addr change - fix TX queue stop for internal TXQs - handling of very small (e.g. STP TCN) packets - two memcpy() hardening fixes - fix probe request 6 GHz capability warning - fix various connection prints - fix decapsulation offload for AP VLAN mt76 - fix rate reporting, LLC packets and receive checksum offload on specific chipsets iwlwifi - fix crash due to list corruption ath11k - fix a compiler warning with GCC 11 and KASAN * tag 'wireless-2022-10-11' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: ath11k: mac: fix reading 16 bytes from a region of size 0 warning wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue (other cases) wifi: mt76: fix rx checksum offload on mt7615/mt7915/mt7921 wifi: mt76: fix receiving LLC packets on mt7615/mt7915 wifi: nl80211: Split memcpy() of struct nl80211_wowlan_tcp_data_token flexible array wifi: wext: use flex array destination for memcpy() wifi: cfg80211: fix ieee80211_data_to_8023_exthdr handling of small packets wifi: mac80211: netdev compatible TX stop for iTXQ drivers wifi: mac80211: fix decap offload for stations on AP_VLAN interfaces wifi: mac80211: unlock on error in ieee80211_can_powered_addr_change() wifi: mac80211: remove/avoid misleading prints wifi: mac80211: fix probe req HE capabilities access wifi: mac80211: do not drop packets smaller than the LLC-SNAP header on fast-rx wifi: mt76: fix rate reporting / throughput regression on mt7915 and newer ==================== Link: https://lore.kernel.org/r/20221011163123.A093CC433D6@smtp.kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
72da9dc22f
@ -2081,7 +2081,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
|
||||
struct cfg80211_chan_def def;
|
||||
const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
|
||||
enum nl80211_band band;
|
||||
u16 *he_mcs_mask;
|
||||
u16 he_mcs_mask[NL80211_HE_NSS_MAX];
|
||||
u8 max_nss, he_mcs;
|
||||
u16 he_tx_mcs = 0, v = 0;
|
||||
int i, he_nss, nss_idx;
|
||||
@ -2098,7 +2098,8 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
|
||||
return;
|
||||
|
||||
band = def.chan->band;
|
||||
he_mcs_mask = arvif->bitrate_mask.control[band].he_mcs;
|
||||
memcpy(he_mcs_mask, arvif->bitrate_mask.control[band].he_mcs,
|
||||
sizeof(he_mcs_mask));
|
||||
|
||||
if (ath11k_peer_assoc_h_he_masked(he_mcs_mask))
|
||||
return;
|
||||
|
@ -384,6 +384,7 @@ static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
iwl_mvm_txq_from_tid(sta, tid);
|
||||
|
||||
mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
|
||||
list_del_init(&mvmtxq->list);
|
||||
}
|
||||
|
||||
/* Regardless if this is a reserved TXQ for a STA - mark it as false */
|
||||
@ -478,6 +479,7 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue)
|
||||
mvmsta->tid_data[tid].txq_id = IWL_MVM_INVALID_QUEUE;
|
||||
|
||||
mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE;
|
||||
list_del_init(&mvmtxq->list);
|
||||
}
|
||||
|
||||
mvmsta->tfd_queue_msk &= ~BIT(queue); /* Don't use this queue anymore */
|
||||
|
@ -696,10 +696,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
|
||||
|
||||
skb_reserve(skb, q->buf_offset);
|
||||
|
||||
if (q == &dev->q_rx[MT_RXQ_MCU]) {
|
||||
u32 *rxfce = (u32 *)skb->cb;
|
||||
*rxfce = info;
|
||||
}
|
||||
*(u32 *)skb->cb = info;
|
||||
|
||||
__skb_put(skb, len);
|
||||
done++;
|
||||
|
@ -345,6 +345,7 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
u32 rxd1 = le32_to_cpu(rxd[1]);
|
||||
u32 rxd2 = le32_to_cpu(rxd[2]);
|
||||
u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM;
|
||||
u32 csum_status = *(u32 *)skb->cb;
|
||||
bool unicast, hdr_trans, remove_pad, insert_ccmp_hdr = false;
|
||||
u16 hdr_gap;
|
||||
int phy_idx;
|
||||
@ -394,7 +395,8 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
spin_unlock_bh(&dev->sta_poll_lock);
|
||||
}
|
||||
|
||||
if ((rxd0 & csum_mask) == csum_mask)
|
||||
if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask &&
|
||||
!(csum_status & (BIT(0) | BIT(2) | BIT(3))))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
if (rxd2 & MT_RXD2_NORMAL_FCS_ERR)
|
||||
@ -610,14 +612,14 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
* When header translation failure is indicated,
|
||||
* the hardware will insert an extra 2-byte field
|
||||
* containing the data length after the protocol
|
||||
* type field.
|
||||
* type field. This happens either when the LLC-SNAP
|
||||
* pattern did not match, or if a VLAN header was
|
||||
* detected.
|
||||
*/
|
||||
pad_start = 12;
|
||||
if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
|
||||
pad_start += 4;
|
||||
|
||||
if (get_unaligned_be16(skb->data + pad_start) !=
|
||||
skb->len - pad_start - 2)
|
||||
else
|
||||
pad_start = 0;
|
||||
}
|
||||
|
||||
|
@ -233,6 +233,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
u8 remove_pad, amsdu_info;
|
||||
u8 mode = 0, qos_ctl = 0;
|
||||
struct mt7915_sta *msta = NULL;
|
||||
u32 csum_status = *(u32 *)skb->cb;
|
||||
bool hdr_trans;
|
||||
u16 hdr_gap;
|
||||
u16 seq_ctrl = 0;
|
||||
@ -288,7 +289,8 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
if (!sband->channels)
|
||||
return -EINVAL;
|
||||
|
||||
if ((rxd0 & csum_mask) == csum_mask)
|
||||
if ((rxd0 & csum_mask) == csum_mask &&
|
||||
!(csum_status & (BIT(0) | BIT(2) | BIT(3))))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
if (rxd1 & MT_RXD1_NORMAL_FCS_ERR)
|
||||
@ -446,14 +448,14 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
* When header translation failure is indicated,
|
||||
* the hardware will insert an extra 2-byte field
|
||||
* containing the data length after the protocol
|
||||
* type field.
|
||||
* type field. This happens either when the LLC-SNAP
|
||||
* pattern did not match, or if a VLAN header was
|
||||
* detected.
|
||||
*/
|
||||
pad_start = 12;
|
||||
if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
|
||||
pad_start += 4;
|
||||
|
||||
if (get_unaligned_be16(skb->data + pad_start) !=
|
||||
skb->len - pad_start - 2)
|
||||
else
|
||||
pad_start = 0;
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
|
||||
struct mt76_phy *mphy = &dev->mt76.phy;
|
||||
struct mt7921_phy *phy = &dev->phy;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u32 csum_status = *(u32 *)skb->cb;
|
||||
u32 rxd0 = le32_to_cpu(rxd[0]);
|
||||
u32 rxd1 = le32_to_cpu(rxd[1]);
|
||||
u32 rxd2 = le32_to_cpu(rxd[2]);
|
||||
@ -290,7 +291,8 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
|
||||
if (!sband->channels)
|
||||
return -EINVAL;
|
||||
|
||||
if ((rxd0 & csum_mask) == csum_mask)
|
||||
if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask &&
|
||||
!(csum_status & (BIT(0) | BIT(2) | BIT(3))))
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
if (rxd1 & MT_RXD1_NORMAL_FCS_ERR)
|
||||
|
@ -60,14 +60,20 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list)
|
||||
.skb = skb,
|
||||
.info = IEEE80211_SKB_CB(skb),
|
||||
};
|
||||
struct ieee80211_rate_status rs = {};
|
||||
struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb);
|
||||
struct mt76_wcid *wcid;
|
||||
|
||||
wcid = rcu_dereference(dev->wcid[cb->wcid]);
|
||||
if (wcid) {
|
||||
status.sta = wcid_to_sta(wcid);
|
||||
status.rates = NULL;
|
||||
status.n_rates = 0;
|
||||
if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) {
|
||||
rs.rate_idx = wcid->rate;
|
||||
status.rates = &rs;
|
||||
status.n_rates = 1;
|
||||
} else {
|
||||
status.n_rates = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hw = mt76_tx_status_get_hw(dev, skb);
|
||||
|
@ -26,7 +26,15 @@ struct compat_iw_point {
|
||||
struct __compat_iw_event {
|
||||
__u16 len; /* Real length of this stuff */
|
||||
__u16 cmd; /* Wireless IOCTL */
|
||||
compat_caddr_t pointer;
|
||||
|
||||
union {
|
||||
compat_caddr_t pointer;
|
||||
|
||||
/* we need ptr_bytes to make memcpy() run-time destination
|
||||
* buffer bounds checking happy, nothing special
|
||||
*/
|
||||
DECLARE_FLEX_ARRAY(__u8, ptr_bytes);
|
||||
};
|
||||
};
|
||||
#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
|
||||
#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
|
||||
|
@ -243,7 +243,7 @@ static int ieee80211_can_powered_addr_change(struct ieee80211_sub_if_data *sdata
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
unlock:
|
||||
@ -461,7 +461,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
|
||||
/*
|
||||
* Stop TX on this interface first.
|
||||
*/
|
||||
if (sdata->dev)
|
||||
if (!local->ops->wake_tx_queue && sdata->dev)
|
||||
netif_tx_stop_all_queues(sdata->dev);
|
||||
|
||||
ieee80211_roc_purge(local, sdata);
|
||||
@ -1412,8 +1412,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||
sdata->vif.type != NL80211_IFTYPE_STATION);
|
||||
}
|
||||
|
||||
set_bit(SDATA_STATE_RUNNING, &sdata->state);
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
rcu_assign_pointer(local->p2p_sdata, sdata);
|
||||
@ -1472,6 +1470,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
||||
set_bit(SDATA_STATE_RUNNING, &sdata->state);
|
||||
|
||||
return 0;
|
||||
err_del_interface:
|
||||
drv_remove_interface(local, sdata);
|
||||
|
@ -4409,8 +4409,11 @@ ieee80211_verify_peer_he_mcs_support(struct ieee80211_sub_if_data *sdata,
|
||||
he_cap_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY,
|
||||
ies->data, ies->len);
|
||||
|
||||
if (!he_cap_elem)
|
||||
return false;
|
||||
|
||||
/* invalid HE IE */
|
||||
if (!he_cap_elem || he_cap_elem->datalen < 1 + sizeof(*he_cap)) {
|
||||
if (he_cap_elem->datalen < 1 + sizeof(*he_cap)) {
|
||||
sdata_info(sdata,
|
||||
"Invalid HE elem, Disable HE\n");
|
||||
return false;
|
||||
@ -4676,8 +4679,6 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
if (!elems->vht_cap_elem) {
|
||||
sdata_info(sdata,
|
||||
"bad VHT capabilities, disabling VHT\n");
|
||||
*conn_flags |= IEEE80211_CONN_DISABLE_VHT;
|
||||
vht_oper = NULL;
|
||||
}
|
||||
|
@ -4352,6 +4352,7 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
|
||||
.vif_type = sdata->vif.type,
|
||||
.control_port_protocol = sdata->control_port_protocol,
|
||||
}, *old, *new = NULL;
|
||||
u32 offload_flags;
|
||||
bool set_offload = false;
|
||||
bool assign = false;
|
||||
bool offload;
|
||||
@ -4467,10 +4468,10 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
|
||||
if (assign)
|
||||
new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);
|
||||
|
||||
offload = assign &&
|
||||
(sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED);
|
||||
offload_flags = get_bss_sdata(sdata)->vif.offload_flags;
|
||||
offload = offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
|
||||
if (offload)
|
||||
if (assign && offload)
|
||||
set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
|
||||
else
|
||||
set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
|
||||
@ -4708,7 +4709,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
|
||||
if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
|
||||
if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))
|
||||
goto drop;
|
||||
return false;
|
||||
|
||||
payload = (void *)(skb->data + snap_offs);
|
||||
|
||||
|
@ -2319,6 +2319,10 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
|
||||
u16 len_rthdr;
|
||||
int hdrlen;
|
||||
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
if (unlikely(!ieee80211_sdata_running(sdata)))
|
||||
goto fail;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
|
||||
IEEE80211_TX_CTL_INJECTED;
|
||||
@ -2378,8 +2382,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
|
||||
* This is necessary, for example, for old hostapd versions that
|
||||
* don't use nl80211-based management TX/RX.
|
||||
*/
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
list_for_each_entry_rcu(tmp_sdata, &local->interfaces, list) {
|
||||
if (!ieee80211_sdata_running(tmp_sdata))
|
||||
continue;
|
||||
@ -4169,7 +4171,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct sk_buff *next;
|
||||
int len = skb->len;
|
||||
|
||||
if (unlikely(skb->len < ETH_HLEN)) {
|
||||
if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
@ -4566,7 +4568,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
|
||||
struct ieee80211_key *key;
|
||||
struct sta_info *sta;
|
||||
|
||||
if (unlikely(skb->len < ETH_HLEN)) {
|
||||
if (unlikely(!ieee80211_sdata_running(sdata) || skb->len < ETH_HLEN)) {
|
||||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
@ -2046,7 +2046,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
|
||||
if (he_cap) {
|
||||
enum nl80211_iftype iftype =
|
||||
ieee80211_vif_type_p2p(&sdata->vif);
|
||||
__le16 cap = ieee80211_get_he_6ghz_capa(sband, iftype);
|
||||
__le16 cap = ieee80211_get_he_6ghz_capa(sband6, iftype);
|
||||
|
||||
pos = ieee80211_write_he_6ghz_cap(pos, cap, end);
|
||||
}
|
||||
|
@ -13265,7 +13265,9 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
|
||||
wake_mask_size);
|
||||
if (tok) {
|
||||
cfg->tokens_size = tokens_size;
|
||||
memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
|
||||
cfg->payload_tok = *tok;
|
||||
memcpy(cfg->payload_tok.token_stream, tok->token_stream,
|
||||
tokens_size);
|
||||
}
|
||||
|
||||
trig->tcp = cfg;
|
||||
|
@ -559,7 +559,7 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
return -1;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset;
|
||||
if (skb->len < hdrlen + 8)
|
||||
if (skb->len < hdrlen)
|
||||
return -1;
|
||||
|
||||
/* convert IEEE 802.11 header + possible LLC headers into Ethernet
|
||||
@ -574,8 +574,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN);
|
||||
memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN);
|
||||
|
||||
if (iftype == NL80211_IFTYPE_MESH_POINT)
|
||||
skb_copy_bits(skb, hdrlen, &mesh_flags, 1);
|
||||
if (iftype == NL80211_IFTYPE_MESH_POINT &&
|
||||
skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0)
|
||||
return -1;
|
||||
|
||||
mesh_flags &= MESH_FLAGS_AE;
|
||||
|
||||
@ -595,11 +596,12 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
if (iftype == NL80211_IFTYPE_MESH_POINT) {
|
||||
if (mesh_flags == MESH_FLAGS_AE_A4)
|
||||
return -1;
|
||||
if (mesh_flags == MESH_FLAGS_AE_A5_A6) {
|
||||
skb_copy_bits(skb, hdrlen +
|
||||
offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
tmp.h_dest, 2 * ETH_ALEN);
|
||||
}
|
||||
if (mesh_flags == MESH_FLAGS_AE_A5_A6 &&
|
||||
skb_copy_bits(skb, hdrlen +
|
||||
offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
tmp.h_dest, 2 * ETH_ALEN) < 0)
|
||||
return -1;
|
||||
|
||||
hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
|
||||
}
|
||||
break;
|
||||
@ -613,10 +615,11 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
if (iftype == NL80211_IFTYPE_MESH_POINT) {
|
||||
if (mesh_flags == MESH_FLAGS_AE_A5_A6)
|
||||
return -1;
|
||||
if (mesh_flags == MESH_FLAGS_AE_A4)
|
||||
skb_copy_bits(skb, hdrlen +
|
||||
offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
tmp.h_source, ETH_ALEN);
|
||||
if (mesh_flags == MESH_FLAGS_AE_A4 &&
|
||||
skb_copy_bits(skb, hdrlen +
|
||||
offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
tmp.h_source, ETH_ALEN) < 0)
|
||||
return -1;
|
||||
hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags);
|
||||
}
|
||||
break;
|
||||
@ -628,16 +631,15 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
|
||||
break;
|
||||
}
|
||||
|
||||
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload));
|
||||
tmp.h_proto = payload.proto;
|
||||
|
||||
if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||
tmp.h_proto != htons(ETH_P_AARP) &&
|
||||
tmp.h_proto != htons(ETH_P_IPX)) ||
|
||||
ether_addr_equal(payload.hdr, bridge_tunnel_header))) {
|
||||
if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
|
||||
((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) &&
|
||||
payload.proto != htons(ETH_P_AARP) &&
|
||||
payload.proto != htons(ETH_P_IPX)) ||
|
||||
ether_addr_equal(payload.hdr, bridge_tunnel_header)))) {
|
||||
/* remove RFC1042 or Bridge-Tunnel encapsulation and
|
||||
* replace EtherType */
|
||||
hdrlen += ETH_ALEN + 2;
|
||||
tmp.h_proto = payload.proto;
|
||||
skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2);
|
||||
} else {
|
||||
tmp.h_proto = htons(skb->len - hdrlen);
|
||||
|
@ -468,6 +468,7 @@ void wireless_send_event(struct net_device * dev,
|
||||
struct __compat_iw_event *compat_event;
|
||||
struct compat_iw_point compat_wrqu;
|
||||
struct sk_buff *compskb;
|
||||
int ptr_len;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -582,6 +583,9 @@ void wireless_send_event(struct net_device * dev,
|
||||
nlmsg_end(skb, nlh);
|
||||
#ifdef CONFIG_COMPAT
|
||||
hdr_len = compat_event_type_size[descr->header_type];
|
||||
|
||||
/* ptr_len is remaining size in event header apart from LCP */
|
||||
ptr_len = hdr_len - IW_EV_COMPAT_LCP_LEN;
|
||||
event_len = hdr_len + extra_len;
|
||||
|
||||
compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
|
||||
@ -612,16 +616,15 @@ void wireless_send_event(struct net_device * dev,
|
||||
if (descr->header_type == IW_HEADER_TYPE_POINT) {
|
||||
compat_wrqu.length = wrqu->data.length;
|
||||
compat_wrqu.flags = wrqu->data.flags;
|
||||
memcpy(&compat_event->pointer,
|
||||
((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
|
||||
hdr_len - IW_EV_COMPAT_LCP_LEN);
|
||||
memcpy(compat_event->ptr_bytes,
|
||||
((char *)&compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
|
||||
ptr_len);
|
||||
if (extra_len)
|
||||
memcpy(((char *) compat_event) + hdr_len,
|
||||
extra, extra_len);
|
||||
memcpy(&compat_event->ptr_bytes[ptr_len],
|
||||
extra, extra_len);
|
||||
} else {
|
||||
/* extra_len must be zero, so no if (extra) needed */
|
||||
memcpy(&compat_event->pointer, wrqu,
|
||||
hdr_len - IW_EV_COMPAT_LCP_LEN);
|
||||
memcpy(compat_event->ptr_bytes, wrqu, ptr_len);
|
||||
}
|
||||
|
||||
nlmsg_end(compskb, nlh);
|
||||
|
Loading…
Reference in New Issue
Block a user