ipv6: Add icmp_echo_ignore_all support for ICMPv6
authorVirgile Jarry <virgile@acceis.fr>
Fri, 10 Aug 2018 15:48:15 +0000 (17:48 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 13 Aug 2018 15:42:25 +0000 (08:42 -0700)
Preventing the kernel from responding to ICMP Echo Requests messages
can be useful in several ways. The sysctl parameter
'icmp_echo_ignore_all' can be used to prevent the kernel from
responding to IPv4 ICMP echo requests. For IPv6 pings, such
a sysctl kernel parameter did not exist.

Add the ability to prevent the kernel from responding to IPv6
ICMP echo requests through the use of the following sysctl
parameter : /proc/sys/net/ipv6/icmp/echo_ignore_all.
Update the documentation to reflect this change.

Signed-off-by: Virgile Jarry <virgile@acceis.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/ip-sysctl.txt
include/net/netns/ipv6.h
include/uapi/linux/sysctl.h
net/ipv6/af_inet6.c
net/ipv6/icmp.c

index e74515ecaa9c4b8f66e2fe1a59b584f340ffa718..8313a636dd533540172859653bcfa173c1e03864 100644 (file)
@@ -1882,6 +1882,11 @@ ratelimit - INTEGER
        otherwise the minimal space between responses in milliseconds.
        Default: 1000
 
+echo_ignore_all - BOOLEAN
+       If set non-zero, then the kernel will ignore all ICMP ECHO
+       requests sent to it over the IPv6 protocol.
+       Default: 0
+
 xfrm6_gc_thresh - INTEGER
        The threshold at which we will start garbage collecting for IPv6
        destination cache entries.  At twice this value the system will
index 762ac9931b6251152b6ee0e5780df0f7b073f3e6..f0e396ab9bec538b2cb6a19a61ff5b038585b4fb 100644 (file)
@@ -32,6 +32,7 @@ struct netns_sysctl_ipv6 {
        int flowlabel_consistency;
        int auto_flowlabels;
        int icmpv6_time;
+       int icmpv6_echo_ignore_all;
        int anycast_src_echo_reply;
        int ip_nonlocal_bind;
        int fwmark_reflect;
index 6b58371b1f0d5a1405328c5e4c43c15bc9588f9a..d71013fffaf65b520420a4d04d2347f450c2f598 100644 (file)
@@ -575,7 +575,8 @@ enum {
 
 /* /proc/sys/net/ipv6/icmp */
 enum {
-       NET_IPV6_ICMP_RATELIMIT=1
+       NET_IPV6_ICMP_RATELIMIT = 1,
+       NET_IPV6_ICMP_ECHO_IGNORE_ALL = 2
 };
 
 /* /proc/sys/net/<protocol>/neigh/<dev> */
index 020f6e14a7afe130e6b016fa8b55d230e6a04559..673bba31eb1807eb04ee0d0c072333000bde4305 100644 (file)
@@ -832,6 +832,7 @@ static int __net_init inet6_net_init(struct net *net)
 
        net->ipv6.sysctl.bindv6only = 0;
        net->ipv6.sysctl.icmpv6_time = 1*HZ;
+       net->ipv6.sysctl.icmpv6_echo_ignore_all = 0;
        net->ipv6.sysctl.flowlabel_consistency = 1;
        net->ipv6.sysctl.auto_flowlabels = IP6_DEFAULT_AUTO_FLOW_LABELS;
        net->ipv6.sysctl.idgen_retries = 3;
index 7f6b1f81c20074b09f32edcbb056b86c1ac22c0a..c9c53ade55c3cee53ffed639aed8eb0f3e5a0f76 100644 (file)
@@ -794,6 +794,7 @@ out:
 
 static int icmpv6_rcv(struct sk_buff *skb)
 {
+       struct net *net = dev_net(skb->dev);
        struct net_device *dev = skb->dev;
        struct inet6_dev *idev = __in6_dev_get(dev);
        const struct in6_addr *saddr, *daddr;
@@ -843,7 +844,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
 
        switch (type) {
        case ICMPV6_ECHO_REQUEST:
-               icmpv6_echo_reply(skb);
+               if (!net->ipv6.sysctl.icmpv6_echo_ignore_all)
+                       icmpv6_echo_reply(skb);
                break;
 
        case ICMPV6_ECHO_REPLY:
@@ -1104,6 +1106,13 @@ static struct ctl_table ipv6_icmp_table_template[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec_ms_jiffies,
        },
+       {
+               .procname       = "echo_ignore_all",
+               .data           = &init_net.ipv6.sysctl.icmpv6_echo_ignore_all,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler = proc_dointvec,
+       },
        { },
 };
 
@@ -1115,9 +1124,10 @@ struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net)
                        sizeof(ipv6_icmp_table_template),
                        GFP_KERNEL);
 
-       if (table)
+       if (table) {
                table[0].data = &net->ipv6.sysctl.icmpv6_time;
-
+               table[1].data = &net->ipv6.sysctl.icmpv6_echo_ignore_all;
+       }
        return table;
 }
 #endif