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 ctnl_timeout { 15 struct list_head head; 16 struct rcu_head rcu_head; 17 refcount_t refcnt; 18 char name[CTNL_TIMEOUT_NAME_MAX]; 19 __u16 l3num; 20 const struct nf_conntrack_l4proto *l4proto; 21 char data[0]; 22 }; 23 24 struct nf_conn_timeout { 25 struct ctnl_timeout __rcu *timeout; 26 }; 27 28 static inline unsigned int * 29 nf_ct_timeout_data(struct nf_conn_timeout *t) 30 { 31 struct ctnl_timeout *timeout; 32 33 timeout = rcu_dereference(t->timeout); 34 if (timeout == NULL) 35 return NULL; 36 37 return (unsigned int *)timeout->data; 38 } 39 40 static inline 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 51 struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct, 52 struct ctnl_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 70 static inline unsigned int * 71 nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct, 72 const struct nf_conntrack_l4proto *l4proto) 73 { 74 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 75 struct nf_conn_timeout *timeout_ext; 76 unsigned int *timeouts; 77 78 timeout_ext = nf_ct_timeout_find(ct); 79 if (timeout_ext) { 80 timeouts = nf_ct_timeout_data(timeout_ext); 81 if (unlikely(!timeouts)) 82 timeouts = l4proto->get_timeouts(net); 83 } else { 84 timeouts = l4proto->get_timeouts(net); 85 } 86 87 return timeouts; 88 #else 89 return l4proto->get_timeouts(net); 90 #endif 91 } 92 93 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 94 int nf_conntrack_timeout_init(void); 95 void nf_conntrack_timeout_fini(void); 96 #else 97 static inline int nf_conntrack_timeout_init(void) 98 { 99 return 0; 100 } 101 102 static inline void nf_conntrack_timeout_fini(void) 103 { 104 return; 105 } 106 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */ 107 108 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 109 extern struct ctnl_timeout *(*nf_ct_timeout_find_get_hook)(struct net *net, const char *name); 110 extern void (*nf_ct_timeout_put_hook)(struct ctnl_timeout *timeout); 111 #endif 112 113 #endif /* _NF_CONNTRACK_TIMEOUT_H */ 114