diff options
author | David S. Miller <davem@davemloft.net> | 2012-06-28 06:59:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-28 06:59:11 -0400 |
commit | 35ebf65e851c6d9731abc6362b189858eb59f4d3 (patch) | |
tree | 2e78c2c81bc72aeeb172484996cdff268f0111a2 /net/ipv4/icmp.c | |
parent | 70e7341673a47fb1525cfc7d6651cc98b5348928 (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.c | 6 |
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)); |