git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
net
/
ipv4
/
ipcomp.c
diff --git
a/net/ipv4/ipcomp.c
b/net/ipv4/ipcomp.c
index
6845207
..
95278b2
100644
(file)
--- a/
net/ipv4/ipcomp.c
+++ b/
net/ipv4/ipcomp.c
@@
-24,10
+24,12
@@
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/rtnetlink.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/rtnetlink.h>
+#include <linux/mutex.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/icmp.h>
#include <net/ipcomp.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/icmp.h>
#include <net/ipcomp.h>
+#include <net/protocol.h>
struct ipcomp_tfms {
struct list_head list;
struct ipcomp_tfms {
struct list_head list;
@@
-35,7
+37,7
@@
struct ipcomp_tfms {
int users;
};
int users;
};
-static DE
CLARE_MUTEX(ipcomp_resource_sem
);
+static DE
FINE_MUTEX(ipcomp_resource_mutex
);
static void **ipcomp_scratches;
static int ipcomp_scratch_users;
static LIST_HEAD(ipcomp_tfms_list);
static void **ipcomp_scratches;
static int ipcomp_scratch_users;
static LIST_HEAD(ipcomp_tfms_list);
@@
-79,8
+81,7
@@
out:
return err;
}
return err;
}
-static int ipcomp_input(struct xfrm_state *x,
- struct xfrm_decap_state *decap, struct sk_buff *skb)
+static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
{
u8 nexthdr;
int err = 0;
{
u8 nexthdr;
int err = 0;
@@
-154,11
+155,9
@@
out:
return err;
}
return err;
}
-static int ipcomp_output(struct sk_buff *skb)
+static int ipcomp_output(struct
xfrm_state *x, struct
sk_buff *skb)
{
int err;
{
int err;
- struct dst_entry *dst = skb->dst;
- struct xfrm_state *x = dst->xfrm;
struct iphdr *iph;
struct ip_comp_hdr *ipch;
struct ipcomp_data *ipcd = x->data;
struct iphdr *iph;
struct ip_comp_hdr *ipch;
struct ipcomp_data *ipcd = x->data;
@@
-169,32
+168,22
@@
static int ipcomp_output(struct sk_buff *skb)
hdr_len = iph->ihl * 4;
if ((skb->len - hdr_len) < ipcd->threshold) {
/* Don't bother compressing */
hdr_len = iph->ihl * 4;
if ((skb->len - hdr_len) < ipcd->threshold) {
/* Don't bother compressing */
- if (x->props.mode) {
- ip_send_check(iph);
- }
goto out_ok;
}
if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
goto out_ok;
}
if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
- err = -ENOMEM;
- goto error;
+ goto out_ok;
}
err = ipcomp_compress(x, skb);
}
err = ipcomp_compress(x, skb);
+ iph = skb->nh.iph;
+
if (err) {
if (err) {
- if (err == -EMSGSIZE) {
- if (x->props.mode) {
- iph = skb->nh.iph;
- ip_send_check(iph);
- }
- goto out_ok;
- }
- goto error;
+ goto out_ok;
}
/* Install ipcomp header, convert into ipcomp datagram. */
}
/* Install ipcomp header, convert into ipcomp datagram. */
- iph = skb->nh.iph;
iph->tot_len = htons(skb->len);
ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4);
ipch->nexthdr = iph->protocol;
iph->tot_len = htons(skb->len);
ipch = (struct ip_comp_hdr *)((char *)iph + iph->ihl * 4);
ipch->nexthdr = iph->protocol;
@@
-202,12
+191,12
@@
static int ipcomp_output(struct sk_buff *skb)
ipch->cpi = htons((u16 )ntohl(x->id.spi));
iph->protocol = IPPROTO_COMP;
ip_send_check(iph);
ipch->cpi = htons((u16 )ntohl(x->id.spi));
iph->protocol = IPPROTO_COMP;
ip_send_check(iph);
+ return 0;
out_ok:
out_ok:
- err = 0;
-
-error:
- return err;
+ if (x->props.mode)
+ ip_send_check(iph);
+ return 0;
}
static void ipcomp4_err(struct sk_buff *skb, u32 info)
}
static void ipcomp4_err(struct sk_buff *skb, u32 info)
@@
-221,13
+210,13
@@
static void ipcomp4_err(struct sk_buff *skb, u32 info)
skb->h.icmph->code != ICMP_FRAG_NEEDED)
return;
skb->h.icmph->code != ICMP_FRAG_NEEDED)
return;
- spi =
ntoh
l(ntohs(ipch->cpi));
+ spi =
hton
l(ntohs(ipch->cpi));
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr,
spi, IPPROTO_COMP, AF_INET);
if (!x)
return;
x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr,
spi, IPPROTO_COMP, AF_INET);
if (!x)
return;
- NETDEBUG(
printk(
KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%u.%u.%u.%u\n",
-
spi, NIPQUAD(iph->daddr)
));
+ NETDEBUG(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%u.%u.%u.%u\n",
+
spi, NIPQUAD(iph->daddr
));
xfrm_state_put(x);
}
xfrm_state_put(x);
}
@@
-248,15
+237,10
@@
static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
t->props.mode = 1;
t->props.saddr.a4 = x->props.saddr.a4;
t->props.flags = x->props.flags;
-
- t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
- if (t->type == NULL)
- goto error;
-
- if (t->type->init_state(t, NULL))
+
+ if (xfrm_init_state(t))
goto error;
goto error;
- t->km.state = XFRM_STATE_VALID;
atomic_set(&t->tunnel_users, 1);
out:
return t;
atomic_set(&t->tunnel_users, 1);
out:
return t;
@@
-269,7
+253,7
@@
error:
}
/*
}
/*
- * Must be protected by xfrm_cfg_
sem
. State and tunnel user references are
+ * Must be protected by xfrm_cfg_
mutex
. State and tunnel user references are
* always incremented on success.
*/
static int ipcomp_tunnel_attach(struct xfrm_state *x)
* always incremented on success.
*/
static int ipcomp_tunnel_attach(struct xfrm_state *x)
@@
-306,11
+290,8
@@
static void ipcomp_free_scratches(void)
if (!scratches)
return;
if (!scratches)
return;
- for_each_cpu(i) {
- void *scratch = *per_cpu_ptr(scratches, i);
- if (scratch)
- vfree(scratch);
- }
+ for_each_possible_cpu(i)
+ vfree(*per_cpu_ptr(scratches, i));
free_percpu(scratches);
}
free_percpu(scratches);
}
@@
-329,7
+310,7
@@
static void **ipcomp_alloc_scratches(void)
ipcomp_scratches = scratches;
ipcomp_scratches = scratches;
- for_each_cpu(i) {
+ for_each_
possible_
cpu(i) {
void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE);
if (!scratch)
return NULL;
void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE);
if (!scratch)
return NULL;
@@
-360,10
+341,9
@@
static void ipcomp_free_tfms(struct crypto_tfm **tfms)
if (!tfms)
return;
if (!tfms)
return;
- for_each_cpu(cpu) {
+ for_each_
possible_
cpu(cpu) {
struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu);
- if (tfm)
- crypto_free_tfm(tfm);
+ crypto_free_tfm(tfm);
}
free_percpu(tfms);
}
}
free_percpu(tfms);
}
@@
-375,7
+355,7
@@
static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name)
int cpu;
/* This can be any valid CPU ID so we don't need locking. */
int cpu;
/* This can be any valid CPU ID so we don't need locking. */
- cpu = smp_processor_id();
+ cpu =
raw_
smp_processor_id();
list_for_each_entry(pos, &ipcomp_tfms_list, list) {
struct crypto_tfm *tfm;
list_for_each_entry(pos, &ipcomp_tfms_list, list) {
struct crypto_tfm *tfm;
@@
-401,7
+381,7
@@
static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name)
if (!tfms)
goto error;
if (!tfms)
goto error;
- for_each_cpu(cpu) {
+ for_each_
possible_
cpu(cpu) {
struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0);
if (!tfm)
goto error;
struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0);
if (!tfm)
goto error;
@@
-428,13
+408,13
@@
static void ipcomp_destroy(struct xfrm_state *x)
if (!ipcd)
return;
xfrm_state_delete_tunnel(x);
if (!ipcd)
return;
xfrm_state_delete_tunnel(x);
-
down(&ipcomp_resource_sem
);
+
mutex_lock(&ipcomp_resource_mutex
);
ipcomp_free_data(ipcd);
ipcomp_free_data(ipcd);
-
up(&ipcomp_resource_sem
);
+
mutex_unlock(&ipcomp_resource_mutex
);
kfree(ipcd);
}
kfree(ipcd);
}
-static int ipcomp_init_state(struct xfrm_state *x
, void *args
)
+static int ipcomp_init_state(struct xfrm_state *x)
{
int err;
struct ipcomp_data *ipcd;
{
int err;
struct ipcomp_data *ipcd;
@@
-457,14
+437,14
@@
static int ipcomp_init_state(struct xfrm_state *x, void *args)
if (x->props.mode)
x->props.header_len += sizeof(struct iphdr);
if (x->props.mode)
x->props.header_len += sizeof(struct iphdr);
-
down(&ipcomp_resource_sem
);
+
mutex_lock(&ipcomp_resource_mutex
);
if (!ipcomp_alloc_scratches())
goto error;
ipcd->tfms = ipcomp_alloc_tfms(x->calg->alg_name);
if (!ipcd->tfms)
goto error;
if (!ipcomp_alloc_scratches())
goto error;
ipcd->tfms = ipcomp_alloc_tfms(x->calg->alg_name);
if (!ipcd->tfms)
goto error;
-
up(&ipcomp_resource_sem
);
+
mutex_unlock(&ipcomp_resource_mutex
);
if (x->props.mode) {
err = ipcomp_tunnel_attach(x);
if (x->props.mode) {
err = ipcomp_tunnel_attach(x);
@@
-472,7
+452,7
@@
static int ipcomp_init_state(struct xfrm_state *x, void *args)
goto error_tunnel;
}
goto error_tunnel;
}
- calg_desc = xfrm_calg_get_byname(x->calg->alg_name);
+ calg_desc = xfrm_calg_get_byname(x->calg->alg_name
, 0
);
BUG_ON(!calg_desc);
ipcd->threshold = calg_desc->uinfo.comp.threshold;
x->data = ipcd;
BUG_ON(!calg_desc);
ipcd->threshold = calg_desc->uinfo.comp.threshold;
x->data = ipcd;
@@
-481,10
+461,10
@@
out:
return err;
error_tunnel:
return err;
error_tunnel:
-
down(&ipcomp_resource_sem
);
+
mutex_lock(&ipcomp_resource_mutex
);
error:
ipcomp_free_data(ipcd);
error:
ipcomp_free_data(ipcd);
-
up(&ipcomp_resource_sem
);
+
mutex_unlock(&ipcomp_resource_mutex
);
kfree(ipcd);
goto out;
}
kfree(ipcd);
goto out;
}