aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/icmp.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-06-28 06:59:11 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-28 06:59:11 -0400
commit35ebf65e851c6d9731abc6362b189858eb59f4d3 (patch)
tree2e78c2c81bc72aeeb172484996cdff268f0111a2 /net/ipv4/icmp.c
parent70e7341673a47fb1525cfc7d6651cc98b5348928 (diff)
ipv4: Create and use fib_compute_spec_dst() helper.
The specific destination is the host we direct unicast replies to. Usually this is the original packet source address, but if we are responding to a multicast or broadcast packet we have to use something different. Specifically we must use the source address we would use if we were to send a packet to the unicast source of the original packet. The routing cache precomputes this value, but we want to remove that precomputation because it creates a hard dependency on the expensive rpfilter source address validation which we'd like to make cheaper. There are only three places where this matters: 1) ICMP replies. 2) pktinfo CMSG 3) IP options Now there will be no real users of rt->rt_spec_dst and we can simply remove it altogether. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r--net/ipv4/icmp.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 49a74cc79dc8..4bce5a2830aa 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -95,6 +95,7 @@
95#include <net/checksum.h> 95#include <net/checksum.h>
96#include <net/xfrm.h> 96#include <net/xfrm.h>
97#include <net/inet_common.h> 97#include <net/inet_common.h>
98#include <net/ip_fib.h>
98 99
99/* 100/*
100 * Build xmit assembly blocks 101 * Build xmit assembly blocks
@@ -333,7 +334,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
333 struct flowi4 fl4; 334 struct flowi4 fl4;
334 struct sock *sk; 335 struct sock *sk;
335 struct inet_sock *inet; 336 struct inet_sock *inet;
336 __be32 daddr; 337 __be32 daddr, saddr;
337 338
338 if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb)) 339 if (ip_options_echo(&icmp_param->replyopts.opt.opt, skb))
339 return; 340 return;
@@ -347,6 +348,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
347 348
348 inet->tos = ip_hdr(skb)->tos; 349 inet->tos = ip_hdr(skb)->tos;
349 daddr = ipc.addr = ip_hdr(skb)->saddr; 350 daddr = ipc.addr = ip_hdr(skb)->saddr;
351 saddr = fib_compute_spec_dst(skb);
350 ipc.opt = NULL; 352 ipc.opt = NULL;
351 ipc.tx_flags = 0; 353 ipc.tx_flags = 0;
352 if (icmp_param->replyopts.opt.opt.optlen) { 354 if (icmp_param->replyopts.opt.opt.optlen) {
@@ -356,7 +358,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
356 } 358 }
357 memset(&fl4, 0, sizeof(fl4)); 359 memset(&fl4, 0, sizeof(fl4));
358 fl4.daddr = daddr; 360 fl4.daddr = daddr;
359 fl4.saddr = rt->rt_spec_dst; 361 fl4.saddr = saddr;
360 fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); 362 fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
361 fl4.flowi4_proto = IPPROTO_ICMP; 363 fl4.flowi4_proto = IPPROTO_ICMP;
362 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); 364 security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));