1 /* 2 * connection tracking event cache. 3 */ 4 5 #ifndef _NF_CONNTRACK_ECACHE_H 6 #define _NF_CONNTRACK_ECACHE_H 7 #include <net/netfilter/nf_conntrack.h> 8 9 #include <net/net_namespace.h> 10 #include <net/netfilter/nf_conntrack_expect.h> 11 #include <linux/netfilter/nf_conntrack_common.h> 12 #include <linux/netfilter/nf_conntrack_tuple_common.h> 13 #include <net/netfilter/nf_conntrack_extend.h> 14 15 enum nf_ct_ecache_state { 16 NFCT_ECACHE_UNKNOWN, /* destroy event not sent */ 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 missed; /* missed events */ 24 u16 ctmask; /* bitmask of ct events to be delivered */ 25 u16 expmask; /* bitmask of expect events to be delivered */ 26 enum nf_ct_ecache_state state:8;/* ecache state */ 27 u32 portid; /* netlink portid of destroyer */ 28 }; 29 30 static inline struct nf_conntrack_ecache * 31 nf_ct_ecache_find(const struct nf_conn *ct) 32 { 33 #ifdef CONFIG_NF_CONNTRACK_EVENTS 34 return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE); 35 #else 36 return NULL; 37 #endif 38 } 39 40 static inline struct nf_conntrack_ecache * 41 nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) 42 { 43 #ifdef CONFIG_NF_CONNTRACK_EVENTS 44 struct net *net = nf_ct_net(ct); 45 struct nf_conntrack_ecache *e; 46 47 if (!ctmask && !expmask && net->ct.sysctl_events) { 48 ctmask = ~0; 49 expmask = ~0; 50 } 51 if (!ctmask && !expmask) 52 return NULL; 53 54 e = nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp); 55 if (e) { 56 e->ctmask = ctmask; 57 e->expmask = expmask; 58 } 59 return e; 60 #else 61 return NULL; 62 #endif 63 }; 64 65 #ifdef CONFIG_NF_CONNTRACK_EVENTS 66 /* This structure is passed to event handler */ 67 struct nf_ct_event { 68 struct nf_conn *ct; 69 u32 portid; 70 int report; 71 }; 72 73 struct nf_ct_event_notifier { 74 int (*fcn)(unsigned int events, struct nf_ct_event *item); 75 }; 76 77 int nf_conntrack_register_notifier(struct net *net, 78 struct nf_ct_event_notifier *nb); 79 void nf_conntrack_unregister_notifier(struct net *net, 80 struct nf_ct_event_notifier *nb); 81 82 void nf_ct_deliver_cached_events(struct nf_conn *ct); 83 int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, 84 u32 portid, int report); 85 86 static inline void 87 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) 88 { 89 struct net *net = nf_ct_net(ct); 90 struct nf_conntrack_ecache *e; 91 92 if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 93 return; 94 95 e = nf_ct_ecache_find(ct); 96 if (e == NULL) 97 return; 98 99 set_bit(event, &e->cache); 100 } 101 102 static inline int 103 nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, 104 u32 portid, int report) 105 { 106 const struct net *net = nf_ct_net(ct); 107 108 if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 109 return 0; 110 111 return nf_conntrack_eventmask_report(1 << event, ct, portid, report); 112 } 113 114 static inline int 115 nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) 116 { 117 const struct net *net = nf_ct_net(ct); 118 119 if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) 120 return 0; 121 122 return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); 123 } 124 125 struct nf_exp_event { 126 struct nf_conntrack_expect *exp; 127 u32 portid; 128 int report; 129 }; 130 131 struct nf_exp_event_notifier { 132 int (*fcn)(unsigned int events, struct nf_exp_event *item); 133 }; 134 135 int nf_ct_expect_register_notifier(struct net *net, 136 struct nf_exp_event_notifier *nb); 137 void nf_ct_expect_unregister_notifier(struct net *net, 138 struct nf_exp_event_notifier *nb); 139 140 void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, 141 struct nf_conntrack_expect *exp, 142 u32 portid, int report); 143 144 int nf_conntrack_ecache_pernet_init(struct net *net); 145 void nf_conntrack_ecache_pernet_fini(struct net *net); 146 147 int nf_conntrack_ecache_init(void); 148 void nf_conntrack_ecache_fini(void); 149 150 static inline void nf_conntrack_ecache_delayed_work(struct net *net) 151 { 152 if (!delayed_work_pending(&net->ct.ecache_dwork)) { 153 schedule_delayed_work(&net->ct.ecache_dwork, HZ); 154 net->ct.ecache_dwork_pending = true; 155 } 156 } 157 158 static inline void nf_conntrack_ecache_work(struct net *net) 159 { 160 if (net->ct.ecache_dwork_pending) { 161 net->ct.ecache_dwork_pending = false; 162 mod_delayed_work(system_wq, &net->ct.ecache_dwork, 0); 163 } 164 } 165 #else /* CONFIG_NF_CONNTRACK_EVENTS */ 166 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, 167 struct nf_conn *ct) {} 168 static inline int nf_conntrack_eventmask_report(unsigned int eventmask, 169 struct nf_conn *ct, 170 u32 portid, 171 int report) { return 0; } 172 static inline int nf_conntrack_event(enum ip_conntrack_events event, 173 struct nf_conn *ct) { return 0; } 174 static inline int nf_conntrack_event_report(enum ip_conntrack_events event, 175 struct nf_conn *ct, 176 u32 portid, 177 int report) { return 0; } 178 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} 179 static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e, 180 struct nf_conntrack_expect *exp, 181 u32 portid, 182 int report) {} 183 184 static inline int nf_conntrack_ecache_pernet_init(struct net *net) 185 { 186 return 0; 187 } 188 189 static inline void nf_conntrack_ecache_pernet_fini(struct net *net) 190 { 191 } 192 193 static inline int nf_conntrack_ecache_init(void) 194 { 195 return 0; 196 } 197 198 static inline void nf_conntrack_ecache_fini(void) 199 { 200 } 201 202 static inline void nf_conntrack_ecache_delayed_work(struct net *net) 203 { 204 } 205 206 static inline void nf_conntrack_ecache_work(struct net *net) 207 { 208 } 209 #endif /* CONFIG_NF_CONNTRACK_EVENTS */ 210 211 #endif /*_NF_CONNTRACK_ECACHE_H*/ 212 213