Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

Conflicts:
	drivers/net/wireless/mwifiex/cfg80211.c
This commit is contained in:
John W. Linville 2012-10-29 16:05:51 -04:00
commit ab3d59d265
18 changed files with 216 additions and 129 deletions

View file

@ -531,6 +531,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
if (ieee80211_is_action(hdr->frame_control)) {
u8 category;
/* make sure category field is present */
if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
return RX_DROP_MONITOR;
mgmt = (struct ieee80211_mgmt *)hdr;
category = mgmt->u.action.category;
if (category != WLAN_CATEGORY_MESH_ACTION &&
@ -883,14 +888,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
*/
if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
ieee80211_is_data_present(hdr->frame_control)) {
u16 ethertype;
u8 *payload;
unsigned int hdrlen;
__be16 ethertype;
payload = rx->skb->data +
ieee80211_hdrlen(hdr->frame_control);
ethertype = (payload[6] << 8) | payload[7];
if (cpu_to_be16(ethertype) ==
rx->sdata->control_port_protocol)
hdrlen = ieee80211_hdrlen(hdr->frame_control);
if (rx->skb->len < hdrlen + 8)
return RX_DROP_MONITOR;
skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
if (ethertype == rx->sdata->control_port_protocol)
return RX_CONTINUE;
}
@ -1467,11 +1474,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
hdr = (struct ieee80211_hdr *)rx->skb->data;
fc = hdr->frame_control;
if (ieee80211_is_ctl(fc))
return RX_CONTINUE;
sc = le16_to_cpu(hdr->seq_ctrl);
frag = sc & IEEE80211_SCTL_FRAG;
if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
(rx->skb)->len < 24 ||
is_multicast_ether_addr(hdr->addr1))) {
/* not fragmented */
goto out;
@ -1894,6 +1904,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
/* make sure fixed part of mesh header is there, also checks skb len */
if (!pskb_may_pull(rx->skb, hdrlen + 6))
return RX_DROP_MONITOR;
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
/* make sure full mesh header is there, also checks skb len */
if (!pskb_may_pull(rx->skb,
hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
return RX_DROP_MONITOR;
/* reload pointers */
hdr = (struct ieee80211_hdr *) skb->data;
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
/* frame is in RMC, don't forward */
@ -1902,7 +1926,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))
return RX_DROP_MONITOR;
if (!ieee80211_is_data(hdr->frame_control))
if (!ieee80211_is_data(hdr->frame_control) ||
!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_CONTINUE;
if (!mesh_hdr->ttl)
@ -1916,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (is_multicast_ether_addr(hdr->addr1)) {
mpp_addr = hdr->addr3;
proxied_addr = mesh_hdr->eaddr1;
} else {
} else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
/* has_a4 already checked in ieee80211_rx_mesh_check */
mpp_addr = hdr->addr4;
proxied_addr = mesh_hdr->eaddr2;
} else {
return RX_DROP_MONITOR;
}
rcu_read_lock();
@ -1946,12 +1974,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
skb_set_queue_mapping(skb, q);
if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
goto out;
if (!--mesh_hdr->ttl) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
return RX_DROP_MONITOR;
goto out;
}
if (!ifmsh->mshcfg.dot11MeshForwarding)
@ -2358,6 +2383,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_SELF_PROTECTED:
if (len < (IEEE80211_MIN_ACTION_SIZE +
sizeof(mgmt->u.action.u.self_prot.action_code)))
break;
switch (mgmt->u.action.u.self_prot.action_code) {
case WLAN_SP_MESH_PEERING_OPEN:
case WLAN_SP_MESH_PEERING_CLOSE:
@ -2376,6 +2405,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_MESH_ACTION:
if (len < (IEEE80211_MIN_ACTION_SIZE +
sizeof(mgmt->u.action.u.mesh_action.action_code)))
break;
if (!ieee80211_vif_is_mesh(&sdata->vif))
break;
if (mesh_action_is_path_sel(mgmt) &&
@ -2918,10 +2951,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
local->dot11ReceivedFragmentCount++;
if (ieee80211_is_mgmt(fc))
err = skb_linearize(skb);
else
if (ieee80211_is_mgmt(fc)) {
/* drop frame if too short for header */
if (skb->len < ieee80211_hdrlen(fc))
err = -ENOBUFS;
else
err = skb_linearize(skb);
} else {
err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
}
if (err) {
dev_kfree_skb(skb);