Commit 631a6698 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Move IP protocol setting from transforms into xfrm4_input.c

This patch makes the IPv4 x->type->input functions return the next protocol
instead of setting it directly.  This is identical to how we do things in
IPv6 and will help us merge common code on the input path.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ceb1eec8
...@@ -125,6 +125,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -125,6 +125,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
int ah_hlen; int ah_hlen;
int ihl; int ihl;
int nexthdr;
int err = -EINVAL; int err = -EINVAL;
struct iphdr *iph; struct iphdr *iph;
struct ip_auth_hdr *ah; struct ip_auth_hdr *ah;
...@@ -136,6 +137,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -136,6 +137,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
ah = (struct ip_auth_hdr *)skb->data; ah = (struct ip_auth_hdr *)skb->data;
ahp = x->data; ahp = x->data;
nexthdr = ah->nexthdr;
ah_hlen = (ah->hdrlen + 2) << 2; ah_hlen = (ah->hdrlen + 2) << 2;
if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) && if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) &&
...@@ -182,13 +184,12 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -182,13 +184,12 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
goto out; goto out;
} }
} }
((struct iphdr*)work_buf)->protocol = ah->nexthdr;
skb->network_header += ah_hlen; skb->network_header += ah_hlen;
memcpy(skb_network_header(skb), work_buf, ihl); memcpy(skb_network_header(skb), work_buf, ihl);
skb->transport_header = skb->network_header; skb->transport_header = skb->network_header;
__skb_pull(skb, ah_hlen + ihl); __skb_pull(skb, ah_hlen + ihl);
return 0; return nexthdr;
out: out:
return err; return err;
......
...@@ -257,12 +257,11 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -257,12 +257,11 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
} }
iph->protocol = nexthdr[1];
pskb_trim(skb, skb->len - alen - padlen - 2); pskb_trim(skb, skb->len - alen - padlen - 2);
__skb_pull(skb, sizeof(*esph) + esp->conf.ivlen); __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);
skb_set_transport_header(skb, -ihl); skb_set_transport_header(skb, -ihl);
return 0; return nexthdr[1];
out: out:
return -EINVAL; return -EINVAL;
......
...@@ -75,7 +75,6 @@ out: ...@@ -75,7 +75,6 @@ out:
static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
int err = -ENOMEM; int err = -ENOMEM;
struct iphdr *iph;
struct ip_comp_hdr *ipch; struct ip_comp_hdr *ipch;
if (skb_linearize_cow(skb)) if (skb_linearize_cow(skb))
...@@ -84,12 +83,14 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) ...@@ -84,12 +83,14 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
/* Remove ipcomp header and decompress original payload */ /* Remove ipcomp header and decompress original payload */
iph = ip_hdr(skb);
ipch = (void *)skb->data; ipch = (void *)skb->data;
iph->protocol = ipch->nexthdr;
skb->transport_header = skb->network_header + sizeof(*ipch); skb->transport_header = skb->network_header + sizeof(*ipch);
__skb_pull(skb, sizeof(*ipch)); __skb_pull(skb, sizeof(*ipch));
err = ipcomp_decompress(x, skb); err = ipcomp_decompress(x, skb);
if (err)
goto out;
err = ipch->nexthdr;
out: out:
return err; return err;
......
...@@ -54,12 +54,14 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -54,12 +54,14 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
int xfrm_nr = 0; int xfrm_nr = 0;
int decaps = 0; int decaps = 0;
int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq); int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
unsigned int nhoff = offsetof(struct iphdr, protocol);
if (err != 0) if (err != 0)
goto drop; goto drop;
do { do {
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
int nexthdr;
if (xfrm_nr == XFRM_MAX_DEPTH) if (xfrm_nr == XFRM_MAX_DEPTH)
goto drop; goto drop;
...@@ -82,9 +84,12 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) ...@@ -82,9 +84,12 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (xfrm_state_check_expire(x)) if (xfrm_state_check_expire(x))
goto drop_unlock; goto drop_unlock;
if (x->type->input(x, skb)) nexthdr = x->type->input(x, skb);
if (nexthdr <= 0)
goto drop_unlock; goto drop_unlock;
skb_network_header(skb)[nhoff] = nexthdr;
/* only the first xfrm gets the encap type */ /* only the first xfrm gets the encap type */
encap_type = 0; encap_type = 0;
......
...@@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb) ...@@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
{ {
return 0; return IPPROTO_IP;
} }
static int ipip_init_state(struct xfrm_state *x) static int ipip_init_state(struct xfrm_state *x)
......
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