1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * connection tracking event cache. 4 */ 5 6 #ifndef _NF_CONNTRACK_ECACHE_H 7 #define _NF_CONNTRACK_ECACHE_H 8 #include <net/netfilter/nf_conntrack.h> 9 10 #include <net/net_namespace.h> 11 #include <net/netfilter/nf_conntrack_expect.h> 12 #include <linux/netfilter/nf_conntrack_common.h> 13 #include <linux/netfilter/nf_conntrack_tuple_common.h> 14 #include <net/netfilter/nf_conntrack_extend.h> 15 16 enum nf_ct_ecache_state { 17 NFCT_ECACHE_DESTROY_FAIL, /* tried but failed to send destroy event */ 18 NFCT_ECACHE_DESTROY_SENT, /* sent destroy event after failure */ 19 }; 20 21 struct nf_conntrack_ecache { 22 unsigned long cache; /* bitops want long */ 23 u16 ctmask; /* bitmask of ct events to be delivered */ 24 u16 expmask; /* bitmask of expect events to be delivered */ 25 u32 missed; /* missed events */ 26 u32 portid; /* netlink portid of destroyer */ 27 }; 28 29 static inline struct nf_conntrack_ecache * 30 nf_ct_ecache_find(const struct nf_conn *ct) 31 { 32 #ifdef CONFIG_NF_CONNTRACK_EVENTS 33 return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE); 34 #else 35 return NULL; 36 #endif 37 } 38 39 static inline bool nf_ct_ecache_exist(const struct nf_conn *ct) 40 { 41 #ifdef CONFIG_NF_CONNTRACK_EVENTS 42 return nf_ct_ext_exist(ct, NF_CT_EXT_ECACHE); 43 #else 44 return false; 45 #endif 46 } 47 48 #ifdef CONFIG_NF_CONNTRACK_EVENTS 49 50 /* This structure is passed to event handler */ 51 struct nf_ct_event { 52 struct nf_conn *ct; 53 u32 portid; 54 int report; 55 }; 56 57 struct nf_exp_event { 58 struct nf_conntrack_expect *exp; 59 u32 portid; 60 int report; 61 }; 62 63 struct nf_ct_event_notifier { 64 int (*ct_event)(unsigned int events, const struct nf_ct_event *item); 65 int (*exp_event)(unsigned int events, const struct nf_exp_event *item); 66 }; 67 68 void nf_conntrack_register_notifier(struct net *net, 69 const struct nf_ct_event_notifier *nb); 70 void nf_conntrack_unregister_notifier(struct net *net); 71 72 void nf_ct_deliver_cached_events(struct nf_conn *ct); 73 int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, 74 u32 portid, int report); 75 76 bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp); 77 #else 78 79 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) 80 { 81 } 82 83 static inline int nf_conntrack_eventmask_report(unsigned int eventmask, 84 struct nf_conn *ct, 85 u32 portid, 86 int report) 87 { 88 return 0; 89 } 90 91 static inline bool nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) 92 { 93 return false; 94 } 95 #endif 96 97 static inline void 98 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) 99 { 100 #ifdef CONFIG_NF_CONNTRACK_EVENTS 101 struct net *net = nf_ct_net(ct); 102 struct nf_conntrack_ecache *e; 103 104 if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 105 return; 106 107 e = nf_ct_ecache_find(ct); 108 if (e == NULL) 109 return; 110 111 set_bit(event, &e->cache); 112 #endif 113 } 114 115 static inline int 116 nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, 117 u32 portid, int report) 118 { 119 #ifdef CONFIG_NF_CONNTRACK_EVENTS 120 if (nf_ct_ecache_exist(ct)) 121 return nf_conntrack_eventmask_report(1 << event, ct, portid, report); 122 #endif 123 return 0; 124 } 125 126 static inline int 127 nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) 128 { 129 #ifdef CONFIG_NF_CONNTRACK_EVENTS 130 if (nf_ct_ecache_exist(ct)) 131 return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); 132 #endif 133 return 0; 134 } 135 136 #ifdef CONFIG_NF_CONNTRACK_EVENTS 137 void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, 138 struct nf_conntrack_expect *exp, 139 u32 portid, int report); 140 141 void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state); 142 143 void nf_conntrack_ecache_pernet_init(struct net *net); 144 void nf_conntrack_ecache_pernet_fini(struct net *net); 145 146 struct nf_conntrack_net_ecache *nf_conn_pernet_ecache(const struct net *net); 147 148 static inline bool nf_conntrack_ecache_dwork_pending(const struct net *net) 149 { 150 return net->ct.ecache_dwork_pending; 151 } 152 #else /* CONFIG_NF_CONNTRACK_EVENTS */ 153 154 static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e, 155 struct nf_conntrack_expect *exp, 156 u32 portid, 157 int report) 158 { 159 } 160 161 static inline void nf_conntrack_ecache_work(struct net *net, 162 enum nf_ct_ecache_state s) 163 { 164 } 165 166 static inline void nf_conntrack_ecache_pernet_init(struct net *net) 167 { 168 } 169 170 static inline void nf_conntrack_ecache_pernet_fini(struct net *net) 171 { 172 } 173 static inline bool nf_conntrack_ecache_dwork_pending(const struct net *net) { return false; } 174 #endif /* CONFIG_NF_CONNTRACK_EVENTS */ 175 #endif /*_NF_CONNTRACK_ECACHE_H*/ 176