Commit 6f7e7e9e authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[AH6]: Get things working again.

Re: [AH6] Disable mutable bits after AH header

Unfortunately I broke ah6_input() in that patch.  Thanks to Miyazawa-san
for notifying me of the problem.

In that patch I removed the nh_offset parameter to ipv6_clear_mutable_options.
That broke ah6_input() because it relies on that variable to set the nexthdr.

The following patch fixes this by moving this work out to the caller
xfrm6_rcv() where the information is already available.  It also removes
an unnecessary call to ip6_find_1stfragopt() in xfrm6_rcv() since nhoffp
already points to the nexthdr preceding the current header.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 5c4aa6af
...@@ -246,9 +246,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -246,9 +246,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
unsigned char *tmp_hdr = NULL; unsigned char *tmp_hdr = NULL;
u16 hdr_len; u16 hdr_len;
u16 ah_hlen; u16 ah_hlen;
u16 nh_offset = 0; int nexthdr;
u8 nexthdr = 0;
u8 *prevhdr;
if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
goto out; goto out;
...@@ -301,8 +299,6 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu ...@@ -301,8 +299,6 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
skb->nh.raw = skb_pull(skb, ah_hlen); skb->nh.raw = skb_pull(skb, ah_hlen);
memcpy(skb->nh.raw, tmp_hdr, hdr_len); memcpy(skb->nh.raw, tmp_hdr, hdr_len);
prevhdr = (u8*)(skb->nh.raw + nh_offset);
*prevhdr = nexthdr;
skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_pull(skb, hdr_len); skb_pull(skb, hdr_len);
skb->h.raw = skb->data; skb->h.raw = skb->data;
......
...@@ -258,7 +258,6 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b ...@@ -258,7 +258,6 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
u8 nexthdr[2]; u8 nexthdr[2];
struct scatterlist *sg = &esp->sgbuf[0]; struct scatterlist *sg = &esp->sgbuf[0];
u8 padlen; u8 padlen;
u8 *prevhdr;
if (unlikely(nfrags > ESP_NUM_FAST_SG)) { if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
...@@ -289,8 +288,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b ...@@ -289,8 +288,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
memcpy(skb->nh.raw, tmp_hdr, hdr_len); memcpy(skb->nh.raw, tmp_hdr, hdr_len);
skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
ip6_find_1stfragopt(skb, &prevhdr); ret = nexthdr[1];
ret = *prevhdr = nexthdr[1];
} }
out: out:
......
...@@ -49,7 +49,6 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s ...@@ -49,7 +49,6 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s
{ {
int err = 0; int err = 0;
u8 nexthdr = 0; u8 nexthdr = 0;
u8 *prevhdr;
int hdr_len = skb->h.raw - skb->nh.raw; int hdr_len = skb->h.raw - skb->nh.raw;
unsigned char *tmp_hdr = NULL; unsigned char *tmp_hdr = NULL;
struct ipv6hdr *iph; struct ipv6hdr *iph;
...@@ -106,8 +105,6 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s ...@@ -106,8 +105,6 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s
iph = skb->nh.ipv6h; iph = skb->nh.ipv6h;
iph->payload_len = htons(skb->len); iph->payload_len = htons(skb->len);
ip6_find_1stfragopt(skb, &prevhdr);
*prevhdr = nexthdr;
out: out:
if (tmp_hdr) if (tmp_hdr)
kfree(tmp_hdr); kfree(tmp_hdr);
......
...@@ -34,12 +34,11 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) ...@@ -34,12 +34,11 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
struct xfrm_state *x; struct xfrm_state *x;
int xfrm_nr = 0; int xfrm_nr = 0;
int decaps = 0; int decaps = 0;
int nexthdr = 0; int nexthdr;
u8 *prevhdr = NULL; unsigned int nhoff;
ip6_find_1stfragopt(skb, &prevhdr); nhoff = *nhoffp;
nexthdr = *prevhdr; nexthdr = skb->nh.raw[nhoff];
*nhoffp = prevhdr - skb->nh.raw;
if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
goto drop; goto drop;
...@@ -67,6 +66,8 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) ...@@ -67,6 +66,8 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
if (nexthdr <= 0) if (nexthdr <= 0)
goto drop_unlock; goto drop_unlock;
skb->nh.raw[nhoff] = nexthdr;
if (x->props.replay_window) if (x->props.replay_window)
xfrm_replay_advance(x, seq); xfrm_replay_advance(x, seq);
......
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