1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _NF_CONNTRACK_TIMEOUT_H 3 #define _NF_CONNTRACK_TIMEOUT_H 4 5 #include <net/net_namespace.h> 6 #include <linux/netfilter/nf_conntrack_common.h> 7 #include <linux/netfilter/nf_conntrack_tuple_common.h> 8 #include <linux/refcount.h> 9 #include <net/netfilter/nf_conntrack.h> 10 #include <net/netfilter/nf_conntrack_extend.h> 11 12 #define CTNL_TIMEOUT_NAME_MAX 32 13 14 struct nf_ct_timeout { 15 __u16 l3num; 16 const struct nf_conntrack_l4proto *l4proto; 17 char data[]; 18 }; 19 20 struct nf_conn_timeout { 21 struct nf_ct_timeout __rcu *timeout; 22 }; 23 24 static inline unsigned int * nf_ct_timeout_data(const struct nf_conn_timeout * t)25 nf_ct_timeout_data(const struct nf_conn_timeout *t) 26 { 27 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 28 struct nf_ct_timeout *timeout; 29 30 timeout = rcu_dereference(t->timeout); 31 if (timeout == NULL) 32 return NULL; 33 34 return (unsigned int *)timeout->data; 35 #else 36 return NULL; 37 #endif 38 } 39 40 static inline nf_ct_timeout_find(const struct nf_conn * ct)41 struct nf_conn_timeout *nf_ct_timeout_find(const struct nf_conn *ct) 42 { 43 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 44 return nf_ct_ext_find(ct, NF_CT_EXT_TIMEOUT); 45 #else 46 return NULL; 47 #endif 48 } 49 50 static inline nf_ct_timeout_ext_add(struct nf_conn * ct,struct nf_ct_timeout * timeout,gfp_t gfp)51 struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct, 52 struct nf_ct_timeout *timeout, 53 gfp_t gfp) 54 { 55 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 56 struct nf_conn_timeout *timeout_ext; 57 58 timeout_ext = nf_ct_ext_add(ct, NF_CT_EXT_TIMEOUT, gfp); 59 if (timeout_ext == NULL) 60 return NULL; 61 62 rcu_assign_pointer(timeout_ext->timeout, timeout); 63 64 return timeout_ext; 65 #else 66 return NULL; 67 #endif 68 }; 69 nf_ct_timeout_lookup(const struct nf_conn * ct)70 static inline unsigned int *nf_ct_timeout_lookup(const struct nf_conn *ct) 71 { 72 unsigned int *timeouts = NULL; 73 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 74 struct nf_conn_timeout *timeout_ext; 75 76 timeout_ext = nf_ct_timeout_find(ct); 77 if (timeout_ext) 78 timeouts = nf_ct_timeout_data(timeout_ext); 79 #endif 80 return timeouts; 81 } 82 83 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 84 void nf_ct_untimeout(struct net *net, struct nf_ct_timeout *timeout); 85 int nf_ct_set_timeout(struct net *net, struct nf_conn *ct, u8 l3num, u8 l4num, 86 const char *timeout_name); 87 void nf_ct_destroy_timeout(struct nf_conn *ct); 88 #else nf_ct_set_timeout(struct net * net,struct nf_conn * ct,u8 l3num,u8 l4num,const char * timeout_name)89 static inline int nf_ct_set_timeout(struct net *net, struct nf_conn *ct, 90 u8 l3num, u8 l4num, 91 const char *timeout_name) 92 { 93 return -EOPNOTSUPP; 94 } 95 nf_ct_destroy_timeout(struct nf_conn * ct)96 static inline void nf_ct_destroy_timeout(struct nf_conn *ct) 97 { 98 return; 99 } 100 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ 101 102 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 103 struct nf_ct_timeout_hooks { 104 struct nf_ct_timeout *(*timeout_find_get)(struct net *net, const char *name); 105 void (*timeout_put)(struct nf_ct_timeout *timeout); 106 }; 107 108 extern const struct nf_ct_timeout_hooks __rcu *nf_ct_timeout_hook; 109 #endif 110 111 #endif /* _NF_CONNTRACK_TIMEOUT_H */ 112