diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ah4.c | 5 | ||||
-rw-r--r-- | net/ipv4/esp4.c | 3 | ||||
-rw-r--r-- | net/ipv4/ipcomp.c | 7 | ||||
-rw-r--r-- | net/ipv4/xfrm4_input.c | 7 | ||||
-rw-r--r-- | net/ipv4/xfrm4_tunnel.c | 2 |
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 | ||
193 | out: | 194 | out: |
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 | ||
267 | out: | 266 | out: |
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: | |||
75 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | 75 | static 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 | ||
94 | out: | 95 | out: |
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 | ||
19 | static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) | 19 | static 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 | ||
24 | static int ipip_init_state(struct xfrm_state *x) | 24 | static int ipip_init_state(struct xfrm_state *x) |