From 6f7e7e9e21979e675c5e623a9217a38fbd8b6049 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 27 Jul 2004 19:01:51 -0700 Subject: [PATCH] [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: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/ah6.c | 6 +----- net/ipv6/esp6.c | 4 +--- net/ipv6/ipcomp6.c | 3 --- net/ipv6/xfrm6_input.c | 11 ++++++----- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index e57cb8ba76110..ca1e0fb576acb 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -246,9 +246,7 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu unsigned char *tmp_hdr = NULL; u16 hdr_len; u16 ah_hlen; - u16 nh_offset = 0; - u8 nexthdr = 0; - u8 *prevhdr; + int nexthdr; if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr))) goto out; @@ -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); 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_pull(skb, hdr_len); skb->h.raw = skb->data; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 8682cf13402a0..0763c9fc50bb7 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -258,7 +258,6 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b u8 nexthdr[2]; struct scatterlist *sg = &esp->sgbuf[0]; u8 padlen; - u8 *prevhdr; if (unlikely(nfrags > ESP_NUM_FAST_SG)) { 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 skb->nh.raw += sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; memcpy(skb->nh.raw, tmp_hdr, hdr_len); skb->nh.ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); - ip6_find_1stfragopt(skb, &prevhdr); - ret = *prevhdr = nexthdr[1]; + ret = nexthdr[1]; } out: diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index c6307aa54f916..9f2dfa1607c4d 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -49,7 +49,6 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s { int err = 0; u8 nexthdr = 0; - u8 *prevhdr; int hdr_len = skb->h.raw - skb->nh.raw; unsigned char *tmp_hdr = NULL; struct ipv6hdr *iph; @@ -106,8 +105,6 @@ static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, s iph = skb->nh.ipv6h; iph->payload_len = htons(skb->len); - ip6_find_1stfragopt(skb, &prevhdr); - *prevhdr = nexthdr; out: if (tmp_hdr) kfree(tmp_hdr); diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index c679a3ce4e165..0791594f8878a 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -34,12 +34,11 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) struct xfrm_state *x; int xfrm_nr = 0; int decaps = 0; - int nexthdr = 0; - u8 *prevhdr = NULL; + int nexthdr; + unsigned int nhoff; - ip6_find_1stfragopt(skb, &prevhdr); - nexthdr = *prevhdr; - *nhoffp = prevhdr - skb->nh.raw; + nhoff = *nhoffp; + nexthdr = skb->nh.raw[nhoff]; if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) goto drop; @@ -67,6 +66,8 @@ int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) if (nexthdr <= 0) goto drop_unlock; + skb->nh.raw[nhoff] = nexthdr; + if (x->props.replay_window) xfrm_replay_advance(x, seq); -- 2.53.0