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