aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_options.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/ip_options.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/ip_options.c')
-rw-r--r--net/ipv4/ip_options.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 708b99494e23..766dfe56885a 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -27,6 +27,7 @@
27#include <net/icmp.h> 27#include <net/icmp.h>
28#include <net/route.h> 28#include <net/route.h>
29#include <net/cipso_ipv4.h> 29#include <net/cipso_ipv4.h>
30#include <net/ip_fib.h>
30 31
31/* 32/*
32 * Write options to IP header, record destination address to 33 * Write options to IP header, record destination address to
@@ -104,7 +105,7 @@ int ip_options_echo(struct ip_options *dopt, struct sk_buff *skb)
104 sptr = skb_network_header(skb); 105 sptr = skb_network_header(skb);
105 dptr = dopt->__data; 106 dptr = dopt->__data;
106 107
107 daddr = skb_rtable(skb)->rt_spec_dst; 108 daddr = fib_compute_spec_dst(skb);
108 109
109 if (sopt->rr) { 110 if (sopt->rr) {
110 optlen = sptr[sopt->rr+1]; 111 optlen = sptr[sopt->rr+1];
@@ -250,15 +251,14 @@ void ip_options_fragment(struct sk_buff *skb)
250int ip_options_compile(struct net *net, 251int ip_options_compile(struct net *net,
251 struct ip_options *opt, struct sk_buff *skb) 252 struct ip_options *opt, struct sk_buff *skb)
252{ 253{
253 int l; 254 __be32 spec_dst = (__force __be32) 0;
254 unsigned char *iph;
255 unsigned char *optptr;
256 int optlen;
257 unsigned char *pp_ptr = NULL; 255 unsigned char *pp_ptr = NULL;
258 struct rtable *rt = NULL; 256 unsigned char *optptr;
257 unsigned char *iph;
258 int optlen, l;
259 259
260 if (skb != NULL) { 260 if (skb != NULL) {
261 rt = skb_rtable(skb); 261 spec_dst = fib_compute_spec_dst(skb);
262 optptr = (unsigned char *)&(ip_hdr(skb)[1]); 262 optptr = (unsigned char *)&(ip_hdr(skb)[1]);
263 } else 263 } else
264 optptr = opt->__data; 264 optptr = opt->__data;
@@ -330,8 +330,8 @@ int ip_options_compile(struct net *net,
330 pp_ptr = optptr + 2; 330 pp_ptr = optptr + 2;
331 goto error; 331 goto error;
332 } 332 }
333 if (rt) { 333 if (skb) {
334 memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); 334 memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
335 opt->is_changed = 1; 335 opt->is_changed = 1;
336 } 336 }
337 optptr[2] += 4; 337 optptr[2] += 4;
@@ -372,8 +372,8 @@ int ip_options_compile(struct net *net,
372 goto error; 372 goto error;
373 } 373 }
374 opt->ts = optptr - iph; 374 opt->ts = optptr - iph;
375 if (rt) { 375 if (skb) {
376 memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); 376 memcpy(&optptr[optptr[2]-1], &spec_dst, 4);
377 timeptr = &optptr[optptr[2]+3]; 377 timeptr = &optptr[optptr[2]+3];
378 } 378 }
379 opt->ts_needaddr = 1; 379 opt->ts_needaddr = 1;