diff options
Diffstat (limited to 'net/ipv4/ip_options.c')
| -rw-r--r-- | net/ipv4/ip_options.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 94bf105ef3c9..ba9836c488ed 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/slab.h> | ||
| 14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
| 15 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
| 16 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
| @@ -237,7 +238,6 @@ void ip_options_fragment(struct sk_buff * skb) | |||
| 237 | opt->rr_needaddr = 0; | 238 | opt->rr_needaddr = 0; |
| 238 | opt->ts_needaddr = 0; | 239 | opt->ts_needaddr = 0; |
| 239 | opt->ts_needtime = 0; | 240 | opt->ts_needtime = 0; |
| 240 | return; | ||
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | /* | 243 | /* |
| @@ -600,6 +600,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
| 600 | unsigned char *optptr = skb_network_header(skb) + opt->srr; | 600 | unsigned char *optptr = skb_network_header(skb) + opt->srr; |
| 601 | struct rtable *rt = skb_rtable(skb); | 601 | struct rtable *rt = skb_rtable(skb); |
| 602 | struct rtable *rt2; | 602 | struct rtable *rt2; |
| 603 | unsigned long orefdst; | ||
| 603 | int err; | 604 | int err; |
| 604 | 605 | ||
| 605 | if (!opt->srr) | 606 | if (!opt->srr) |
| @@ -623,16 +624,16 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
| 623 | } | 624 | } |
| 624 | memcpy(&nexthop, &optptr[srrptr-1], 4); | 625 | memcpy(&nexthop, &optptr[srrptr-1], 4); |
| 625 | 626 | ||
| 626 | rt = skb_rtable(skb); | 627 | orefdst = skb->_skb_refdst; |
| 627 | skb_dst_set(skb, NULL); | 628 | skb_dst_set(skb, NULL); |
| 628 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); | 629 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); |
| 629 | rt2 = skb_rtable(skb); | 630 | rt2 = skb_rtable(skb); |
| 630 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { | 631 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { |
| 631 | ip_rt_put(rt2); | 632 | skb_dst_drop(skb); |
| 632 | skb_dst_set(skb, &rt->u.dst); | 633 | skb->_skb_refdst = orefdst; |
| 633 | return -EINVAL; | 634 | return -EINVAL; |
| 634 | } | 635 | } |
| 635 | ip_rt_put(rt); | 636 | refdst_drop(orefdst); |
| 636 | if (rt2->rt_type != RTN_LOCAL) | 637 | if (rt2->rt_type != RTN_LOCAL) |
| 637 | break; | 638 | break; |
| 638 | /* Superfast 8) loopback forward */ | 639 | /* Superfast 8) loopback forward */ |
