aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/ah4.c5
-rw-r--r--net/ipv4/esp4.c3
-rw-r--r--net/ipv4/ipcomp.c7
-rw-r--r--net/ipv4/xfrm4_input.c7
-rw-r--r--net/ipv4/xfrm4_tunnel.c2
5 files changed, 15 insertions, 9 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 60925fedbf16..4e8e3b079f5b 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -125,6 +125,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
125{ 125{
126 int ah_hlen; 126 int ah_hlen;
127 int ihl; 127 int ihl;
128 int nexthdr;
128 int err = -EINVAL; 129 int err = -EINVAL;
129 struct iphdr *iph; 130 struct iphdr *iph;
130 struct ip_auth_hdr *ah; 131 struct ip_auth_hdr *ah;
@@ -136,6 +137,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
136 137
137 ah = (struct ip_auth_hdr *)skb->data; 138 ah = (struct ip_auth_hdr *)skb->data;
138 ahp = x->data; 139 ahp = x->data;
140 nexthdr = ah->nexthdr;
139 ah_hlen = (ah->hdrlen + 2) << 2; 141 ah_hlen = (ah->hdrlen + 2) << 2;
140 142
141 if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) && 143 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 goto out; 184 goto out;
183 } 185 }
184 } 186 }
185 ((struct iphdr*)work_buf)->protocol = ah->nexthdr;
186 skb->network_header += ah_hlen; 187 skb->network_header += ah_hlen;
187 memcpy(skb_network_header(skb), work_buf, ihl); 188 memcpy(skb_network_header(skb), work_buf, ihl);
188 skb->transport_header = skb->network_header; 189 skb->transport_header = skb->network_header;
189 __skb_pull(skb, ah_hlen + ihl); 190 __skb_pull(skb, ah_hlen + ihl);
190 191
191 return 0; 192 return nexthdr;
192 193
193out: 194out:
194 return err; 195 return err;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 8377bedf3f66..6b1a31a74cf2 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -257,12 +257,11 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
257 skb->ip_summed = CHECKSUM_UNNECESSARY; 257 skb->ip_summed = CHECKSUM_UNNECESSARY;
258 } 258 }
259 259
260 iph->protocol = nexthdr[1];
261 pskb_trim(skb, skb->len - alen - padlen - 2); 260 pskb_trim(skb, skb->len - alen - padlen - 2);
262 __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen); 261 __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen);
263 skb_set_transport_header(skb, -ihl); 262 skb_set_transport_header(skb, -ihl);
264 263
265 return 0; 264 return nexthdr[1];
266 265
267out: 266out:
268 return -EINVAL; 267 return -EINVAL;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 32b02deca2ec..0bfeb02a5f87 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -75,7 +75,6 @@ out:
75static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) 75static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
76{ 76{
77 int err = -ENOMEM; 77 int err = -ENOMEM;
78 struct iphdr *iph;
79 struct ip_comp_hdr *ipch; 78 struct ip_comp_hdr *ipch;
80 79
81 if (skb_linearize_cow(skb)) 80 if (skb_linearize_cow(skb))
@@ -84,12 +83,14 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
84 skb->ip_summed = CHECKSUM_NONE; 83 skb->ip_summed = CHECKSUM_NONE;
85 84
86 /* Remove ipcomp header and decompress original payload */ 85 /* Remove ipcomp header and decompress original payload */
87 iph = ip_hdr(skb);
88 ipch = (void *)skb->data; 86 ipch = (void *)skb->data;
89 iph->protocol = ipch->nexthdr;
90 skb->transport_header = skb->network_header + sizeof(*ipch); 87 skb->transport_header = skb->network_header + sizeof(*ipch);
91 __skb_pull(skb, sizeof(*ipch)); 88 __skb_pull(skb, sizeof(*ipch));
92 err = ipcomp_decompress(x, skb); 89 err = ipcomp_decompress(x, skb);
90 if (err)
91 goto out;
92
93 err = ipch->nexthdr;
93 94
94out: 95out:
95 return err; 96 return err;
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 2fa108245413..e9bbfde19ac3 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -54,12 +54,14 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
54 int xfrm_nr = 0; 54 int xfrm_nr = 0;
55 int decaps = 0; 55 int decaps = 0;
56 int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq); 56 int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);
57 unsigned int nhoff = offsetof(struct iphdr, protocol);
57 58
58 if (err != 0) 59 if (err != 0)
59 goto drop; 60 goto drop;
60 61
61 do { 62 do {
62 const struct iphdr *iph = ip_hdr(skb); 63 const struct iphdr *iph = ip_hdr(skb);
64 int nexthdr;
63 65
64 if (xfrm_nr == XFRM_MAX_DEPTH) 66 if (xfrm_nr == XFRM_MAX_DEPTH)
65 goto drop; 67 goto drop;
@@ -82,9 +84,12 @@ static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
82 if (xfrm_state_check_expire(x)) 84 if (xfrm_state_check_expire(x))
83 goto drop_unlock; 85 goto drop_unlock;
84 86
85 if (x->type->input(x, skb)) 87 nexthdr = x->type->input(x, skb);
88 if (nexthdr <= 0)
86 goto drop_unlock; 89 goto drop_unlock;
87 90
91 skb_network_header(skb)[nhoff] = nexthdr;
92
88 /* only the first xfrm gets the encap type */ 93 /* only the first xfrm gets the encap type */
89 encap_type = 0; 94 encap_type = 0;
90 95
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index e1fafc1562d8..1312417608e2 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb)
18 18
19static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) 19static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
20{ 20{
21 return 0; 21 return IPPROTO_IP;
22} 22}
23 23
24static int ipip_init_state(struct xfrm_state *x) 24static int ipip_init_state(struct xfrm_state *x)