diff options
| author | Balazs Scheidler <bazsi@balabit.hu> | 2010-10-21 10:03:43 -0400 |
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-10-21 10:03:43 -0400 |
| commit | e97c3e278e951501c2f385de70c3ceacdea78c4a (patch) | |
| tree | 1794d174ef487cff2ff135f8ca4c795c847f41ed | |
| parent | 093d282321daeb19c107e5f1f16d7f68484f3ade (diff) | |
tproxy: split off ipv6 defragmentation to a separate module
Like with IPv4, TProxy needs IPv6 defragmentation but does not
require connection tracking. Since defragmentation was coupled
with conntrack, I split off the two, creating an nf_defrag_ipv6 module,
similar to the already existing nf_defrag_ipv4.
Signed-off-by: Balazs Scheidler <bazsi@balabit.hu>
Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
| -rw-r--r-- | include/net/netfilter/ipv6/nf_defrag_ipv6.h | 6 | ||||
| -rw-r--r-- | net/ipv6/netfilter/Makefile | 5 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 78 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 14 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 131 |
5 files changed, 156 insertions, 78 deletions
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h new file mode 100644 index 000000000000..94dd54d76b48 --- /dev/null +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #ifndef _NF_DEFRAG_IPV6_H | ||
| 2 | #define _NF_DEFRAG_IPV6_H | ||
| 3 | |||
| 4 | extern void nf_defrag_ipv6_enable(void); | ||
| 5 | |||
| 6 | #endif /* _NF_DEFRAG_IPV6_H */ | ||
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index aafbba30c899..3f8e4a3d83ce 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
| @@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o | |||
| 11 | obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o | 11 | obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o |
| 12 | 12 | ||
| 13 | # objects for l3 independent conntrack | 13 | # objects for l3 independent conntrack |
| 14 | nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o | 14 | nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o |
| 15 | nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o | ||
| 15 | 16 | ||
| 16 | # l3 independent conntrack | 17 | # l3 independent conntrack |
| 17 | obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o | 18 | obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o |
| 18 | 19 | ||
| 19 | # matches | 20 | # matches |
| 20 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o | 21 | obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ff43461704be..c8af58b22562 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
| 18 | #include <linux/icmp.h> | 18 | #include <linux/icmp.h> |
| 19 | #include <linux/sysctl.h> | ||
| 20 | #include <net/ipv6.h> | 19 | #include <net/ipv6.h> |
| 21 | #include <net/inet_frag.h> | 20 | #include <net/inet_frag.h> |
| 22 | 21 | ||
| @@ -29,6 +28,7 @@ | |||
| 29 | #include <net/netfilter/nf_conntrack_core.h> | 28 | #include <net/netfilter/nf_conntrack_core.h> |
| 30 | #include <net/netfilter/nf_conntrack_zones.h> | 29 | #include <net/netfilter/nf_conntrack_zones.h> |
| 31 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> | 30 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> |
| 31 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> | ||
| 32 | #include <net/netfilter/nf_log.h> | 32 | #include <net/netfilter/nf_log.h> |
| 33 | 33 | ||
| 34 | static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, | 34 | static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, |
| @@ -189,53 +189,6 @@ out: | |||
| 189 | return nf_conntrack_confirm(skb); | 189 | return nf_conntrack_confirm(skb); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | ||
| 193 | struct sk_buff *skb) | ||
| 194 | { | ||
| 195 | u16 zone = NF_CT_DEFAULT_ZONE; | ||
| 196 | |||
| 197 | if (skb->nfct) | ||
| 198 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); | ||
| 199 | |||
| 200 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
| 201 | if (skb->nf_bridge && | ||
| 202 | skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) | ||
| 203 | return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; | ||
| 204 | #endif | ||
| 205 | if (hooknum == NF_INET_PRE_ROUTING) | ||
| 206 | return IP6_DEFRAG_CONNTRACK_IN + zone; | ||
| 207 | else | ||
| 208 | return IP6_DEFRAG_CONNTRACK_OUT + zone; | ||
| 209 | |||
| 210 | } | ||
| 211 | |||
| 212 | static unsigned int ipv6_defrag(unsigned int hooknum, | ||
| 213 | struct sk_buff *skb, | ||
| 214 | const struct net_device *in, | ||
| 215 | const struct net_device *out, | ||
| 216 | int (*okfn)(struct sk_buff *)) | ||
| 217 | { | ||
| 218 | struct sk_buff *reasm; | ||
| 219 | |||
| 220 | /* Previously seen (loopback)? */ | ||
| 221 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) | ||
| 222 | return NF_ACCEPT; | ||
| 223 | |||
| 224 | reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); | ||
| 225 | /* queued */ | ||
| 226 | if (reasm == NULL) | ||
| 227 | return NF_STOLEN; | ||
| 228 | |||
| 229 | /* error occured or not fragmented */ | ||
| 230 | if (reasm == skb) | ||
| 231 | return NF_ACCEPT; | ||
| 232 | |||
| 233 | nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in, | ||
| 234 | (struct net_device *)out, okfn); | ||
| 235 | |||
| 236 | return NF_STOLEN; | ||
| 237 | } | ||
| 238 | |||
| 239 | static unsigned int __ipv6_conntrack_in(struct net *net, | 192 | static unsigned int __ipv6_conntrack_in(struct net *net, |
| 240 | unsigned int hooknum, | 193 | unsigned int hooknum, |
| 241 | struct sk_buff *skb, | 194 | struct sk_buff *skb, |
| @@ -288,13 +241,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum, | |||
| 288 | 241 | ||
| 289 | static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { | 242 | static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { |
| 290 | { | 243 | { |
| 291 | .hook = ipv6_defrag, | ||
| 292 | .owner = THIS_MODULE, | ||
| 293 | .pf = NFPROTO_IPV6, | ||
| 294 | .hooknum = NF_INET_PRE_ROUTING, | ||
| 295 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, | ||
| 296 | }, | ||
| 297 | { | ||
| 298 | .hook = ipv6_conntrack_in, | 244 | .hook = ipv6_conntrack_in, |
| 299 | .owner = THIS_MODULE, | 245 | .owner = THIS_MODULE, |
| 300 | .pf = NFPROTO_IPV6, | 246 | .pf = NFPROTO_IPV6, |
| @@ -309,13 +255,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { | |||
| 309 | .priority = NF_IP6_PRI_CONNTRACK, | 255 | .priority = NF_IP6_PRI_CONNTRACK, |
| 310 | }, | 256 | }, |
| 311 | { | 257 | { |
| 312 | .hook = ipv6_defrag, | ||
| 313 | .owner = THIS_MODULE, | ||
| 314 | .pf = NFPROTO_IPV6, | ||
| 315 | .hooknum = NF_INET_LOCAL_OUT, | ||
| 316 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, | ||
| 317 | }, | ||
| 318 | { | ||
| 319 | .hook = ipv6_confirm, | 258 | .hook = ipv6_confirm, |
| 320 | .owner = THIS_MODULE, | 259 | .owner = THIS_MODULE, |
| 321 | .pf = NFPROTO_IPV6, | 260 | .pf = NFPROTO_IPV6, |
| @@ -387,10 +326,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { | |||
| 387 | .nlattr_to_tuple = ipv6_nlattr_to_tuple, | 326 | .nlattr_to_tuple = ipv6_nlattr_to_tuple, |
| 388 | .nla_policy = ipv6_nla_policy, | 327 | .nla_policy = ipv6_nla_policy, |
| 389 | #endif | 328 | #endif |
| 390 | #ifdef CONFIG_SYSCTL | ||
| 391 | .ctl_table_path = nf_net_netfilter_sysctl_path, | ||
| 392 | .ctl_table = nf_ct_ipv6_sysctl_table, | ||
| 393 | #endif | ||
| 394 | .me = THIS_MODULE, | 329 | .me = THIS_MODULE, |
| 395 | }; | 330 | }; |
| 396 | 331 | ||
| @@ -403,16 +338,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) | |||
| 403 | int ret = 0; | 338 | int ret = 0; |
| 404 | 339 | ||
| 405 | need_conntrack(); | 340 | need_conntrack(); |
| 341 | nf_defrag_ipv6_enable(); | ||
| 406 | 342 | ||
| 407 | ret = nf_ct_frag6_init(); | ||
| 408 | if (ret < 0) { | ||
| 409 | pr_err("nf_conntrack_ipv6: can't initialize frag6.\n"); | ||
| 410 | return ret; | ||
| 411 | } | ||
| 412 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); | 343 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); |
| 413 | if (ret < 0) { | 344 | if (ret < 0) { |
| 414 | pr_err("nf_conntrack_ipv6: can't register tcp.\n"); | 345 | pr_err("nf_conntrack_ipv6: can't register tcp.\n"); |
| 415 | goto cleanup_frag6; | 346 | return ret; |
| 416 | } | 347 | } |
| 417 | 348 | ||
| 418 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); | 349 | ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); |
| @@ -450,8 +381,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) | |||
| 450 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); | 381 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); |
| 451 | cleanup_tcp: | 382 | cleanup_tcp: |
| 452 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); | 383 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); |
| 453 | cleanup_frag6: | ||
| 454 | nf_ct_frag6_cleanup(); | ||
| 455 | return ret; | 384 | return ret; |
| 456 | } | 385 | } |
| 457 | 386 | ||
| @@ -463,7 +392,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) | |||
| 463 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); | 392 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); |
| 464 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); | 393 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); |
| 465 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); | 394 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); |
| 466 | nf_ct_frag6_cleanup(); | ||
| 467 | } | 395 | } |
| 468 | 396 | ||
| 469 | module_init(nf_conntrack_l3proto_ipv6_init); | 397 | module_init(nf_conntrack_l3proto_ipv6_init); |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 138a8b362706..489d71b844ac 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -73,7 +73,7 @@ static struct inet_frags nf_frags; | |||
| 73 | static struct netns_frags nf_init_frags; | 73 | static struct netns_frags nf_init_frags; |
| 74 | 74 | ||
| 75 | #ifdef CONFIG_SYSCTL | 75 | #ifdef CONFIG_SYSCTL |
| 76 | struct ctl_table nf_ct_ipv6_sysctl_table[] = { | 76 | struct ctl_table nf_ct_frag6_sysctl_table[] = { |
| 77 | { | 77 | { |
| 78 | .procname = "nf_conntrack_frag6_timeout", | 78 | .procname = "nf_conntrack_frag6_timeout", |
| 79 | .data = &nf_init_frags.timeout, | 79 | .data = &nf_init_frags.timeout, |
| @@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { | |||
| 97 | }, | 97 | }, |
| 98 | { } | 98 | { } |
| 99 | }; | 99 | }; |
| 100 | |||
| 101 | static struct ctl_table_header *nf_ct_frag6_sysctl_header; | ||
| 100 | #endif | 102 | #endif |
| 101 | 103 | ||
| 102 | static unsigned int nf_hashfn(struct inet_frag_queue *q) | 104 | static unsigned int nf_hashfn(struct inet_frag_queue *q) |
| @@ -623,11 +625,21 @@ int nf_ct_frag6_init(void) | |||
| 623 | inet_frags_init_net(&nf_init_frags); | 625 | inet_frags_init_net(&nf_init_frags); |
| 624 | inet_frags_init(&nf_frags); | 626 | inet_frags_init(&nf_frags); |
| 625 | 627 | ||
| 628 | nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, | ||
| 629 | nf_ct_frag6_sysctl_table); | ||
| 630 | if (!nf_ct_frag6_sysctl_header) { | ||
| 631 | inet_frags_fini(&nf_frags); | ||
| 632 | return -ENOMEM; | ||
| 633 | } | ||
| 634 | |||
| 626 | return 0; | 635 | return 0; |
| 627 | } | 636 | } |
| 628 | 637 | ||
| 629 | void nf_ct_frag6_cleanup(void) | 638 | void nf_ct_frag6_cleanup(void) |
| 630 | { | 639 | { |
| 640 | unregister_sysctl_table(nf_ct_frag6_sysctl_header); | ||
| 641 | nf_ct_frag6_sysctl_header = NULL; | ||
| 642 | |||
| 631 | inet_frags_fini(&nf_frags); | 643 | inet_frags_fini(&nf_frags); |
| 632 | 644 | ||
| 633 | nf_init_frags.low_thresh = 0; | 645 | nf_init_frags.low_thresh = 0; |
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c new file mode 100644 index 000000000000..99abfb53bab9 --- /dev/null +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
| 2 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/ipv6.h> | ||
| 11 | #include <linux/in6.h> | ||
| 12 | #include <linux/netfilter.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/skbuff.h> | ||
| 15 | #include <linux/icmp.h> | ||
| 16 | #include <linux/sysctl.h> | ||
| 17 | #include <net/ipv6.h> | ||
| 18 | #include <net/inet_frag.h> | ||
| 19 | |||
| 20 | #include <linux/netfilter_ipv6.h> | ||
| 21 | #include <linux/netfilter_bridge.h> | ||
| 22 | #include <net/netfilter/nf_conntrack.h> | ||
| 23 | #include <net/netfilter/nf_conntrack_helper.h> | ||
| 24 | #include <net/netfilter/nf_conntrack_l4proto.h> | ||
| 25 | #include <net/netfilter/nf_conntrack_l3proto.h> | ||
| 26 | #include <net/netfilter/nf_conntrack_core.h> | ||
| 27 | #include <net/netfilter/nf_conntrack_zones.h> | ||
| 28 | #include <net/netfilter/ipv6/nf_conntrack_ipv6.h> | ||
| 29 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> | ||
| 30 | |||
| 31 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, | ||
| 32 | struct sk_buff *skb) | ||
| 33 | { | ||
| 34 | u16 zone = NF_CT_DEFAULT_ZONE; | ||
| 35 | |||
| 36 | if (skb->nfct) | ||
| 37 | zone = nf_ct_zone((struct nf_conn *)skb->nfct); | ||
| 38 | |||
| 39 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
| 40 | if (skb->nf_bridge && | ||
| 41 | skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) | ||
| 42 | return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; | ||
| 43 | #endif | ||
| 44 | if (hooknum == NF_INET_PRE_ROUTING) | ||
| 45 | return IP6_DEFRAG_CONNTRACK_IN + zone; | ||
| 46 | else | ||
| 47 | return IP6_DEFRAG_CONNTRACK_OUT + zone; | ||
| 48 | |||
| 49 | } | ||
| 50 | |||
| 51 | static unsigned int ipv6_defrag(unsigned int hooknum, | ||
| 52 | struct sk_buff *skb, | ||
| 53 | const struct net_device *in, | ||
| 54 | const struct net_device *out, | ||
| 55 | int (*okfn)(struct sk_buff *)) | ||
| 56 | { | ||
| 57 | struct sk_buff *reasm; | ||
| 58 | |||
| 59 | /* Previously seen (loopback)? */ | ||
| 60 | if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) | ||
| 61 | return NF_ACCEPT; | ||
| 62 | |||
| 63 | reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); | ||
| 64 | /* queued */ | ||
| 65 | if (reasm == NULL) | ||
| 66 | return NF_STOLEN; | ||
| 67 | |||
| 68 | /* error occured or not fragmented */ | ||
| 69 | if (reasm == skb) | ||
| 70 | return NF_ACCEPT; | ||
| 71 | |||
| 72 | nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in, | ||
| 73 | (struct net_device *)out, okfn); | ||
| 74 | |||
| 75 | return NF_STOLEN; | ||
| 76 | } | ||
| 77 | |||
| 78 | static struct nf_hook_ops ipv6_defrag_ops[] = { | ||
| 79 | { | ||
| 80 | .hook = ipv6_defrag, | ||
| 81 | .owner = THIS_MODULE, | ||
| 82 | .pf = NFPROTO_IPV6, | ||
| 83 | .hooknum = NF_INET_PRE_ROUTING, | ||
| 84 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, | ||
| 85 | }, | ||
| 86 | { | ||
| 87 | .hook = ipv6_defrag, | ||
| 88 | .owner = THIS_MODULE, | ||
| 89 | .pf = NFPROTO_IPV6, | ||
| 90 | .hooknum = NF_INET_LOCAL_OUT, | ||
| 91 | .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, | ||
| 92 | }, | ||
| 93 | }; | ||
| 94 | |||
| 95 | static int __init nf_defrag_init(void) | ||
| 96 | { | ||
| 97 | int ret = 0; | ||
| 98 | |||
| 99 | ret = nf_ct_frag6_init(); | ||
| 100 | if (ret < 0) { | ||
| 101 | pr_err("nf_defrag_ipv6: can't initialize frag6.\n"); | ||
| 102 | return ret; | ||
| 103 | } | ||
| 104 | ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops)); | ||
| 105 | if (ret < 0) { | ||
| 106 | pr_err("nf_defrag_ipv6: can't register hooks\n"); | ||
| 107 | goto cleanup_frag6; | ||
| 108 | } | ||
| 109 | return ret; | ||
| 110 | |||
| 111 | cleanup_frag6: | ||
| 112 | nf_ct_frag6_cleanup(); | ||
| 113 | return ret; | ||
| 114 | |||
| 115 | } | ||
| 116 | |||
| 117 | static void __exit nf_defrag_fini(void) | ||
| 118 | { | ||
| 119 | nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops)); | ||
| 120 | nf_ct_frag6_cleanup(); | ||
| 121 | } | ||
| 122 | |||
| 123 | void nf_defrag_ipv6_enable(void) | ||
| 124 | { | ||
| 125 | } | ||
| 126 | EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); | ||
| 127 | |||
| 128 | module_init(nf_defrag_init); | ||
| 129 | module_exit(nf_defrag_fini); | ||
| 130 | |||
| 131 | MODULE_LICENSE("GPL"); | ||
