Subject: Re: Configure ICMP error source address

From: Robert Sander <[email-masked]>
Date: Sun, 10 Jan 2016 20:12:09 +0100

Am 10.01.2016 um 00:01 schrieb Hannes Frederic Sowa:

> I am not a fan of such implicit assumptions. I would prefer the direct
> specification of the source ip address over writing interface
> information to a procfs file.

I tried that but as I am not a seasoned kernel hacker introducing a new
sysctl including the validation of an IPv4 address was a bit too much.

Instead I created this patch (applicable against kernel version 3.2):

diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index ab188ae..eba2071 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -567,7 +567,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 
                rcu_read_lock();
                if (rt_is_input_route(rt) &&
-                   net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr)
+                   net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr == 1)
                        dev = dev_get_by_index_rcu(net, rt->rt_iif);
 
                if (dev)
@@ -577,6 +577,23 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                rcu_read_unlock();
        }
 
+       /*
+        *      Set source in case of error reply
+        */
+
+       if (icmp_pointers[type].error && net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr == 2) {
+               struct net_device *dev = NULL;
+               __be32 tmpaddr = 0;
+
+               rcu_read_lock();
+               dev = dev_get_by_name_rcu(net, "lo");
+               if (dev)
+                       tmpaddr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
+                       if (tmpaddr)
+                               saddr = tmpaddr;
+               rcu_read_unlock();
+       }
+
        tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
                                           IPTOS_PREC_INTERNETCONTROL) :
                                          iph->tos;

It currently works in my testbed (Debian wheezy based, therefor kernel 3.2).

Maybe there is someone more experienced with introducing new sysctl
files and handling strings in kernel space than me that is able to
pick up this idea and implement it properly.

Regards
-- 
Robert Sander
Heinlein Support GmbH
Schwedter Str. 8/9b, 10119 Berlin

http://www.heinlein-support.de

Tel: 030 / 405051-43
Fax: 030 / 405051-19

Zwangsangaben lt. §35a GmbHG: 
HRB 93818 B / Amtsgericht Berlin-Charlottenburg,
Geschäftsführer: Peer Heinlein -- Sitz: Berlin