From 0dad032b69ab5b129ecdbe6619be42938bb9924f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 4 Feb 2016 13:31:18 +0100 Subject: [PATCH] ipv4: add option to drop gratuitous ARP packets In certain 802.11 wireless deployments, there will be ARP proxies that use knowledge of the network to correctly answer requests. To prevent gratuitous ARP frames on the shared medium from being a problem, on such deployments wireless needs to drop them. Enable this by providing an option called "drop_gratuitous_arp". Signed-off-by: Johannes Berg Signed-off-by: David S. Miller (cherry picked from commit 4078228159c9f54cca7347a8bdace29f2abdef65) Change-Id: I8772dbd7471085878f8b4161eb2a056d79b8b232 --- Documentation/networking/ip-sysctl.txt | 5 +++++ include/uapi/linux/ip.h | 1 + net/ipv4/arp.c | 8 ++++++++ net/ipv4/devinet.c | 2 ++ 4 files changed, 16 insertions(+) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2dc947fa5ad8..f5f99b8c3c00 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1060,6 +1060,11 @@ drop_unicast_in_l2_multicast - BOOLEAN 1122, but is disabled by default for compatibility reasons. Default: off (0) +drop_gratuitous_arp - BOOLEAN + Drop all gratuitous ARP frames, for example if there's a known + good ARP proxy on the network and such frames need not be used + (or in the case of 802.11, must not be used to prevent attacks.) + Default: off (0) tag - INTEGER Allows you to write a number, which can be used as required. diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h index a948faea6257..289371fe9761 100644 --- a/include/uapi/linux/ip.h +++ b/include/uapi/linux/ip.h @@ -163,6 +163,7 @@ enum IPV4_DEVCONF_PROXY_ARP_PVLAN, IPV4_DEVCONF_ROUTE_LOCALNET, IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, + IPV4_DEVCONF_DROP_GRATUITOUS_ARP, __IPV4_DEVCONF_MAX }; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 8f93f3c3a06a..1c70e4c1ac1a 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -809,6 +809,14 @@ static int arp_process(struct sk_buff *skb) (!IN_DEV_ROUTE_LOCALNET(in_dev) && ipv4_is_loopback(tip))) goto out; +/* + * For some 802.11 wireless deployments (and possibly other networks), + * there will be an ARP proxy and gratuitous ARP frames are attacks + * and thus should not be accepted. + */ + if (sip == tip && IN_DEV_ORCONF(in_dev, DROP_GRATUITOUS_ARP)) + goto out; + /* * Special case: We must set Frame Relay source Q.922 address */ diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 238858a9276f..7479513f0db4 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -2109,6 +2109,8 @@ static struct devinet_sysctl_table { DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"), DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"), DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"), + DEVINET_SYSCTL_RW_ENTRY(DROP_GRATUITOUS_ARP, + "drop_gratuitous_arp"), DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),