diff mbox

Configure ICMP error source address

Message ID 5692AD09.80406@heinlein-support.de
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Robert Sander Jan. 10, 2016, 7:12 p.m. UTC
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):



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
diff mbox

Patch

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;