0001
0002
0003
0004
0005
0006
0007 #include <linux/types.h>
0008 #include <linux/netfilter.h>
0009 #include <linux/skbuff.h>
0010 #include <linux/vmalloc.h>
0011 #include <linux/stddef.h>
0012 #include <linux/err.h>
0013 #include <linux/percpu.h>
0014 #include <linux/kernel.h>
0015 #include <linux/netdevice.h>
0016 #include <linux/slab.h>
0017 #include <linux/export.h>
0018
0019 #include <net/netfilter/nf_conntrack.h>
0020 #include <net/netfilter/nf_conntrack_core.h>
0021 #include <net/netfilter/nf_conntrack_extend.h>
0022 #include <net/netfilter/nf_conntrack_l4proto.h>
0023 #include <net/netfilter/nf_conntrack_timeout.h>
0024
0025 const struct nf_ct_timeout_hooks __rcu *nf_ct_timeout_hook __read_mostly;
0026 EXPORT_SYMBOL_GPL(nf_ct_timeout_hook);
0027
0028 static int untimeout(struct nf_conn *ct, void *timeout)
0029 {
0030 struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct);
0031
0032 if (timeout_ext) {
0033 const struct nf_ct_timeout *t;
0034
0035 t = rcu_access_pointer(timeout_ext->timeout);
0036
0037 if (!timeout || t == timeout)
0038 RCU_INIT_POINTER(timeout_ext->timeout, NULL);
0039 }
0040
0041
0042 return 0;
0043 }
0044
0045 void nf_ct_untimeout(struct net *net, struct nf_ct_timeout *timeout)
0046 {
0047 struct nf_ct_iter_data iter_data = {
0048 .net = net,
0049 .data = timeout,
0050 };
0051
0052 nf_ct_iterate_cleanup_net(untimeout, &iter_data);
0053 }
0054 EXPORT_SYMBOL_GPL(nf_ct_untimeout);
0055
0056 static void __nf_ct_timeout_put(struct nf_ct_timeout *timeout)
0057 {
0058 const struct nf_ct_timeout_hooks *h = rcu_dereference(nf_ct_timeout_hook);
0059
0060 if (h)
0061 h->timeout_put(timeout);
0062 }
0063
0064 int nf_ct_set_timeout(struct net *net, struct nf_conn *ct,
0065 u8 l3num, u8 l4num, const char *timeout_name)
0066 {
0067 const struct nf_ct_timeout_hooks *h;
0068 struct nf_ct_timeout *timeout;
0069 struct nf_conn_timeout *timeout_ext;
0070 const char *errmsg = NULL;
0071 int ret = 0;
0072
0073 rcu_read_lock();
0074 h = rcu_dereference(nf_ct_timeout_hook);
0075 if (!h) {
0076 ret = -ENOENT;
0077 errmsg = "Timeout policy base is empty";
0078 goto out;
0079 }
0080
0081 timeout = h->timeout_find_get(net, timeout_name);
0082 if (!timeout) {
0083 ret = -ENOENT;
0084 pr_info_ratelimited("No such timeout policy \"%s\"\n",
0085 timeout_name);
0086 goto out;
0087 }
0088
0089 if (timeout->l3num != l3num) {
0090 ret = -EINVAL;
0091 pr_info_ratelimited("Timeout policy `%s' can only be used by "
0092 "L%d protocol number %d\n",
0093 timeout_name, 3, timeout->l3num);
0094 goto err_put_timeout;
0095 }
0096
0097
0098
0099 if (timeout->l4proto->l4proto != l4num) {
0100 ret = -EINVAL;
0101 pr_info_ratelimited("Timeout policy `%s' can only be used by "
0102 "L%d protocol number %d\n",
0103 timeout_name, 4, timeout->l4proto->l4proto);
0104 goto err_put_timeout;
0105 }
0106 timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
0107 if (!timeout_ext) {
0108 ret = -ENOMEM;
0109 goto err_put_timeout;
0110 }
0111
0112 rcu_read_unlock();
0113 return ret;
0114
0115 err_put_timeout:
0116 __nf_ct_timeout_put(timeout);
0117 out:
0118 rcu_read_unlock();
0119 if (errmsg)
0120 pr_info_ratelimited("%s\n", errmsg);
0121 return ret;
0122 }
0123 EXPORT_SYMBOL_GPL(nf_ct_set_timeout);
0124
0125 void nf_ct_destroy_timeout(struct nf_conn *ct)
0126 {
0127 struct nf_conn_timeout *timeout_ext;
0128 const struct nf_ct_timeout_hooks *h;
0129
0130 rcu_read_lock();
0131 h = rcu_dereference(nf_ct_timeout_hook);
0132
0133 if (h) {
0134 timeout_ext = nf_ct_timeout_find(ct);
0135 if (timeout_ext) {
0136 struct nf_ct_timeout *t;
0137
0138 t = rcu_dereference(timeout_ext->timeout);
0139 if (t)
0140 h->timeout_put(t);
0141 RCU_INIT_POINTER(timeout_ext->timeout, NULL);
0142 }
0143 }
0144 rcu_read_unlock();
0145 }
0146 EXPORT_SYMBOL_GPL(nf_ct_destroy_timeout);