int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) { int ret = 0; if (proto->l3proto >= AF_MAX) { ret = -EBUSY; goto out; } write_lock_bh(&nf_conntrack_lock); if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) { ret = -EBUSY; goto out_unlock; } nf_ct_l3protos[proto->l3proto] = proto; write_unlock_bh(&nf_conntrack_lock); ret = nf_ct_l3proto_register_sysctl(proto); if (ret < 0) nf_conntrack_l3proto_unregister(proto); return ret; out_unlock: write_unlock_bh(&nf_conntrack_lock); out: return ret; }
static int __init nf_conntrack_l3proto_ipv6_init(void) { int ret = 0; need_conntrack(); ret = nf_ct_frag6_init(); if (ret < 0) { printk("nf_conntrack_ipv6: can't initialize frag6.\n"); return ret; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register tcp.\n"); goto cleanup_frag6; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register udp.\n"); goto cleanup_tcp; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register icmpv6.\n"); goto cleanup_udp; } ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register ipv6\n"); goto cleanup_icmpv6; } ret = nf_register_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); if (ret < 0) { printk("nf_conntrack_ipv6: can't register pre-routing defrag " "hook.\n"); goto cleanup_ipv6; } return ret; cleanup_ipv6: nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); cleanup_icmpv6: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); cleanup_udp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); cleanup_tcp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); cleanup_frag6: nf_ct_frag6_cleanup(); return ret; }
static void __exit nf_conntrack_l3proto_ipv6_fini(void) { synchronize_net(); nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); nf_ct_frag6_cleanup(); }
static void ipv4_net_exit(struct net *net) { nf_conntrack_l3proto_unregister(net, &nf_conntrack_l3proto_ipv4); nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_icmp); nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_udp4); nf_conntrack_l4proto_unregister(net, &nf_conntrack_l4proto_tcp4); }
static void __exit nf_conntrack_l3proto_ipv4_fini(void) { synchronize_net(); #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) nf_conntrack_ipv4_compat_fini(); #endif nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4); nf_unregister_sockopt(&so_getorigdst); }
static int __init nf_conntrack_l3proto_ipv4_init(void) { int ret = 0; need_conntrack(); nf_defrag_ipv4_enable(); ret = nf_register_sockopt(&so_getorigdst); if (ret < 0) { printk(KERN_ERR "Unable to register netfilter socket option\n"); return ret; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register tcp.\n"); goto cleanup_sockopt; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register udp.\n"); goto cleanup_tcp; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register icmp.\n"); goto cleanup_udp; } ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv4); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register ipv4\n"); goto cleanup_icmp; } ret = nf_register_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); if (ret < 0) { pr_err("nf_conntrack_ipv4: can't register hooks.\n"); goto cleanup_ipv4; } #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) ret = nf_conntrack_ipv4_compat_init(); if (ret < 0) goto cleanup_hooks; #endif return ret; #if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) cleanup_hooks: nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); #endif cleanup_ipv4: nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); cleanup_icmp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp); cleanup_udp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4); cleanup_tcp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4); cleanup_sockopt: nf_unregister_sockopt(&so_getorigdst); return ret; }
static int init_or_cleanup(int init) { int ret = 0; if (!init) goto cleanup; ret = nf_ct_frag6_init(); if (ret < 0) { printk("nf_conntrack_ipv6: can't initialize frag6.\n"); goto cleanup_nothing; } ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register tcp.\n"); goto cleanup_frag6; } ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register udp.\n"); goto cleanup_tcp; } ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmpv6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register icmpv6.\n"); goto cleanup_udp; } ret = nf_conntrack_l3proto_register(&nf_conntrack_l3proto_ipv6); if (ret < 0) { printk("nf_conntrack_ipv6: can't register ipv6\n"); goto cleanup_icmpv6; } ret = nf_register_hook(&ipv6_conntrack_defrag_ops); if (ret < 0) { printk("nf_conntrack_ipv6: can't register pre-routing defrag " "hook.\n"); goto cleanup_ipv6; } ret = nf_register_hook(&ipv6_conntrack_defrag_local_out_ops); if (ret < 0) { printk("nf_conntrack_ipv6: can't register local_out defrag " "hook.\n"); goto cleanup_defragops; } ret = nf_register_hook(&ipv6_conntrack_in_ops); if (ret < 0) { printk("nf_conntrack_ipv6: can't register pre-routing hook.\n"); goto cleanup_defraglocalops; } ret = nf_register_hook(&ipv6_conntrack_local_out_ops); if (ret < 0) { printk("nf_conntrack_ipv6: can't register local out hook.\n"); goto cleanup_inops; } ret = nf_register_hook(&ipv6_conntrack_out_ops); if (ret < 0) { printk("nf_conntrack_ipv6: can't register post-routing hook.\n"); goto cleanup_inandlocalops; } ret = nf_register_hook(&ipv6_conntrack_local_in_ops); if (ret < 0) { printk("nf_conntrack_ipv6: can't register local in hook.\n"); goto cleanup_inoutandlocalops; } #ifdef CONFIG_SYSCTL nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); if (nf_ct_ipv6_sysctl_header == NULL) { printk("nf_conntrack: can't register to sysctl.\n"); ret = -ENOMEM; goto cleanup_localinops; } #endif return ret; cleanup: synchronize_net(); #ifdef CONFIG_SYSCTL unregister_sysctl_table(nf_ct_ipv6_sysctl_header); cleanup_localinops: #endif nf_unregister_hook(&ipv6_conntrack_local_in_ops); cleanup_inoutandlocalops: nf_unregister_hook(&ipv6_conntrack_out_ops); cleanup_inandlocalops: nf_unregister_hook(&ipv6_conntrack_local_out_ops); cleanup_inops: nf_unregister_hook(&ipv6_conntrack_in_ops); cleanup_defraglocalops: nf_unregister_hook(&ipv6_conntrack_defrag_local_out_ops); cleanup_defragops: nf_unregister_hook(&ipv6_conntrack_defrag_ops); cleanup_ipv6: nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); cleanup_icmpv6: nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6); cleanup_udp: nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6); cleanup_tcp: nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); cleanup_frag6: nf_ct_frag6_cleanup(); cleanup_nothing: return ret; }