|
|
@@ -281,15 +281,15 @@ void nf_ct_l4proto_unregister_sysctl(struct net *net,
|
|
|
|
|
|
/* FIXME: Allow NULL functions and sub in pointers to generic for
|
|
|
them. --RR */
|
|
|
-int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto)
|
|
|
+int nf_ct_l4proto_register_one(struct nf_conntrack_l4proto *l4proto)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
|
|
|
if (l4proto->l3proto >= PF_MAX)
|
|
|
return -EBUSY;
|
|
|
|
|
|
- if ((l4proto->to_nlattr && !l4proto->nlattr_size)
|
|
|
- || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
|
|
|
+ if ((l4proto->to_nlattr && !l4proto->nlattr_size) ||
|
|
|
+ (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
|
|
|
return -EINVAL;
|
|
|
|
|
|
mutex_lock(&nf_ct_proto_mutex);
|
|
|
@@ -307,7 +307,8 @@ int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto)
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < MAX_NF_CT_PROTO; i++)
|
|
|
- RCU_INIT_POINTER(proto_array[i], &nf_conntrack_l4proto_generic);
|
|
|
+ RCU_INIT_POINTER(proto_array[i],
|
|
|
+ &nf_conntrack_l4proto_generic);
|
|
|
|
|
|
/* Before making proto_array visible to lockless readers,
|
|
|
* we must make sure its content is committed to memory.
|
|
|
@@ -335,10 +336,10 @@ out_unlock:
|
|
|
mutex_unlock(&nf_ct_proto_mutex);
|
|
|
return ret;
|
|
|
}
|
|
|
-EXPORT_SYMBOL_GPL(nf_ct_l4proto_register);
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_register_one);
|
|
|
|
|
|
-int nf_ct_l4proto_pernet_register(struct net *net,
|
|
|
- struct nf_conntrack_l4proto *l4proto)
|
|
|
+int nf_ct_l4proto_pernet_register_one(struct net *net,
|
|
|
+ struct nf_conntrack_l4proto *l4proto)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
struct nf_proto_net *pn = NULL;
|
|
|
@@ -361,9 +362,9 @@ int nf_ct_l4proto_pernet_register(struct net *net,
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|
|
|
-EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register);
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register_one);
|
|
|
|
|
|
-void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
|
|
|
+void nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *l4proto)
|
|
|
{
|
|
|
BUG_ON(l4proto->l3proto >= PF_MAX);
|
|
|
|
|
|
@@ -378,10 +379,10 @@ void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
|
|
|
|
|
|
synchronize_rcu();
|
|
|
}
|
|
|
-EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister);
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister_one);
|
|
|
|
|
|
-void nf_ct_l4proto_pernet_unregister(struct net *net,
|
|
|
- struct nf_conntrack_l4proto *l4proto)
|
|
|
+void nf_ct_l4proto_pernet_unregister_one(struct net *net,
|
|
|
+ struct nf_conntrack_l4proto *l4proto)
|
|
|
{
|
|
|
struct nf_proto_net *pn = NULL;
|
|
|
|
|
|
@@ -395,6 +396,66 @@ void nf_ct_l4proto_pernet_unregister(struct net *net,
|
|
|
/* Remove all contrack entries for this protocol */
|
|
|
nf_ct_iterate_cleanup(net, kill_l4proto, l4proto, 0, 0);
|
|
|
}
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister_one);
|
|
|
+
|
|
|
+int nf_ct_l4proto_register(struct nf_conntrack_l4proto *l4proto[],
|
|
|
+ unsigned int num_proto)
|
|
|
+{
|
|
|
+ int ret = -EINVAL, ver;
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
+ for (i = 0; i < num_proto; i++) {
|
|
|
+ ret = nf_ct_l4proto_register_one(l4proto[i]);
|
|
|
+ if (ret < 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (i != num_proto) {
|
|
|
+ ver = l4proto[i]->l3proto == PF_INET6 ? 6 : 4;
|
|
|
+ pr_err("nf_conntrack_ipv%d: can't register %s%d proto.\n",
|
|
|
+ ver, l4proto[i]->name, ver);
|
|
|
+ nf_ct_l4proto_unregister(l4proto, i);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_register);
|
|
|
+
|
|
|
+int nf_ct_l4proto_pernet_register(struct net *net,
|
|
|
+ struct nf_conntrack_l4proto *l4proto[],
|
|
|
+ unsigned int num_proto)
|
|
|
+{
|
|
|
+ int ret = -EINVAL;
|
|
|
+ unsigned int i;
|
|
|
+
|
|
|
+ for (i = 0; i < num_proto; i++) {
|
|
|
+ ret = nf_ct_l4proto_pernet_register_one(net, l4proto[i]);
|
|
|
+ if (ret < 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (i != num_proto) {
|
|
|
+ pr_err("nf_conntrack_%s%d: pernet registration failed\n",
|
|
|
+ l4proto[i]->name,
|
|
|
+ l4proto[i]->l3proto == PF_INET6 ? 6 : 4);
|
|
|
+ nf_ct_l4proto_pernet_unregister(net, l4proto, i);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_register);
|
|
|
+
|
|
|
+void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *l4proto[],
|
|
|
+ unsigned int num_proto)
|
|
|
+{
|
|
|
+ while (num_proto-- != 0)
|
|
|
+ nf_ct_l4proto_unregister_one(l4proto[num_proto]);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(nf_ct_l4proto_unregister);
|
|
|
+
|
|
|
+void nf_ct_l4proto_pernet_unregister(struct net *net,
|
|
|
+ struct nf_conntrack_l4proto *l4proto[],
|
|
|
+ unsigned int num_proto)
|
|
|
+{
|
|
|
+ while (num_proto-- != 0)
|
|
|
+ nf_ct_l4proto_pernet_unregister_one(net, l4proto[num_proto]);
|
|
|
+}
|
|
|
EXPORT_SYMBOL_GPL(nf_ct_l4proto_pernet_unregister);
|
|
|
|
|
|
int nf_conntrack_proto_pernet_init(struct net *net)
|