Commit 9f718554 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

wifi: cfg80211: factor out bridge tunnel / RFC1042 header check

The same check is done in multiple places, unify it.
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20230213100855.34315-2-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 0f690e6b
...@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) ...@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
} }
EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto)
{
const __be16 *hdr_proto = hdr + ETH_ALEN;
if (!(ether_addr_equal(hdr, rfc1042_header) &&
*hdr_proto != htons(ETH_P_AARP) &&
*hdr_proto != htons(ETH_P_IPX)) &&
!ether_addr_equal(hdr, bridge_tunnel_header))
return false;
*proto = *hdr_proto;
return true;
}
int ieee80211_data_to_8023_exthdr(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,
u8 data_offset, bool is_amsdu) u8 data_offset, bool is_amsdu)
...@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, ...@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
if (likely(!is_amsdu && if (likely(!is_amsdu &&
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 &&
((ether_addr_equal(payload.hdr, rfc1042_header) && ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) {
payload.proto != htons(ETH_P_AARP) && /* remove RFC1042 or Bridge-Tunnel encapsulation */
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; hdrlen += ETH_ALEN + 2;
tmp.h_proto = payload.proto;
skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2); skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2);
} else { } else {
tmp.h_proto = htons(skb->len - hdrlen); tmp.h_proto = htons(skb->len - hdrlen);
...@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, ...@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
{ {
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;
u8 *payload;
int offset = 0, remaining; 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);
...@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, ...@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
frame->dev = skb->dev; frame->dev = skb->dev;
frame->priority = skb->priority; frame->priority = skb->priority;
payload = frame->data; if (likely(ieee80211_get_8023_tunnel_proto(frame->data, &eth.h_proto)))
ethertype = (payload[6] << 8) | payload[7];
if (likely((ether_addr_equal(payload, rfc1042_header) &&
ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
ether_addr_equal(payload, bridge_tunnel_header))) {
eth.h_proto = htons(ethertype);
skb_pull(frame, ETH_ALEN + 2); skb_pull(frame, ETH_ALEN + 2);
}
memcpy(skb_push(frame, sizeof(eth)), &eth, sizeof(eth)); memcpy(skb_push(frame, sizeof(eth)), &eth, sizeof(eth));
__skb_queue_tail(list, frame); __skb_queue_tail(list, frame);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment