提交 7f6990c8 编写于 作者: J Johannes Berg

cfg80211: let ieee80211_amsdu_to_8023s() take only header-less SKB

There's only a single case where has_80211_header is passed as true,
which is in mac80211. Given that there's only simple code that needs
to be done before calling it, export that function from cfg80211
instead and let mac80211 call it itself.
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 ea720935
...@@ -45,7 +45,7 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv, ...@@ -45,7 +45,7 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv,
skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length)); skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
priv->wdev.iftype, 0, false); priv->wdev.iftype, 0);
while (!skb_queue_empty(&list)) { while (!skb_queue_empty(&list)) {
struct rx_packet_hdr *rx_hdr; struct rx_packet_hdr *rx_hdr;
......
...@@ -4039,6 +4039,18 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); ...@@ -4039,6 +4039,18 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
* that do not do the 802.11/802.3 conversion on the device. * that do not do the 802.11/802.3 conversion on the device.
*/ */
/**
* ieee80211_data_to_8023_exthdr - convert an 802.11 data frame to 802.3
* @skb: the 802.11 data frame
* @ehdr: pointer to a &struct ethhdr that will get the header, instead
* of it being pushed into the SKB
* @addr: the device MAC address
* @iftype: the virtual interface type
* Return: 0 on success. Non-zero on error.
*/
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
const u8 *addr, enum nl80211_iftype iftype);
/** /**
* ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
* @skb: the 802.11 data frame * @skb: the 802.11 data frame
...@@ -4046,8 +4058,11 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); ...@@ -4046,8 +4058,11 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
* @iftype: the virtual interface type * @iftype: the virtual interface type
* Return: 0 on success. Non-zero on error. * Return: 0 on success. Non-zero on error.
*/ */
int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
enum nl80211_iftype iftype); enum nl80211_iftype iftype)
{
return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);
}
/** /**
* ieee80211_data_from_8023 - convert an 802.3 frame to 802.11 * ieee80211_data_from_8023 - convert an 802.3 frame to 802.11
...@@ -4065,22 +4080,20 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, ...@@ -4065,22 +4080,20 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
/** /**
* ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame
* *
* Decode an IEEE 802.11n A-MSDU frame and convert it to a list of * Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames.
* 802.3 frames. The @list will be empty if the decode fails. The * The @list will be empty if the decode fails. The @skb must be fully
* @skb is consumed after the function returns. * header-less before being passed in here; it is freed in this function.
* *
* @skb: The input IEEE 802.11n A-MSDU frame. * @skb: The input A-MSDU frame without any headers.
* @list: The output list of 802.3 frames. It must be allocated and * @list: The output list of 802.3 frames. It must be allocated and
* initialized by by the caller. * initialized by by the caller.
* @addr: The device MAC address. * @addr: The device MAC address.
* @iftype: The device interface type. * @iftype: The device interface type.
* @extra_headroom: The hardware extra headroom for SKBs in the @list. * @extra_headroom: The hardware extra headroom for SKBs in the @list.
* @has_80211_header: Set it true if SKB is with IEEE 802.11 header.
*/ */
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
const u8 *addr, enum nl80211_iftype iftype, const u8 *addr, enum nl80211_iftype iftype,
const unsigned int extra_headroom, const unsigned int extra_headroom);
bool has_80211_header);
/** /**
* cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
......
...@@ -2298,6 +2298,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) ...@@ -2298,6 +2298,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
__le16 fc = hdr->frame_control; __le16 fc = hdr->frame_control;
struct sk_buff_head frame_list; struct sk_buff_head frame_list;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
struct ethhdr ethhdr;
if (unlikely(!ieee80211_is_data(fc))) if (unlikely(!ieee80211_is_data(fc)))
return RX_CONTINUE; return RX_CONTINUE;
...@@ -2329,9 +2330,14 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) ...@@ -2329,9 +2330,14 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
skb->dev = dev; skb->dev = dev;
__skb_queue_head_init(&frame_list); __skb_queue_head_init(&frame_list);
if (ieee80211_data_to_8023_exthdr(skb, &ethhdr,
rx->sdata->vif.addr,
rx->sdata->vif.type))
return RX_DROP_UNUSABLE;
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
rx->sdata->vif.type, rx->sdata->vif.type,
rx->local->hw.extra_tx_headroom, true); rx->local->hw.extra_tx_headroom);
while (!skb_queue_empty(&frame_list)) { while (!skb_queue_empty(&frame_list)) {
rx->skb = __skb_dequeue(&frame_list); rx->skb = __skb_dequeue(&frame_list);
......
...@@ -420,8 +420,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) ...@@ -420,8 +420,8 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
} }
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
static int __ieee80211_data_to_8023(struct sk_buff *skb, struct ethhdr *ehdr, int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
const u8 *addr, enum nl80211_iftype iftype) const u8 *addr, enum nl80211_iftype iftype)
{ {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct { struct {
...@@ -525,13 +525,7 @@ static int __ieee80211_data_to_8023(struct sk_buff *skb, struct ethhdr *ehdr, ...@@ -525,13 +525,7 @@ static int __ieee80211_data_to_8023(struct sk_buff *skb, struct ethhdr *ehdr,
return 0; return 0;
} }
EXPORT_SYMBOL(ieee80211_data_to_8023_exthdr);
int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
enum nl80211_iftype iftype)
{
return __ieee80211_data_to_8023(skb, NULL, addr, iftype);
}
EXPORT_SYMBOL(ieee80211_data_to_8023);
int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
enum nl80211_iftype iftype, enum nl80211_iftype iftype,
...@@ -745,25 +739,18 @@ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, ...@@ -745,25 +739,18 @@ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
const u8 *addr, enum nl80211_iftype iftype, const u8 *addr, enum nl80211_iftype iftype,
const unsigned int extra_headroom, const unsigned int extra_headroom)
bool has_80211_header)
{ {
unsigned int hlen = ALIGN(extra_headroom, 4); unsigned int hlen = ALIGN(extra_headroom, 4);
struct sk_buff *frame = NULL; struct sk_buff *frame = NULL;
u16 ethertype; u16 ethertype;
u8 *payload; u8 *payload;
int offset = 0, remaining, err; int offset = 0, remaining;
struct ethhdr eth; struct ethhdr eth;
bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb);
bool reuse_skb = false; bool reuse_skb = false;
bool last = false; bool last = false;
if (has_80211_header) {
err = __ieee80211_data_to_8023(skb, &eth, addr, iftype);
if (err)
goto out;
}
while (!last) { while (!last) {
unsigned int subframe_len; unsigned int subframe_len;
int len; int len;
...@@ -819,7 +806,6 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, ...@@ -819,7 +806,6 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
purge: purge:
__skb_queue_purge(list); __skb_queue_purge(list);
out:
dev_kfree_skb(skb); dev_kfree_skb(skb);
} }
EXPORT_SYMBOL(ieee80211_amsdu_to_8023s); EXPORT_SYMBOL(ieee80211_amsdu_to_8023s);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册