#include <net/protocol.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
-#include <linux/mutex.h>
struct ipcomp6_tfms {
struct list_head list;
int users;
};
-static DEFINE_MUTEX(ipcomp6_resource_mutex);
+static DECLARE_MUTEX(ipcomp6_resource_sem);
static void **ipcomp6_scratches;
static int ipcomp6_scratch_users;
static LIST_HEAD(ipcomp6_tfms_list);
-static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
+static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
{
int err = 0;
u8 nexthdr = 0;
if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG)
return;
- spi = htonl(ntohs(ipcomph->cpi));
+ spi = ntohl(ntohs(ipcomph->cpi));
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
if (!x)
return;
t->id.proto = IPPROTO_IPV6;
t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr);
- if (!t->id.spi)
- goto error;
-
memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
memcpy(&t->sel, &x->sel, sizeof(t->sel));
t->props.family = AF_INET6;
return t;
error:
- t->km.state = XFRM_STATE_DEAD;
xfrm_state_put(t);
- t = NULL;
goto out;
}
if (!scratches)
return;
- for_each_possible_cpu(i) {
+ for_each_cpu(i) {
void *scratch = *per_cpu_ptr(scratches, i);
-
- vfree(scratch);
+ if (scratch)
+ vfree(scratch);
}
free_percpu(scratches);
ipcomp6_scratches = scratches;
- for_each_possible_cpu(i) {
+ for_each_cpu(i) {
void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE);
if (!scratch)
return NULL;
if (!tfms)
return;
- for_each_possible_cpu(cpu) {
+ for_each_cpu(cpu) {
struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
crypto_free_tfm(tfm);
}
if (!tfms)
goto error;
- for_each_possible_cpu(cpu) {
+ for_each_cpu(cpu) {
struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0);
if (!tfm)
goto error;
if (!ipcd)
return;
xfrm_state_delete_tunnel(x);
- mutex_lock(&ipcomp6_resource_mutex);
+ down(&ipcomp6_resource_sem);
ipcomp6_free_data(ipcd);
- mutex_unlock(&ipcomp6_resource_mutex);
+ up(&ipcomp6_resource_sem);
kfree(ipcd);
xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
goto out;
err = -ENOMEM;
- ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
+ ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd)
goto out;
+ memset(ipcd, 0, sizeof(*ipcd));
x->props.header_len = 0;
if (x->props.mode)
x->props.header_len += sizeof(struct ipv6hdr);
- mutex_lock(&ipcomp6_resource_mutex);
+ down(&ipcomp6_resource_sem);
if (!ipcomp6_alloc_scratches())
goto error;
ipcd->tfms = ipcomp6_alloc_tfms(x->calg->alg_name);
if (!ipcd->tfms)
goto error;
- mutex_unlock(&ipcomp6_resource_mutex);
+ up(&ipcomp6_resource_sem);
if (x->props.mode) {
err = ipcomp6_tunnel_attach(x);
out:
return err;
error_tunnel:
- mutex_lock(&ipcomp6_resource_mutex);
+ down(&ipcomp6_resource_sem);
error:
ipcomp6_free_data(ipcd);
- mutex_unlock(&ipcomp6_resource_mutex);
+ up(&ipcomp6_resource_sem);
kfree(ipcd);
goto out;