mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-16 05:50:19 +00:00
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
This commit is contained in:
commit
efec22b468
@ -2651,6 +2651,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
|
||||
*/
|
||||
unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
|
||||
|
||||
/**
|
||||
* ieee80211_get_mesh_hdrlen - get mesh extension header length
|
||||
* @meshhdr: the mesh extension header, only the flags field
|
||||
* (first byte) will be accessed
|
||||
* Returns the length of the extension header, which is always at
|
||||
* least 6 bytes and at most 18 if address 5 and 6 are present.
|
||||
*/
|
||||
unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
|
||||
|
||||
/**
|
||||
* DOC: Data path helpers
|
||||
*
|
||||
|
@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
|
||||
sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
|
||||
sdata->u.ibss.ibss_join_req = jiffies;
|
||||
|
||||
memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
|
||||
memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
|
||||
sdata->u.ibss.ssid_len = params->ssid_len;
|
||||
|
||||
mutex_unlock(&sdata->u.ibss.mtx);
|
||||
|
@ -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, ðertype, 2);
|
||||
if (ethertype == rx->sdata->control_port_protocol)
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
||||
@ -1462,11 +1469,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;
|
||||
@ -1889,6 +1899,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 */
|
||||
@ -1897,7 +1921,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)
|
||||
@ -1911,9 +1936,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();
|
||||
@ -1941,12 +1969,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)
|
||||
@ -2353,6 +2378,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:
|
||||
@ -2371,6 +2400,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) &&
|
||||
@ -2913,10 +2946,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);
|
||||
|
@ -643,13 +643,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
|
||||
break;
|
||||
}
|
||||
|
||||
if (id != WLAN_EID_VENDOR_SPECIFIC &&
|
||||
id != WLAN_EID_QUIET &&
|
||||
test_bit(id, seen_elems)) {
|
||||
elems->parse_error = true;
|
||||
left -= elen;
|
||||
pos += elen;
|
||||
continue;
|
||||
switch (id) {
|
||||
case WLAN_EID_SSID:
|
||||
case WLAN_EID_SUPP_RATES:
|
||||
case WLAN_EID_FH_PARAMS:
|
||||
case WLAN_EID_DS_PARAMS:
|
||||
case WLAN_EID_CF_PARAMS:
|
||||
case WLAN_EID_TIM:
|
||||
case WLAN_EID_IBSS_PARAMS:
|
||||
case WLAN_EID_CHALLENGE:
|
||||
case WLAN_EID_RSN:
|
||||
case WLAN_EID_ERP_INFO:
|
||||
case WLAN_EID_EXT_SUPP_RATES:
|
||||
case WLAN_EID_HT_CAPABILITY:
|
||||
case WLAN_EID_HT_OPERATION:
|
||||
case WLAN_EID_VHT_CAPABILITY:
|
||||
case WLAN_EID_VHT_OPERATION:
|
||||
case WLAN_EID_MESH_ID:
|
||||
case WLAN_EID_MESH_CONFIG:
|
||||
case WLAN_EID_PEER_MGMT:
|
||||
case WLAN_EID_PREQ:
|
||||
case WLAN_EID_PREP:
|
||||
case WLAN_EID_PERR:
|
||||
case WLAN_EID_RANN:
|
||||
case WLAN_EID_CHANNEL_SWITCH:
|
||||
case WLAN_EID_EXT_CHANSWITCH_ANN:
|
||||
case WLAN_EID_COUNTRY:
|
||||
case WLAN_EID_PWR_CONSTRAINT:
|
||||
case WLAN_EID_TIMEOUT_INTERVAL:
|
||||
if (test_bit(id, seen_elems)) {
|
||||
elems->parse_error = true;
|
||||
left -= elen;
|
||||
pos += elen;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (calc_crc && id < 64 && (filter & (1ULL << id)))
|
||||
|
@ -526,8 +526,7 @@ int wiphy_register(struct wiphy *wiphy)
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
sband->channels[i].orig_flags =
|
||||
sband->channels[i].flags;
|
||||
sband->channels[i].orig_mag =
|
||||
sband->channels[i].max_antenna_gain;
|
||||
sband->channels[i].orig_mag = INT_MAX;
|
||||
sband->channels[i].orig_mpwr =
|
||||
sband->channels[i].max_power;
|
||||
sband->channels[i].band = band;
|
||||
|
@ -908,7 +908,7 @@ static void handle_channel(struct wiphy *wiphy,
|
||||
map_regdom_flags(reg_rule->flags) | bw_flags;
|
||||
chan->max_antenna_gain = chan->orig_mag =
|
||||
(int) MBI_TO_DBI(power_rule->max_antenna_gain);
|
||||
chan->max_power = chan->orig_mpwr =
|
||||
chan->max_reg_power = chan->max_power = chan->orig_mpwr =
|
||||
(int) MBM_TO_DBM(power_rule->max_eirp);
|
||||
return;
|
||||
}
|
||||
@ -1331,7 +1331,8 @@ static void handle_channel_custom(struct wiphy *wiphy,
|
||||
|
||||
chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
|
||||
chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
|
||||
chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
|
||||
chan->max_reg_power = chan->max_power =
|
||||
(int) MBM_TO_DBM(power_rule->max_eirp);
|
||||
}
|
||||
|
||||
static void handle_band_custom(struct wiphy *wiphy, enum ieee80211_band band,
|
||||
|
@ -309,23 +309,21 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
|
||||
|
||||
static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
|
||||
unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
|
||||
{
|
||||
int ae = meshhdr->flags & MESH_FLAGS_AE;
|
||||
/* 7.1.3.5a.2 */
|
||||
/* 802.11-2012, 8.2.4.7.3 */
|
||||
switch (ae) {
|
||||
default:
|
||||
case 0:
|
||||
return 6;
|
||||
case MESH_FLAGS_AE_A4:
|
||||
return 12;
|
||||
case MESH_FLAGS_AE_A5_A6:
|
||||
return 18;
|
||||
case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
|
||||
return 24;
|
||||
default:
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
|
||||
|
||||
int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
|
||||
enum nl80211_iftype iftype)
|
||||
@ -373,6 +371,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
|
||||
/* make sure meshdr->flags is on the linear part */
|
||||
if (!pskb_may_pull(skb, hdrlen + 1))
|
||||
return -1;
|
||||
if (meshdr->flags & MESH_FLAGS_AE_A4)
|
||||
return -1;
|
||||
if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
|
||||
skb_copy_bits(skb, hdrlen +
|
||||
offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
@ -397,6 +397,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
|
||||
/* make sure meshdr->flags is on the linear part */
|
||||
if (!pskb_may_pull(skb, hdrlen + 1))
|
||||
return -1;
|
||||
if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
|
||||
return -1;
|
||||
if (meshdr->flags & MESH_FLAGS_AE_A4)
|
||||
skb_copy_bits(skb, hdrlen +
|
||||
offsetof(struct ieee80211s_hdr, eaddr1),
|
||||
|
Loading…
Reference in New Issue
Block a user