aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c6
-rw-r--r--net/ipv4/xfrm4_mode_beet.c26
-rw-r--r--net/ipv6/route.c19
3 files changed, 24 insertions, 27 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 0acee9f324e9..256969e1300c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4834,8 +4834,10 @@ static int tg3_chip_reset(struct tg3 *tp)
4834 * sharing or irqpoll. 4834 * sharing or irqpoll.
4835 */ 4835 */
4836 tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; 4836 tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
4837 tp->hw_status->status = 0; 4837 if (tp->hw_status) {
4838 tp->hw_status->status_tag = 0; 4838 tp->hw_status->status = 0;
4839 tp->hw_status->status_tag = 0;
4840 }
4839 tp->last_tag = 0; 4841 tp->last_tag = 0;
4840 smp_mb(); 4842 smp_mb();
4841 synchronize_irq(tp->pdev->irq); 4843 synchronize_irq(tp->pdev->irq);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 89cf59ea7bbe..f68dfd8a0f5c 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -42,10 +42,9 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
42 42
43 skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen); 43 skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen);
44 top_iph = skb->nh.iph; 44 top_iph = skb->nh.iph;
45 hdrlen = iph->ihl * 4 - optlen; 45 skb->h.raw += sizeof(*iph) - hdrlen;
46 skb->h.raw += hdrlen;
47 46
48 memmove(top_iph, iph, hdrlen); 47 memmove(top_iph, iph, sizeof(*iph));
49 if (unlikely(optlen)) { 48 if (unlikely(optlen)) {
50 struct ip_beet_phdr *ph; 49 struct ip_beet_phdr *ph;
51 50
@@ -55,6 +54,8 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
55 ph->padlen = 4 - (optlen & 4); 54 ph->padlen = 4 - (optlen & 4);
56 ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8; 55 ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
57 ph->nexthdr = top_iph->protocol; 56 ph->nexthdr = top_iph->protocol;
57 if (ph->padlen)
58 memset(ph + 1, IPOPT_NOP, ph->padlen);
58 59
59 top_iph->protocol = IPPROTO_BEETPH; 60 top_iph->protocol = IPPROTO_BEETPH;
60 top_iph->ihl = sizeof(struct iphdr) / 4; 61 top_iph->ihl = sizeof(struct iphdr) / 4;
@@ -77,29 +78,32 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
77 protocol = iph->protocol; 78 protocol = iph->protocol;
78 79
79 if (unlikely(iph->protocol == IPPROTO_BEETPH)) { 80 if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
80 struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1); 81 struct ip_beet_phdr *ph;
81 82
82 if (!pskb_may_pull(skb, sizeof(*ph))) 83 if (!pskb_may_pull(skb, sizeof(*ph)))
83 goto out; 84 goto out;
85 ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1);
84 86
85 phlen = ph->hdrlen * 8; 87 phlen = sizeof(*ph) + ph->padlen;
86 optlen = phlen - ph->padlen - sizeof(*ph); 88 optlen = ph->hdrlen * 8 - phlen;
87 if (optlen < 0 || optlen & 3 || optlen > 250) 89 if (optlen < 0 || optlen & 3 || optlen > 250)
88 goto out; 90 goto out;
89 91
90 if (!pskb_may_pull(skb, phlen)) 92 if (!pskb_may_pull(skb, phlen + optlen))
91 goto out; 93 goto out;
94 skb->len -= phlen + optlen;
92 95
93 ph_nexthdr = ph->nexthdr; 96 ph_nexthdr = ph->nexthdr;
94 } 97 }
95 98
96 skb_push(skb, sizeof(*iph) - phlen + optlen); 99 skb->nh.raw = skb->data + (phlen - sizeof(*iph));
97 memmove(skb->data, skb->nh.raw, sizeof(*iph)); 100 memmove(skb->nh.raw, iph, sizeof(*iph));
98 skb->nh.raw = skb->data; 101 skb->h.raw = skb->data + (phlen + optlen);
102 skb->data = skb->h.raw;
99 103
100 iph = skb->nh.iph; 104 iph = skb->nh.iph;
101 iph->ihl = (sizeof(*iph) + optlen) / 4; 105 iph->ihl = (sizeof(*iph) + optlen) / 4;
102 iph->tot_len = htons(skb->len); 106 iph->tot_len = htons(skb->len + iph->ihl * 4);
103 iph->daddr = x->sel.daddr.a4; 107 iph->daddr = x->sel.daddr.a4;
104 iph->saddr = x->sel.saddr.a4; 108 iph->saddr = x->sel.saddr.a4;
105 if (ph_nexthdr) 109 if (ph_nexthdr)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 3931b33b25e8..ad9b285692ba 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -311,21 +311,12 @@ static inline void rt6_probe(struct rt6_info *rt)
311static inline int rt6_check_dev(struct rt6_info *rt, int oif) 311static inline int rt6_check_dev(struct rt6_info *rt, int oif)
312{ 312{
313 struct net_device *dev = rt->rt6i_dev; 313 struct net_device *dev = rt->rt6i_dev;
314 int ret = 0; 314 if (!oif || dev->ifindex == oif)
315
316 if (!oif)
317 return 2;
318 if (dev->flags & IFF_LOOPBACK) {
319 if (!WARN_ON(rt->rt6i_idev == NULL) &&
320 rt->rt6i_idev->dev->ifindex == oif)
321 ret = 1;
322 else
323 return 0;
324 }
325 if (dev->ifindex == oif)
326 return 2; 315 return 2;
327 316 if ((dev->flags & IFF_LOOPBACK) &&
328 return ret; 317 rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif)
318 return 1;
319 return 0;
329} 320}
330 321
331static inline int rt6_check_neigh(struct rt6_info *rt) 322static inline int rt6_check_neigh(struct rt6_info *rt)