diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index ebe94f2cab98..99838259e2e6 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -884,8 +884,8 @@ icmp_ignore_bogus_error_responses - BOOLEAN icmp_errors_use_inbound_ifaddr - BOOLEAN - If zero, icmp error messages are sent with the primary address of - the exiting interface. + If zero, icmp error messages except redirects are sent with the primary + address of the exiting interface. If non-zero, the message will be sent with the primary address of the interface that received the packet that caused the icmp error. @@ -897,8 +897,23 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN then the primary address of the first non-loopback interface that has one will be used regardless of this setting. + The source address selection of icmp redirect messages is controlled by + icmp_errors_use_inbound_ifaddr. Default: 0 +icmp_redirects_use_orig_daddr - BOOLEAN + + If zero, icmp redirect messages are sent using the address specified for + other icmp errors by icmp_errors_use_inbound_ifaddr. + + If non-zero, the message will be sent with the destination address of + the packet that caused the icmp redirect. + This behaviour is the preferred one on VRRP routers (see RFC 5798 + section 8.1.1). + + Default: 0 + + igmp_max_memberships - INTEGER Change the maximum number of multicast groups we can subscribe to. Default: 20 diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index c68926b4899c..46d336abca92 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -74,6 +74,7 @@ struct netns_ipv4 { int sysctl_icmp_ratelimit; int sysctl_icmp_ratemask; int sysctl_icmp_errors_use_inbound_ifaddr; + int sysctl_icmp_redirects_use_orig_daddr; struct local_ports ip_local_ports; 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 @@ -817,6 +817,13 @@ static struct ctl_table ipv4_net_table[] = { .mode = 0644, .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,