aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_options.c12
-rw-r--r--net/ipv4/route.c24
2 files changed, 20 insertions, 16 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index c6474cd1cbfa..89268baabc87 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39void ip_options_build(struct sk_buff *skb, struct ip_options *opt, 39void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
40 __be32 daddr, struct rtable *rt, int is_frag) 40 __be32 daddr, struct rtable *rt, int is_frag)
41{ 41{
42 unsigned char *iph = skb_network_header(skb); 42 unsigned char *iph = skb_network_header(skb);
43 43
@@ -50,9 +50,9 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
50 50
51 if (!is_frag) { 51 if (!is_frag) {
52 if (opt->rr_needaddr) 52 if (opt->rr_needaddr)
53 ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt); 53 ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, skb, rt);
54 if (opt->ts_needaddr) 54 if (opt->ts_needaddr)
55 ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt); 55 ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, skb, rt);
56 if (opt->ts_needtime) { 56 if (opt->ts_needtime) {
57 struct timespec tv; 57 struct timespec tv;
58 __be32 midtime; 58 __be32 midtime;
@@ -553,7 +553,7 @@ void ip_forward_options(struct sk_buff *skb)
553 553
554 if (opt->rr_needaddr) { 554 if (opt->rr_needaddr) {
555 optptr = (unsigned char *)raw + opt->rr; 555 optptr = (unsigned char *)raw + opt->rr;
556 ip_rt_get_source(&optptr[optptr[2]-5], rt); 556 ip_rt_get_source(&optptr[optptr[2]-5], skb, rt);
557 opt->is_changed = 1; 557 opt->is_changed = 1;
558 } 558 }
559 if (opt->srr_is_hit) { 559 if (opt->srr_is_hit) {
@@ -572,13 +572,13 @@ void ip_forward_options(struct sk_buff *skb)
572 } 572 }
573 if (srrptr + 3 <= srrspace) { 573 if (srrptr + 3 <= srrspace) {
574 opt->is_changed = 1; 574 opt->is_changed = 1;
575 ip_rt_get_source(&optptr[srrptr-1], rt); 575 ip_rt_get_source(&optptr[srrptr-1], skb, rt);
576 optptr[2] = srrptr+4; 576 optptr[2] = srrptr+4;
577 } else if (net_ratelimit()) 577 } else if (net_ratelimit())
578 printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n"); 578 printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
579 if (opt->ts_needaddr) { 579 if (opt->ts_needaddr) {
580 optptr = raw + opt->ts; 580 optptr = raw + opt->ts;
581 ip_rt_get_source(&optptr[optptr[2]-9], rt); 581 ip_rt_get_source(&optptr[optptr[2]-9], skb, rt);
582 opt->is_changed = 1; 582 opt->is_changed = 1;
583 } 583 }
584 } 584 }
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 6a83840b16af..ad141d894e4e 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1699,22 +1699,26 @@ static int ip_rt_bug(struct sk_buff *skb)
1699 in IP options! 1699 in IP options!
1700 */ 1700 */
1701 1701
1702void ip_rt_get_source(u8 *addr, struct rtable *rt) 1702void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
1703{ 1703{
1704 __be32 src; 1704 __be32 src;
1705 struct fib_result res;
1706 1705
1707 if (rt_is_output_route(rt)) 1706 if (rt_is_output_route(rt))
1708 src = rt->rt_src; 1707 src = rt->rt_src;
1709 else { 1708 else {
1710 struct flowi4 fl4 = { 1709 struct fib_result res;
1711 .daddr = rt->rt_key_dst, 1710 struct flowi4 fl4;
1712 .saddr = rt->rt_key_src, 1711 struct iphdr *iph;
1713 .flowi4_tos = rt->rt_key_tos, 1712
1714 .flowi4_oif = rt->rt_oif, 1713 iph = ip_hdr(skb);
1715 .flowi4_iif = rt->rt_iif, 1714
1716 .flowi4_mark = rt->rt_mark, 1715 memset(&fl4, 0, sizeof(fl4));
1717 }; 1716 fl4.daddr = iph->daddr;
1717 fl4.saddr = iph->saddr;
1718 fl4.flowi4_tos = iph->tos;
1719 fl4.flowi4_oif = rt->dst.dev->ifindex;
1720 fl4.flowi4_iif = skb->dev->ifindex;
1721 fl4.flowi4_mark = skb->mark;
1718 1722
1719 rcu_read_lock(); 1723 rcu_read_lock();
1720 if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0) 1724 if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)