forked from rubenslte/android_kernel_samsung_msm8226
Merge "mac80211: implement HS2.0 gratuitous ARP/unsolicited NA dropping"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
8713600a1d
@@ -3799,6 +3799,15 @@ void cfg80211_ft_event(struct net_device *netdev,
|
||||
* @gfp: context flags
|
||||
*/
|
||||
void cfg80211_ap_stopped(struct net_device *netdev, gfp_t gfp);
|
||||
/**
|
||||
* cfg80211_is_gratuitous_arp_unsolicited_na - packet is grat. ARP/unsol. NA
|
||||
* @skb: the input packet, must be an ethernet frame already
|
||||
*
|
||||
* Return: %true if the packet is a gratuitous ARP or unsolicited NA packet.
|
||||
* This is used to drop packets that shouldn't occur because the AP implements
|
||||
* a proxy service.
|
||||
*/
|
||||
bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb);
|
||||
|
||||
/* Logging, debugging and troubleshooting/diagnostic helpers. */
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/dsfield.h>
|
||||
#include <net/ndisc.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include "core.h"
|
||||
|
||||
struct ieee80211_rate *
|
||||
@@ -1150,3 +1152,54 @@ EXPORT_SYMBOL(rfc1042_header);
|
||||
const unsigned char bridge_tunnel_header[] __aligned(2) =
|
||||
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
|
||||
EXPORT_SYMBOL(bridge_tunnel_header);
|
||||
|
||||
bool cfg80211_is_gratuitous_arp_unsolicited_na(struct sk_buff *skb)
|
||||
{
|
||||
const struct ethhdr *eth = (void *)skb->data;
|
||||
const struct {
|
||||
struct arphdr hdr;
|
||||
u8 ar_sha[ETH_ALEN];
|
||||
u8 ar_sip[4];
|
||||
u8 ar_tha[ETH_ALEN];
|
||||
u8 ar_tip[4];
|
||||
} __packed *arp;
|
||||
const struct ipv6hdr *ipv6;
|
||||
const struct icmp6hdr *icmpv6;
|
||||
|
||||
switch (eth->h_proto) {
|
||||
case cpu_to_be16(ETH_P_ARP):
|
||||
/* can't say - but will probably be dropped later anyway */
|
||||
if (!pskb_may_pull(skb, sizeof(*eth) + sizeof(*arp)))
|
||||
return false;
|
||||
|
||||
arp = (void *)(eth + 1);
|
||||
|
||||
if ((arp->hdr.ar_op == cpu_to_be16(ARPOP_REPLY) ||
|
||||
arp->hdr.ar_op == cpu_to_be16(ARPOP_REQUEST)) &&
|
||||
!memcmp(arp->ar_sip, arp->ar_tip, sizeof(arp->ar_sip)))
|
||||
return true;
|
||||
break;
|
||||
case cpu_to_be16(ETH_P_IPV6):
|
||||
/* can't say - but will probably be dropped later anyway */
|
||||
if (!pskb_may_pull(skb, sizeof(*eth) + sizeof(*ipv6) +
|
||||
sizeof(*icmpv6)))
|
||||
return false;
|
||||
|
||||
ipv6 = (void *)(eth + 1);
|
||||
icmpv6 = (void *)(ipv6 + 1);
|
||||
|
||||
if (icmpv6->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT &&
|
||||
!memcmp(&ipv6->saddr, &ipv6->daddr, sizeof(ipv6->saddr)))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* no need to support other protocols, proxy service isn't
|
||||
* specified for any others
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_is_gratuitous_arp_unsolicited_na);
|
||||
|
||||
Reference in New Issue
Block a user