summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2015-10-09 14:34:31 +0200
committerDavid S. Miller <davem@davemloft.net>2015-10-12 19:38:02 -0700
commite2ca690b657f4ca5c204fcc6470d462b776d73b3 (patch)
treebad7ed1b3899da4affa41704c52c27e0a8a616c0 /net/ipv4
parent0944d6b5a2fad9ba3b7abb2e94a6b7d40cd4a935 (diff)
downloadlinux-stable-e2ca690b657f4ca5c204fcc6470d462b776d73b3.tar.gz
linux-stable-e2ca690b657f4ca5c204fcc6470d462b776d73b3.tar.bz2
linux-stable-e2ca690b657f4ca5c204fcc6470d462b776d73b3.zip
ipv4/icmp: redirect messages can use the ingress daddr as source
This patch allows configuring how the source address of ICMP redirect messages is selected; by default the old behaviour is retained, while setting icmp_redirects_use_orig_daddr force the usage of the destination address of the packet that caused the redirect. The new behaviour fits closely the RFC 5798 section 8.1.1, and fix the following scenario: Two machines are set up with VRRP to act as routers out of a subnet, they have IPs x.x.x.1/24 and x.x.x.2/24, with VRRP holding on to x.x.x.254/24. If a host in said subnet needs to get an ICMP redirect from the VRRP router, i.e. to reach a destination behind a different gateway, the source IP in the ICMP redirect is chosen as the primary IP on the interface that the packet arrived at, i.e. x.x.x.1 or x.x.x.2. The host will then ignore said redirect, due to RFC 1122 section 3.2.2.2, and will continue to use the wrong next-op. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/icmp.c9
-rw-r--r--net/ipv4/sysctl_net_ipv4.c7
2 files changed, 15 insertions, 1 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 36e26977c908..f3c356b7c1f0 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -659,7 +659,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
*/
saddr = iph->daddr;
- if (!(rt->rt_flags & RTCF_LOCAL)) {
+ if (!((type == ICMP_REDIRECT) &&
+ net->ipv4.sysctl_icmp_redirects_use_orig_daddr) &&
+ !(rt->rt_flags & RTCF_LOCAL)) {
struct net_device *dev = NULL;
rcu_read_lock();
@@ -1222,6 +1224,11 @@ static int __net_init icmp_sk_init(struct net *net)
net->ipv4.sysctl_icmp_ratemask = 0x1818;
net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr = 0;
+ /* Control paramerer - use the daddr of originating packets as saddr
+ * in redirect messages?
+ */
+ net->ipv4.sysctl_icmp_redirects_use_orig_daddr = 0;
+
return 0;
fail:
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 894da3a70aff..30a531ccbf77 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -818,6 +818,13 @@ static struct ctl_table ipv4_net_table[] = {
.proc_handler = proc_dointvec
},
{
+ .procname = "icmp_redirects_use_orig_daddr",
+ .data = &init_net.ipv4.sysctl_icmp_redirects_use_orig_daddr,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
+ {
.procname = "icmp_ratelimit",
.data = &init_net.ipv4.sysctl_icmp_ratelimit,
.maxlen = sizeof(int),