xref: /openbmc/linux/net/xfrm/xfrm_algo.c (revision 9d749629)
1 /*
2  * xfrm algorithm interface
3  *
4  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  */
11 
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/pfkeyv2.h>
15 #include <linux/crypto.h>
16 #include <linux/scatterlist.h>
17 #include <net/xfrm.h>
18 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
19 #include <net/esp.h>
20 #endif
21 
22 /*
23  * Algorithms supported by IPsec.  These entries contain properties which
24  * are used in key negotiation and xfrm processing, and are used to verify
25  * that instantiated crypto transforms have correct parameters for IPsec
26  * purposes.
27  */
28 static struct xfrm_algo_desc aead_list[] = {
29 {
30 	.name = "rfc4106(gcm(aes))",
31 
32 	.uinfo = {
33 		.aead = {
34 			.icv_truncbits = 64,
35 		}
36 	},
37 
38 	.pfkey_supported = 1,
39 
40 	.desc = {
41 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV8,
42 		.sadb_alg_ivlen = 8,
43 		.sadb_alg_minbits = 128,
44 		.sadb_alg_maxbits = 256
45 	}
46 },
47 {
48 	.name = "rfc4106(gcm(aes))",
49 
50 	.uinfo = {
51 		.aead = {
52 			.icv_truncbits = 96,
53 		}
54 	},
55 
56 	.pfkey_supported = 1,
57 
58 	.desc = {
59 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV12,
60 		.sadb_alg_ivlen = 8,
61 		.sadb_alg_minbits = 128,
62 		.sadb_alg_maxbits = 256
63 	}
64 },
65 {
66 	.name = "rfc4106(gcm(aes))",
67 
68 	.uinfo = {
69 		.aead = {
70 			.icv_truncbits = 128,
71 		}
72 	},
73 
74 	.pfkey_supported = 1,
75 
76 	.desc = {
77 		.sadb_alg_id = SADB_X_EALG_AES_GCM_ICV16,
78 		.sadb_alg_ivlen = 8,
79 		.sadb_alg_minbits = 128,
80 		.sadb_alg_maxbits = 256
81 	}
82 },
83 {
84 	.name = "rfc4309(ccm(aes))",
85 
86 	.uinfo = {
87 		.aead = {
88 			.icv_truncbits = 64,
89 		}
90 	},
91 
92 	.pfkey_supported = 1,
93 
94 	.desc = {
95 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV8,
96 		.sadb_alg_ivlen = 8,
97 		.sadb_alg_minbits = 128,
98 		.sadb_alg_maxbits = 256
99 	}
100 },
101 {
102 	.name = "rfc4309(ccm(aes))",
103 
104 	.uinfo = {
105 		.aead = {
106 			.icv_truncbits = 96,
107 		}
108 	},
109 
110 	.pfkey_supported = 1,
111 
112 	.desc = {
113 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV12,
114 		.sadb_alg_ivlen = 8,
115 		.sadb_alg_minbits = 128,
116 		.sadb_alg_maxbits = 256
117 	}
118 },
119 {
120 	.name = "rfc4309(ccm(aes))",
121 
122 	.uinfo = {
123 		.aead = {
124 			.icv_truncbits = 128,
125 		}
126 	},
127 
128 	.pfkey_supported = 1,
129 
130 	.desc = {
131 		.sadb_alg_id = SADB_X_EALG_AES_CCM_ICV16,
132 		.sadb_alg_ivlen = 8,
133 		.sadb_alg_minbits = 128,
134 		.sadb_alg_maxbits = 256
135 	}
136 },
137 {
138 	.name = "rfc4543(gcm(aes))",
139 
140 	.uinfo = {
141 		.aead = {
142 			.icv_truncbits = 128,
143 		}
144 	},
145 
146 	.pfkey_supported = 1,
147 
148 	.desc = {
149 		.sadb_alg_id = SADB_X_EALG_NULL_AES_GMAC,
150 		.sadb_alg_ivlen = 8,
151 		.sadb_alg_minbits = 128,
152 		.sadb_alg_maxbits = 256
153 	}
154 },
155 };
156 
157 static struct xfrm_algo_desc aalg_list[] = {
158 {
159 	.name = "digest_null",
160 
161 	.uinfo = {
162 		.auth = {
163 			.icv_truncbits = 0,
164 			.icv_fullbits = 0,
165 		}
166 	},
167 
168 	.pfkey_supported = 1,
169 
170 	.desc = {
171 		.sadb_alg_id = SADB_X_AALG_NULL,
172 		.sadb_alg_ivlen = 0,
173 		.sadb_alg_minbits = 0,
174 		.sadb_alg_maxbits = 0
175 	}
176 },
177 {
178 	.name = "hmac(md5)",
179 	.compat = "md5",
180 
181 	.uinfo = {
182 		.auth = {
183 			.icv_truncbits = 96,
184 			.icv_fullbits = 128,
185 		}
186 	},
187 
188 	.pfkey_supported = 1,
189 
190 	.desc = {
191 		.sadb_alg_id = SADB_AALG_MD5HMAC,
192 		.sadb_alg_ivlen = 0,
193 		.sadb_alg_minbits = 128,
194 		.sadb_alg_maxbits = 128
195 	}
196 },
197 {
198 	.name = "hmac(sha1)",
199 	.compat = "sha1",
200 
201 	.uinfo = {
202 		.auth = {
203 			.icv_truncbits = 96,
204 			.icv_fullbits = 160,
205 		}
206 	},
207 
208 	.pfkey_supported = 1,
209 
210 	.desc = {
211 		.sadb_alg_id = SADB_AALG_SHA1HMAC,
212 		.sadb_alg_ivlen = 0,
213 		.sadb_alg_minbits = 160,
214 		.sadb_alg_maxbits = 160
215 	}
216 },
217 {
218 	.name = "hmac(sha256)",
219 	.compat = "sha256",
220 
221 	.uinfo = {
222 		.auth = {
223 			.icv_truncbits = 96,
224 			.icv_fullbits = 256,
225 		}
226 	},
227 
228 	.pfkey_supported = 1,
229 
230 	.desc = {
231 		.sadb_alg_id = SADB_X_AALG_SHA2_256HMAC,
232 		.sadb_alg_ivlen = 0,
233 		.sadb_alg_minbits = 256,
234 		.sadb_alg_maxbits = 256
235 	}
236 },
237 {
238 	.name = "hmac(sha384)",
239 
240 	.uinfo = {
241 		.auth = {
242 			.icv_truncbits = 192,
243 			.icv_fullbits = 384,
244 		}
245 	},
246 
247 	.pfkey_supported = 1,
248 
249 	.desc = {
250 		.sadb_alg_id = SADB_X_AALG_SHA2_384HMAC,
251 		.sadb_alg_ivlen = 0,
252 		.sadb_alg_minbits = 384,
253 		.sadb_alg_maxbits = 384
254 	}
255 },
256 {
257 	.name = "hmac(sha512)",
258 
259 	.uinfo = {
260 		.auth = {
261 			.icv_truncbits = 256,
262 			.icv_fullbits = 512,
263 		}
264 	},
265 
266 	.pfkey_supported = 1,
267 
268 	.desc = {
269 		.sadb_alg_id = SADB_X_AALG_SHA2_512HMAC,
270 		.sadb_alg_ivlen = 0,
271 		.sadb_alg_minbits = 512,
272 		.sadb_alg_maxbits = 512
273 	}
274 },
275 {
276 	.name = "hmac(rmd160)",
277 	.compat = "rmd160",
278 
279 	.uinfo = {
280 		.auth = {
281 			.icv_truncbits = 96,
282 			.icv_fullbits = 160,
283 		}
284 	},
285 
286 	.pfkey_supported = 1,
287 
288 	.desc = {
289 		.sadb_alg_id = SADB_X_AALG_RIPEMD160HMAC,
290 		.sadb_alg_ivlen = 0,
291 		.sadb_alg_minbits = 160,
292 		.sadb_alg_maxbits = 160
293 	}
294 },
295 {
296 	.name = "xcbc(aes)",
297 
298 	.uinfo = {
299 		.auth = {
300 			.icv_truncbits = 96,
301 			.icv_fullbits = 128,
302 		}
303 	},
304 
305 	.pfkey_supported = 1,
306 
307 	.desc = {
308 		.sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
309 		.sadb_alg_ivlen = 0,
310 		.sadb_alg_minbits = 128,
311 		.sadb_alg_maxbits = 128
312 	}
313 },
314 };
315 
316 static struct xfrm_algo_desc ealg_list[] = {
317 {
318 	.name = "ecb(cipher_null)",
319 	.compat = "cipher_null",
320 
321 	.uinfo = {
322 		.encr = {
323 			.blockbits = 8,
324 			.defkeybits = 0,
325 		}
326 	},
327 
328 	.pfkey_supported = 1,
329 
330 	.desc = {
331 		.sadb_alg_id =	SADB_EALG_NULL,
332 		.sadb_alg_ivlen = 0,
333 		.sadb_alg_minbits = 0,
334 		.sadb_alg_maxbits = 0
335 	}
336 },
337 {
338 	.name = "cbc(des)",
339 	.compat = "des",
340 
341 	.uinfo = {
342 		.encr = {
343 			.blockbits = 64,
344 			.defkeybits = 64,
345 		}
346 	},
347 
348 	.pfkey_supported = 1,
349 
350 	.desc = {
351 		.sadb_alg_id = SADB_EALG_DESCBC,
352 		.sadb_alg_ivlen = 8,
353 		.sadb_alg_minbits = 64,
354 		.sadb_alg_maxbits = 64
355 	}
356 },
357 {
358 	.name = "cbc(des3_ede)",
359 	.compat = "des3_ede",
360 
361 	.uinfo = {
362 		.encr = {
363 			.blockbits = 64,
364 			.defkeybits = 192,
365 		}
366 	},
367 
368 	.pfkey_supported = 1,
369 
370 	.desc = {
371 		.sadb_alg_id = SADB_EALG_3DESCBC,
372 		.sadb_alg_ivlen = 8,
373 		.sadb_alg_minbits = 192,
374 		.sadb_alg_maxbits = 192
375 	}
376 },
377 {
378 	.name = "cbc(cast5)",
379 	.compat = "cast5",
380 
381 	.uinfo = {
382 		.encr = {
383 			.blockbits = 64,
384 			.defkeybits = 128,
385 		}
386 	},
387 
388 	.pfkey_supported = 1,
389 
390 	.desc = {
391 		.sadb_alg_id = SADB_X_EALG_CASTCBC,
392 		.sadb_alg_ivlen = 8,
393 		.sadb_alg_minbits = 40,
394 		.sadb_alg_maxbits = 128
395 	}
396 },
397 {
398 	.name = "cbc(blowfish)",
399 	.compat = "blowfish",
400 
401 	.uinfo = {
402 		.encr = {
403 			.blockbits = 64,
404 			.defkeybits = 128,
405 		}
406 	},
407 
408 	.pfkey_supported = 1,
409 
410 	.desc = {
411 		.sadb_alg_id = SADB_X_EALG_BLOWFISHCBC,
412 		.sadb_alg_ivlen = 8,
413 		.sadb_alg_minbits = 40,
414 		.sadb_alg_maxbits = 448
415 	}
416 },
417 {
418 	.name = "cbc(aes)",
419 	.compat = "aes",
420 
421 	.uinfo = {
422 		.encr = {
423 			.blockbits = 128,
424 			.defkeybits = 128,
425 		}
426 	},
427 
428 	.pfkey_supported = 1,
429 
430 	.desc = {
431 		.sadb_alg_id = SADB_X_EALG_AESCBC,
432 		.sadb_alg_ivlen = 8,
433 		.sadb_alg_minbits = 128,
434 		.sadb_alg_maxbits = 256
435 	}
436 },
437 {
438 	.name = "cbc(serpent)",
439 	.compat = "serpent",
440 
441 	.uinfo = {
442 		.encr = {
443 			.blockbits = 128,
444 			.defkeybits = 128,
445 		}
446 	},
447 
448 	.pfkey_supported = 1,
449 
450 	.desc = {
451 		.sadb_alg_id = SADB_X_EALG_SERPENTCBC,
452 		.sadb_alg_ivlen = 8,
453 		.sadb_alg_minbits = 128,
454 		.sadb_alg_maxbits = 256,
455 	}
456 },
457 {
458 	.name = "cbc(camellia)",
459 	.compat = "camellia",
460 
461 	.uinfo = {
462 		.encr = {
463 			.blockbits = 128,
464 			.defkeybits = 128,
465 		}
466 	},
467 
468 	.pfkey_supported = 1,
469 
470 	.desc = {
471 		.sadb_alg_id = SADB_X_EALG_CAMELLIACBC,
472 		.sadb_alg_ivlen = 8,
473 		.sadb_alg_minbits = 128,
474 		.sadb_alg_maxbits = 256
475 	}
476 },
477 {
478 	.name = "cbc(twofish)",
479 	.compat = "twofish",
480 
481 	.uinfo = {
482 		.encr = {
483 			.blockbits = 128,
484 			.defkeybits = 128,
485 		}
486 	},
487 
488 	.pfkey_supported = 1,
489 
490 	.desc = {
491 		.sadb_alg_id = SADB_X_EALG_TWOFISHCBC,
492 		.sadb_alg_ivlen = 8,
493 		.sadb_alg_minbits = 128,
494 		.sadb_alg_maxbits = 256
495 	}
496 },
497 {
498 	.name = "rfc3686(ctr(aes))",
499 
500 	.uinfo = {
501 		.encr = {
502 			.blockbits = 128,
503 			.defkeybits = 160, /* 128-bit key + 32-bit nonce */
504 		}
505 	},
506 
507 	.pfkey_supported = 1,
508 
509 	.desc = {
510 		.sadb_alg_id = SADB_X_EALG_AESCTR,
511 		.sadb_alg_ivlen	= 8,
512 		.sadb_alg_minbits = 160,
513 		.sadb_alg_maxbits = 288
514 	}
515 },
516 };
517 
518 static struct xfrm_algo_desc calg_list[] = {
519 {
520 	.name = "deflate",
521 	.uinfo = {
522 		.comp = {
523 			.threshold = 90,
524 		}
525 	},
526 	.pfkey_supported = 1,
527 	.desc = { .sadb_alg_id = SADB_X_CALG_DEFLATE }
528 },
529 {
530 	.name = "lzs",
531 	.uinfo = {
532 		.comp = {
533 			.threshold = 90,
534 		}
535 	},
536 	.pfkey_supported = 1,
537 	.desc = { .sadb_alg_id = SADB_X_CALG_LZS }
538 },
539 {
540 	.name = "lzjh",
541 	.uinfo = {
542 		.comp = {
543 			.threshold = 50,
544 		}
545 	},
546 	.pfkey_supported = 1,
547 	.desc = { .sadb_alg_id = SADB_X_CALG_LZJH }
548 },
549 };
550 
551 static inline int aead_entries(void)
552 {
553 	return ARRAY_SIZE(aead_list);
554 }
555 
556 static inline int aalg_entries(void)
557 {
558 	return ARRAY_SIZE(aalg_list);
559 }
560 
561 static inline int ealg_entries(void)
562 {
563 	return ARRAY_SIZE(ealg_list);
564 }
565 
566 static inline int calg_entries(void)
567 {
568 	return ARRAY_SIZE(calg_list);
569 }
570 
571 struct xfrm_algo_list {
572 	struct xfrm_algo_desc *algs;
573 	int entries;
574 	u32 type;
575 	u32 mask;
576 };
577 
578 static const struct xfrm_algo_list xfrm_aead_list = {
579 	.algs = aead_list,
580 	.entries = ARRAY_SIZE(aead_list),
581 	.type = CRYPTO_ALG_TYPE_AEAD,
582 	.mask = CRYPTO_ALG_TYPE_MASK,
583 };
584 
585 static const struct xfrm_algo_list xfrm_aalg_list = {
586 	.algs = aalg_list,
587 	.entries = ARRAY_SIZE(aalg_list),
588 	.type = CRYPTO_ALG_TYPE_HASH,
589 	.mask = CRYPTO_ALG_TYPE_HASH_MASK,
590 };
591 
592 static const struct xfrm_algo_list xfrm_ealg_list = {
593 	.algs = ealg_list,
594 	.entries = ARRAY_SIZE(ealg_list),
595 	.type = CRYPTO_ALG_TYPE_BLKCIPHER,
596 	.mask = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
597 };
598 
599 static const struct xfrm_algo_list xfrm_calg_list = {
600 	.algs = calg_list,
601 	.entries = ARRAY_SIZE(calg_list),
602 	.type = CRYPTO_ALG_TYPE_COMPRESS,
603 	.mask = CRYPTO_ALG_TYPE_MASK,
604 };
605 
606 static struct xfrm_algo_desc *xfrm_find_algo(
607 	const struct xfrm_algo_list *algo_list,
608 	int match(const struct xfrm_algo_desc *entry, const void *data),
609 	const void *data, int probe)
610 {
611 	struct xfrm_algo_desc *list = algo_list->algs;
612 	int i, status;
613 
614 	for (i = 0; i < algo_list->entries; i++) {
615 		if (!match(list + i, data))
616 			continue;
617 
618 		if (list[i].available)
619 			return &list[i];
620 
621 		if (!probe)
622 			break;
623 
624 		status = crypto_has_alg(list[i].name, algo_list->type,
625 					algo_list->mask);
626 		if (!status)
627 			break;
628 
629 		list[i].available = status;
630 		return &list[i];
631 	}
632 	return NULL;
633 }
634 
635 static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
636 			     const void *data)
637 {
638 	return entry->desc.sadb_alg_id == (unsigned long)data;
639 }
640 
641 struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
642 {
643 	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
644 			      (void *)(unsigned long)alg_id, 1);
645 }
646 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
647 
648 struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
649 {
650 	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
651 			      (void *)(unsigned long)alg_id, 1);
652 }
653 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
654 
655 struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
656 {
657 	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
658 			      (void *)(unsigned long)alg_id, 1);
659 }
660 EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
661 
662 static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
663 			       const void *data)
664 {
665 	const char *name = data;
666 
667 	return name && (!strcmp(name, entry->name) ||
668 			(entry->compat && !strcmp(name, entry->compat)));
669 }
670 
671 struct xfrm_algo_desc *xfrm_aalg_get_byname(const char *name, int probe)
672 {
673 	return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
674 			      probe);
675 }
676 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
677 
678 struct xfrm_algo_desc *xfrm_ealg_get_byname(const char *name, int probe)
679 {
680 	return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
681 			      probe);
682 }
683 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
684 
685 struct xfrm_algo_desc *xfrm_calg_get_byname(const char *name, int probe)
686 {
687 	return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
688 			      probe);
689 }
690 EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
691 
692 struct xfrm_aead_name {
693 	const char *name;
694 	int icvbits;
695 };
696 
697 static int xfrm_aead_name_match(const struct xfrm_algo_desc *entry,
698 				const void *data)
699 {
700 	const struct xfrm_aead_name *aead = data;
701 	const char *name = aead->name;
702 
703 	return aead->icvbits == entry->uinfo.aead.icv_truncbits && name &&
704 	       !strcmp(name, entry->name);
705 }
706 
707 struct xfrm_algo_desc *xfrm_aead_get_byname(const char *name, int icv_len, int probe)
708 {
709 	struct xfrm_aead_name data = {
710 		.name = name,
711 		.icvbits = icv_len,
712 	};
713 
714 	return xfrm_find_algo(&xfrm_aead_list, xfrm_aead_name_match, &data,
715 			      probe);
716 }
717 EXPORT_SYMBOL_GPL(xfrm_aead_get_byname);
718 
719 struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx)
720 {
721 	if (idx >= aalg_entries())
722 		return NULL;
723 
724 	return &aalg_list[idx];
725 }
726 EXPORT_SYMBOL_GPL(xfrm_aalg_get_byidx);
727 
728 struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
729 {
730 	if (idx >= ealg_entries())
731 		return NULL;
732 
733 	return &ealg_list[idx];
734 }
735 EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
736 
737 /*
738  * Probe for the availability of crypto algorithms, and set the available
739  * flag for any algorithms found on the system.  This is typically called by
740  * pfkey during userspace SA add, update or register.
741  */
742 void xfrm_probe_algs(void)
743 {
744 	int i, status;
745 
746 	BUG_ON(in_softirq());
747 
748 	for (i = 0; i < aalg_entries(); i++) {
749 		status = crypto_has_hash(aalg_list[i].name, 0,
750 					 CRYPTO_ALG_ASYNC);
751 		if (aalg_list[i].available != status)
752 			aalg_list[i].available = status;
753 	}
754 
755 	for (i = 0; i < ealg_entries(); i++) {
756 		status = crypto_has_ablkcipher(ealg_list[i].name, 0, 0);
757 		if (ealg_list[i].available != status)
758 			ealg_list[i].available = status;
759 	}
760 
761 	for (i = 0; i < calg_entries(); i++) {
762 		status = crypto_has_comp(calg_list[i].name, 0,
763 					 CRYPTO_ALG_ASYNC);
764 		if (calg_list[i].available != status)
765 			calg_list[i].available = status;
766 	}
767 }
768 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
769 
770 int xfrm_count_pfkey_auth_supported(void)
771 {
772 	int i, n;
773 
774 	for (i = 0, n = 0; i < aalg_entries(); i++)
775 		if (aalg_list[i].available && aalg_list[i].pfkey_supported)
776 			n++;
777 	return n;
778 }
779 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_auth_supported);
780 
781 int xfrm_count_pfkey_enc_supported(void)
782 {
783 	int i, n;
784 
785 	for (i = 0, n = 0; i < ealg_entries(); i++)
786 		if (ealg_list[i].available && ealg_list[i].pfkey_supported)
787 			n++;
788 	return n;
789 }
790 EXPORT_SYMBOL_GPL(xfrm_count_pfkey_enc_supported);
791 
792 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
793 
794 void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len)
795 {
796 	if (tail != skb) {
797 		skb->data_len += len;
798 		skb->len += len;
799 	}
800 	return skb_put(tail, len);
801 }
802 EXPORT_SYMBOL_GPL(pskb_put);
803 #endif
804 
805 MODULE_LICENSE("GPL");
806