Commit b55ee909 authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji

[XFRM] fix dependency issues for CONFIG_IPV6=m.

parent 0d51db7b
...@@ -816,7 +816,7 @@ extern void xfrm_state_flush(u8 proto); ...@@ -816,7 +816,7 @@ extern void xfrm_state_flush(u8 proto);
extern int xfrm_replay_check(struct xfrm_state *x, u32 seq); extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq); extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl); extern int xfrm_check_selectors(struct xfrm_state **x, int n, struct flowi *fl);
extern int xfrm_check_output(struct xfrm_state *x, struct sk_buff *skb, unsigned short family); extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
extern int xfrm4_rcv(struct sk_buff *skb); extern int xfrm4_rcv(struct sk_buff *skb);
extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
......
...@@ -74,12 +74,15 @@ static int ah_output(struct sk_buff **pskb) ...@@ -74,12 +74,15 @@ static int ah_output(struct sk_buff **pskb)
} }
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
err = xfrm_check_output(x, *pskb, AF_INET); err = xfrm_state_check(x, *pskb);
if (err) if (err)
goto error; goto error;
iph = (*pskb)->nh.iph; iph = (*pskb)->nh.iph;
if (x->props.mode) { if (x->props.mode) {
err = xfrm4_tunnel_check_size(*pskb);
if (err)
goto error;
top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len); top_iph = (struct iphdr*)skb_push(*pskb, x->props.header_len);
top_iph->ihl = 5; top_iph->ihl = 5;
top_iph->version = 4; top_iph->version = 4;
......
...@@ -49,19 +49,24 @@ int esp_output(struct sk_buff **pskb) ...@@ -49,19 +49,24 @@ int esp_output(struct sk_buff **pskb)
} }
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
err = xfrm_check_output(x, *pskb, AF_INET); err = xfrm_state_check(x, *pskb);
if (err) if (err)
goto error; goto error;
err = -ENOMEM;
/* Strip IP header in transport mode. Save it. */ if (x->props.mode) {
if (!x->props.mode) { err = xfrm4_tunnel_check_size(*pskb);
if (err)
goto error;
} else {
/* Strip IP header in transport mode. Save it. */
iph = (*pskb)->nh.iph; iph = (*pskb)->nh.iph;
memcpy(&tmp_iph, iph, iph->ihl*4); memcpy(&tmp_iph, iph, iph->ihl*4);
__skb_pull(*pskb, iph->ihl*4); __skb_pull(*pskb, iph->ihl*4);
} }
/* Now skb is pure payload to encrypt */ /* Now skb is pure payload to encrypt */
err = -ENOMEM;
/* Round to block size */ /* Round to block size */
clen = (*pskb)->len; clen = (*pskb)->len;
......
...@@ -164,12 +164,16 @@ static int ipcomp_output(struct sk_buff **pskb) ...@@ -164,12 +164,16 @@ static int ipcomp_output(struct sk_buff **pskb)
} }
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
err = xfrm_check_output(x, *pskb, AF_INET); err = xfrm_state_check(x, *pskb);
if (err) if (err)
goto error; goto error;
/* Don't bother compressing */ if (x->props.mode) {
if (!x->props.mode) { err = xfrm4_tunnel_check_size(*pskb);
if (err)
goto error;
} else {
/* Don't bother compressing */
iph = (*pskb)->nh.iph; iph = (*pskb)->nh.iph;
hdr_len = iph->ihl * 4; hdr_len = iph->ihl * 4;
} }
......
...@@ -163,11 +163,15 @@ int ah6_output(struct sk_buff **pskb) ...@@ -163,11 +163,15 @@ int ah6_output(struct sk_buff **pskb)
} }
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
err = xfrm_check_output(x, *pskb, AF_INET6); err = xfrm_state_check(x, *pskb);
if (err) if (err)
goto error; goto error;
if (x->props.mode) { if (x->props.mode) {
err = xfrm6_tunnel_check_size(*pskb);
if (err)
goto error;
iph = (*pskb)->nh.ipv6h; iph = (*pskb)->nh.ipv6h;
(*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len); (*pskb)->nh.ipv6h = (struct ipv6hdr*)skb_push(*pskb, x->props.header_len);
(*pskb)->nh.ipv6h->version = 6; (*pskb)->nh.ipv6h->version = 6;
......
...@@ -65,14 +65,16 @@ int esp6_output(struct sk_buff **pskb) ...@@ -65,14 +65,16 @@ int esp6_output(struct sk_buff **pskb)
} }
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
err = xfrm_check_output(x, *pskb, AF_INET6); err = xfrm_state_check(x, *pskb);
if (err) if (err)
goto error; goto error;
err = -ENOMEM;
/* Strip IP header in transport mode. Save it. */
if (!x->props.mode) { if (x->props.mode) {
err = xfrm6_tunnel_check_size(*pskb);
if (err)
goto error;
} else {
/* Strip IP header in transport mode. Save it. */
hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr); hdr_len = ip6_find_1stfragopt(*pskb, &prevhdr);
nexthdr = *prevhdr; nexthdr = *prevhdr;
*prevhdr = IPPROTO_ESP; *prevhdr = IPPROTO_ESP;
...@@ -86,6 +88,7 @@ int esp6_output(struct sk_buff **pskb) ...@@ -86,6 +88,7 @@ int esp6_output(struct sk_buff **pskb)
} }
/* Now skb is pure payload to encrypt */ /* Now skb is pure payload to encrypt */
err = -ENOMEM;
/* Round to block size */ /* Round to block size */
clen = (*pskb)->len; clen = (*pskb)->len;
......
...@@ -140,11 +140,15 @@ static int ipcomp6_output(struct sk_buff **pskb) ...@@ -140,11 +140,15 @@ static int ipcomp6_output(struct sk_buff **pskb)
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
err = xfrm_check_output(x, *pskb, AF_INET6); err = xfrm_state_check(x, *pskb);
if (err) if (err)
goto error; goto error;
if (x->props.mode) { if (x->props.mode) {
err = xfrm6_tunnel_check_size(*pskb);
if (err)
goto error;
hdr_len = sizeof(struct ipv6hdr); hdr_len = sizeof(struct ipv6hdr);
nexthdr = IPPROTO_IPV6; nexthdr = IPPROTO_IPV6;
iph = (*pskb)->nh.ipv6h; iph = (*pskb)->nh.ipv6h;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the XFRM subsystem. # Makefile for the XFRM subsystem.
# #
obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o xfrm_output.o \ obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_input.o xfrm_algo.o \
xfrm_export.o xfrm_export.o
obj-$(CONFIG_XFRM_USER) += xfrm_user.o obj-$(CONFIG_XFRM_USER) += xfrm_user.o
...@@ -18,6 +18,7 @@ EXPORT_SYMBOL(xfrm_state_add); ...@@ -18,6 +18,7 @@ EXPORT_SYMBOL(xfrm_state_add);
EXPORT_SYMBOL(xfrm_state_update); EXPORT_SYMBOL(xfrm_state_update);
EXPORT_SYMBOL(xfrm_state_check_expire); EXPORT_SYMBOL(xfrm_state_check_expire);
EXPORT_SYMBOL(xfrm_state_check_space); EXPORT_SYMBOL(xfrm_state_check_space);
EXPORT_SYMBOL(xfrm_state_check);
EXPORT_SYMBOL(xfrm_state_lookup); EXPORT_SYMBOL(xfrm_state_lookup);
EXPORT_SYMBOL(xfrm_state_register_afinfo); EXPORT_SYMBOL(xfrm_state_register_afinfo);
EXPORT_SYMBOL(xfrm_state_unregister_afinfo); EXPORT_SYMBOL(xfrm_state_unregister_afinfo);
...@@ -27,7 +28,6 @@ EXPORT_SYMBOL(xfrm_state_delete_tunnel); ...@@ -27,7 +28,6 @@ EXPORT_SYMBOL(xfrm_state_delete_tunnel);
EXPORT_SYMBOL(xfrm_replay_check); EXPORT_SYMBOL(xfrm_replay_check);
EXPORT_SYMBOL(xfrm_replay_advance); EXPORT_SYMBOL(xfrm_replay_advance);
EXPORT_SYMBOL(xfrm_check_selectors); EXPORT_SYMBOL(xfrm_check_selectors);
EXPORT_SYMBOL(xfrm_check_output);
EXPORT_SYMBOL(__secpath_destroy); EXPORT_SYMBOL(__secpath_destroy);
EXPORT_SYMBOL(secpath_dup); EXPORT_SYMBOL(secpath_dup);
EXPORT_SYMBOL(xfrm_get_acqseq); EXPORT_SYMBOL(xfrm_get_acqseq);
......
/*
* generic xfrm output routines
*
* Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <net/xfrm.h>
int xfrm_check_output(struct xfrm_state *x,
struct sk_buff *skb, unsigned short family)
{
int err;
err = xfrm_state_check_expire(x);
if (err)
goto out;
if (x->props.mode) {
switch (family) {
case AF_INET:
err = xfrm4_tunnel_check_size(skb);
break;
case AF_INET6:
err = xfrm6_tunnel_check_size(skb);
break;
default:
err = -EINVAL;
}
if (err)
goto out;
}
err = xfrm_state_check_space(x, skb);
out:
return err;
}
...@@ -531,6 +531,16 @@ int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) ...@@ -531,6 +531,16 @@ int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
return 0; return 0;
} }
int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb)
{
int err = xfrm_state_check_expire(x);
if (err < 0)
goto err;
err = xfrm_state_check_space(x, skb);
err:
return err;
}
struct xfrm_state * struct xfrm_state *
xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto,
unsigned short family) unsigned short family)
......
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