20 #include <linux/list.h>
21 #include <linux/module.h>
24 #include <linux/slab.h>
38 static void *
__percpu *ipcomp_scratches;
39 static int ipcomp_scratch_users;
51 int err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen);
63 if (len > skb_tailroom(skb))
64 len = skb_tailroom(skb);
69 skb_copy_to_linear_data(skb, scratch, len);
71 while ((scratch += len, dlen -= len) > 0) {
79 frag = skb_shinfo(skb)->frags + skb_shinfo(skb)->nr_frags;
86 __skb_frag_set_page(frag, page);
93 skb_frag_size_set(frag, len);
94 memcpy(skb_frag_address(frag), scratch, len);
100 skb_shinfo(skb)->nr_frags++;
116 if (skb_linearize_cow(skb))
122 ipch = (
void *)skb->
data;
126 __skb_pull(skb,
sizeof(*ipch));
127 err = ipcomp_decompress(x, skb);
141 const int plen = skb->
len;
150 err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
182 if (skb_linearize_cow(skb))
185 err = ipcomp_compress(x, skb);
193 ipch->
nexthdr = *skb_mac_header(skb);
198 skb_push(skb, -skb_network_offset(skb));
203 static void ipcomp_free_scratches(
void)
208 if (--ipcomp_scratch_users)
211 scratches = ipcomp_scratches;
221 static
void *
__percpu *ipcomp_alloc_scratches(
void)
226 if (ipcomp_scratch_users++)
227 return ipcomp_scratches;
233 ipcomp_scratches = scratches;
251 if (pos->
tfms == tfms)
268 crypto_free_comp(tfm);
288 if (!
strcmp(crypto_comp_name(tfm), alg_name)) {
299 INIT_LIST_HEAD(&pos->
list);
300 list_add(&pos->
list, &ipcomp_tfms_list);
307 struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
317 ipcomp_free_tfms(tfms);
321 static void ipcomp_free_data(
struct ipcomp_data *ipcd)
324 ipcomp_free_tfms(ipcd->
tfms);
325 ipcomp_free_scratches();
335 ipcomp_free_data(ipcd);
360 if (!ipcomp_alloc_scratches())
363 ipcd->
tfms = ipcomp_alloc_tfms(x->
calg->alg_name);
377 ipcomp_free_data(ipcd);