aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2016-02-04 07:31:20 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-11 04:27:36 -0500
commit7a02bf892d8f1e5298af1676f001bee410509d80 (patch)
treedcdd03f7fdedaf5c1ff5363415b68afe6ac57374
parentabbc30436d39dfed8ebfca338d253f211ac7b094 (diff)
ipv6: add option to drop unsolicited neighbor advertisements
In certain 802.11 wireless deployments, there will be NA proxies that use knowledge of the network to correctly answer requests. To prevent unsolicitd advertisements on the shared medium from being a problem, on such deployments wireless needs to drop them. Enable this by providing an option called "drop_unsolicited_na". Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/ip-sysctl.txt7
-rw-r--r--include/linux/ipv6.h1
-rw-r--r--include/uapi/linux/ipv6.h1
-rw-r--r--net/ipv6/addrconf.c8
-rw-r--r--net/ipv6/ndisc.c9
5 files changed, 26 insertions, 0 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index e0e7350a4e6a..24ce97f42d35 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1680,6 +1680,13 @@ drop_unicast_in_l2_multicast - BOOLEAN
1680 1680
1681 By default this is turned off. 1681 By default this is turned off.
1682 1682
1683drop_unsolicited_na - BOOLEAN
1684 Drop all unsolicited neighbor advertisements, for example if there's
1685 a known good NA proxy on the network and such frames need not be used
1686 (or in the case of 802.11, must not be used to prevent attacks.)
1687
1688 By default this is turned off.
1689
1683icmp/*: 1690icmp/*:
1684ratelimit - INTEGER 1691ratelimit - INTEGER
1685 Limit the maximal rates for sending ICMPv6 packets. 1692 Limit the maximal rates for sending ICMPv6 packets.
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 4a4c1ae826cb..4b2267e1b7c3 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -56,6 +56,7 @@ struct ipv6_devconf {
56 __s32 ndisc_notify; 56 __s32 ndisc_notify;
57 __s32 suppress_frag_ndisc; 57 __s32 suppress_frag_ndisc;
58 __s32 accept_ra_mtu; 58 __s32 accept_ra_mtu;
59 __s32 drop_unsolicited_na;
59 struct ipv6_stable_secret { 60 struct ipv6_stable_secret {
60 bool initialized; 61 bool initialized;
61 struct in6_addr secret; 62 struct in6_addr secret;
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 4c413570efe8..ec117b65d5a5 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -175,6 +175,7 @@ enum {
175 DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT, 175 DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
176 DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, 176 DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
177 DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, 177 DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
178 DEVCONF_DROP_UNSOLICITED_NA,
178 DEVCONF_MAX 179 DEVCONF_MAX
179}; 180};
180 181
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 23e325f39f8e..ac0ba9e4e06b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4712,6 +4712,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
4712 /* we omit DEVCONF_STABLE_SECRET for now */ 4712 /* we omit DEVCONF_STABLE_SECRET for now */
4713 array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only; 4713 array[DEVCONF_USE_OIF_ADDRS_ONLY] = cnf->use_oif_addrs_only;
4714 array[DEVCONF_DROP_UNICAST_IN_L2_MULTICAST] = cnf->drop_unicast_in_l2_multicast; 4714 array[DEVCONF_DROP_UNICAST_IN_L2_MULTICAST] = cnf->drop_unicast_in_l2_multicast;
4715 array[DEVCONF_DROP_UNSOLICITED_NA] = cnf->drop_unsolicited_na;
4715} 4716}
4716 4717
4717static inline size_t inet6_ifla6_size(void) 4718static inline size_t inet6_ifla6_size(void)
@@ -5793,6 +5794,13 @@ static struct addrconf_sysctl_table
5793 .proc_handler = proc_dointvec, 5794 .proc_handler = proc_dointvec,
5794 }, 5795 },
5795 { 5796 {
5797 .procname = "drop_unsolicited_na",
5798 .data = &ipv6_devconf.drop_unsolicited_na,
5799 .maxlen = sizeof(int),
5800 .mode = 0644,
5801 .proc_handler = proc_dointvec,
5802 },
5803 {
5796 /* sentinel */ 5804 /* sentinel */
5797 } 5805 }
5798 }, 5806 },
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 84afb9a77278..c245895a3d41 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -883,6 +883,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
883 offsetof(struct nd_msg, opt)); 883 offsetof(struct nd_msg, opt));
884 struct ndisc_options ndopts; 884 struct ndisc_options ndopts;
885 struct net_device *dev = skb->dev; 885 struct net_device *dev = skb->dev;
886 struct inet6_dev *idev = __in6_dev_get(dev);
886 struct inet6_ifaddr *ifp; 887 struct inet6_ifaddr *ifp;
887 struct neighbour *neigh; 888 struct neighbour *neigh;
888 889
@@ -902,6 +903,14 @@ static void ndisc_recv_na(struct sk_buff *skb)
902 return; 903 return;
903 } 904 }
904 905
906 /* For some 802.11 wireless deployments (and possibly other networks),
907 * there will be a NA proxy and unsolicitd packets are attacks
908 * and thus should not be accepted.
909 */
910 if (!msg->icmph.icmp6_solicited && idev &&
911 idev->cnf.drop_unsolicited_na)
912 return;
913
905 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { 914 if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) {
906 ND_PRINTK(2, warn, "NS: invalid ND option\n"); 915 ND_PRINTK(2, warn, "NS: invalid ND option\n");
907 return; 916 return;