Commit bbef6181 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [TG3]: Fix crash during tg3_init_one().
  [IPV6]: Revert recent change to rt6_check_dev().
  [XFRM]: beet: fix IP option decapsulation
  [XFRM]: beet: fix beet mode decapsulation
  [XFRM]: beet: use IPOPT_NOP for option padding
  [XFRM]: beet: fix IP option encapsulation
parents a21bd69e b8fa2f3a
...@@ -4834,8 +4834,10 @@ static int tg3_chip_reset(struct tg3 *tp) ...@@ -4834,8 +4834,10 @@ static int tg3_chip_reset(struct tg3 *tp)
* sharing or irqpoll. * sharing or irqpoll.
*/ */
tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
tp->hw_status->status = 0; if (tp->hw_status) {
tp->hw_status->status_tag = 0; tp->hw_status->status = 0;
tp->hw_status->status_tag = 0;
}
tp->last_tag = 0; tp->last_tag = 0;
smp_mb(); smp_mb();
synchronize_irq(tp->pdev->irq); synchronize_irq(tp->pdev->irq);
......
...@@ -42,10 +42,9 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -42,10 +42,9 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen); skb->nh.raw = skb_push(skb, x->props.header_len + hdrlen);
top_iph = skb->nh.iph; top_iph = skb->nh.iph;
hdrlen = iph->ihl * 4 - optlen; skb->h.raw += sizeof(*iph) - hdrlen;
skb->h.raw += hdrlen;
memmove(top_iph, iph, hdrlen); memmove(top_iph, iph, sizeof(*iph));
if (unlikely(optlen)) { if (unlikely(optlen)) {
struct ip_beet_phdr *ph; struct ip_beet_phdr *ph;
...@@ -55,6 +54,8 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -55,6 +54,8 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
ph->padlen = 4 - (optlen & 4); ph->padlen = 4 - (optlen & 4);
ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8; ph->hdrlen = (optlen + ph->padlen + sizeof(*ph)) / 8;
ph->nexthdr = top_iph->protocol; ph->nexthdr = top_iph->protocol;
if (ph->padlen)
memset(ph + 1, IPOPT_NOP, ph->padlen);
top_iph->protocol = IPPROTO_BEETPH; top_iph->protocol = IPPROTO_BEETPH;
top_iph->ihl = sizeof(struct iphdr) / 4; 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,29 +78,32 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
protocol = iph->protocol; protocol = iph->protocol;
if (unlikely(iph->protocol == IPPROTO_BEETPH)) { if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(iph + 1); struct ip_beet_phdr *ph;
if (!pskb_may_pull(skb, sizeof(*ph))) if (!pskb_may_pull(skb, sizeof(*ph)))
goto out; goto out;
ph = (struct ip_beet_phdr *)(skb->h.ipiph + 1);
phlen = ph->hdrlen * 8; phlen = sizeof(*ph) + ph->padlen;
optlen = phlen - ph->padlen - sizeof(*ph); optlen = ph->hdrlen * 8 - phlen;
if (optlen < 0 || optlen & 3 || optlen > 250) if (optlen < 0 || optlen & 3 || optlen > 250)
goto out; goto out;
if (!pskb_may_pull(skb, phlen)) if (!pskb_may_pull(skb, phlen + optlen))
goto out; goto out;
skb->len -= phlen + optlen;
ph_nexthdr = ph->nexthdr; ph_nexthdr = ph->nexthdr;
} }
skb_push(skb, sizeof(*iph) - phlen + optlen); skb->nh.raw = skb->data + (phlen - sizeof(*iph));
memmove(skb->data, skb->nh.raw, sizeof(*iph)); memmove(skb->nh.raw, iph, sizeof(*iph));
skb->nh.raw = skb->data; skb->h.raw = skb->data + (phlen + optlen);
skb->data = skb->h.raw;
iph = skb->nh.iph; iph = skb->nh.iph;
iph->ihl = (sizeof(*iph) + optlen) / 4; iph->ihl = (sizeof(*iph) + optlen) / 4;
iph->tot_len = htons(skb->len); iph->tot_len = htons(skb->len + iph->ihl * 4);
iph->daddr = x->sel.daddr.a4; iph->daddr = x->sel.daddr.a4;
iph->saddr = x->sel.saddr.a4; iph->saddr = x->sel.saddr.a4;
if (ph_nexthdr) if (ph_nexthdr)
......
...@@ -311,21 +311,12 @@ static inline void rt6_probe(struct rt6_info *rt) ...@@ -311,21 +311,12 @@ static inline void rt6_probe(struct rt6_info *rt)
static inline int rt6_check_dev(struct rt6_info *rt, int oif) static inline int rt6_check_dev(struct rt6_info *rt, int oif)
{ {
struct net_device *dev = rt->rt6i_dev; struct net_device *dev = rt->rt6i_dev;
int ret = 0; if (!oif || dev->ifindex == oif)
if (!oif)
return 2;
if (dev->flags & IFF_LOOPBACK) {
if (!WARN_ON(rt->rt6i_idev == NULL) &&
rt->rt6i_idev->dev->ifindex == oif)
ret = 1;
else
return 0;
}
if (dev->ifindex == oif)
return 2; return 2;
if ((dev->flags & IFF_LOOPBACK) &&
return ret; rt->rt6i_idev && rt->rt6i_idev->dev->ifindex == oif)
return 1;
return 0;
} }
static inline int rt6_check_neigh(struct rt6_info *rt) static inline int rt6_check_neigh(struct rt6_info *rt)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment