diff options
-rw-r--r-- | include/linux/xfrm.h | 1 | ||||
-rw-r--r-- | include/net/xfrm.h | 1 | ||||
-rw-r--r-- | net/ipv4/ah4.c | 25 |
3 files changed, 21 insertions, 6 deletions
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 930fdd2de79c..b93d6f598085 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h | |||
@@ -350,6 +350,7 @@ struct xfrm_usersa_info { | |||
350 | #define XFRM_STATE_WILDRECV 8 | 350 | #define XFRM_STATE_WILDRECV 8 |
351 | #define XFRM_STATE_ICMP 16 | 351 | #define XFRM_STATE_ICMP 16 |
352 | #define XFRM_STATE_AF_UNSPEC 32 | 352 | #define XFRM_STATE_AF_UNSPEC 32 |
353 | #define XFRM_STATE_ALIGN4 64 | ||
353 | }; | 354 | }; |
354 | 355 | ||
355 | struct xfrm_usersa_id { | 356 | struct xfrm_usersa_id { |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index b9f385da758e..1f6e8a0eb544 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #define XFRM_PROTO_ROUTING IPPROTO_ROUTING | 36 | #define XFRM_PROTO_ROUTING IPPROTO_ROUTING |
37 | #define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS | 37 | #define XFRM_PROTO_DSTOPTS IPPROTO_DSTOPTS |
38 | 38 | ||
39 | #define XFRM_ALIGN4(len) (((len) + 3) & ~3) | ||
39 | #define XFRM_ALIGN8(len) (((len) + 7) & ~7) | 40 | #define XFRM_ALIGN8(len) (((len) + 7) & ~7) |
40 | #define MODULE_ALIAS_XFRM_MODE(family, encap) \ | 41 | #define MODULE_ALIAS_XFRM_MODE(family, encap) \ |
41 | MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap)) | 42 | MODULE_ALIAS("xfrm-mode-" __stringify(family) "-" __stringify(encap)) |
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 86961bec70ab..325053df6e70 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -201,7 +201,10 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) | |||
201 | top_iph->ttl = 0; | 201 | top_iph->ttl = 0; |
202 | top_iph->check = 0; | 202 | top_iph->check = 0; |
203 | 203 | ||
204 | ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2; | 204 | if (x->props.flags & XFRM_STATE_ALIGN4) |
205 | ah->hdrlen = (XFRM_ALIGN4(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2; | ||
206 | else | ||
207 | ah->hdrlen = (XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len) >> 2) - 2; | ||
205 | 208 | ||
206 | ah->reserved = 0; | 209 | ah->reserved = 0; |
207 | ah->spi = x->id.spi; | 210 | ah->spi = x->id.spi; |
@@ -299,9 +302,15 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | |||
299 | nexthdr = ah->nexthdr; | 302 | nexthdr = ah->nexthdr; |
300 | ah_hlen = (ah->hdrlen + 2) << 2; | 303 | ah_hlen = (ah->hdrlen + 2) << 2; |
301 | 304 | ||
302 | if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) && | 305 | if (x->props.flags & XFRM_STATE_ALIGN4) { |
303 | ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len)) | 306 | if (ah_hlen != XFRM_ALIGN4(sizeof(*ah) + ahp->icv_full_len) && |
304 | goto out; | 307 | ah_hlen != XFRM_ALIGN4(sizeof(*ah) + ahp->icv_trunc_len)) |
308 | goto out; | ||
309 | } else { | ||
310 | if (ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_full_len) && | ||
311 | ah_hlen != XFRM_ALIGN8(sizeof(*ah) + ahp->icv_trunc_len)) | ||
312 | goto out; | ||
313 | } | ||
305 | 314 | ||
306 | if (!pskb_may_pull(skb, ah_hlen)) | 315 | if (!pskb_may_pull(skb, ah_hlen)) |
307 | goto out; | 316 | goto out; |
@@ -450,8 +459,12 @@ static int ah_init_state(struct xfrm_state *x) | |||
450 | 459 | ||
451 | BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN); | 460 | BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN); |
452 | 461 | ||
453 | x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + | 462 | if (x->props.flags & XFRM_STATE_ALIGN4) |
454 | ahp->icv_trunc_len); | 463 | x->props.header_len = XFRM_ALIGN4(sizeof(struct ip_auth_hdr) + |
464 | ahp->icv_trunc_len); | ||
465 | else | ||
466 | x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + | ||
467 | ahp->icv_trunc_len); | ||
455 | if (x->props.mode == XFRM_MODE_TUNNEL) | 468 | if (x->props.mode == XFRM_MODE_TUNNEL) |
456 | x->props.header_len += sizeof(struct iphdr); | 469 | x->props.header_len += sizeof(struct iphdr); |
457 | x->data = ahp; | 470 | x->data = ahp; |