Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 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 | |
Alexey Dobriyan | 6058fa6 | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 9 | #include <net/net_namespace.h> |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 10 | #include <net/netfilter/nf_conntrack_expect.h> |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 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> |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 14 | |
Florian Westphal | 616b14b | 2016-08-25 15:33:30 +0200 | [diff] [blame] | 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 | |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 21 | struct nf_conntrack_ecache { |
Florian Westphal | 616b14b | 2016-08-25 15:33:30 +0200 | [diff] [blame] | 22 | unsigned long cache; /* bitops want long */ |
| 23 | unsigned long missed; /* missed events */ |
| 24 | u16 ctmask; /* bitmask of ct events to be delivered */ |
| 25 | u16 expmask; /* bitmask of expect events to be delivered */ |
| 26 | u32 portid; /* netlink portid of destroyer */ |
| 27 | enum nf_ct_ecache_state state; /* ecache state */ |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 28 | }; |
| 29 | |
| 30 | static inline struct nf_conntrack_ecache * |
| 31 | nf_ct_ecache_find(const struct nf_conn *ct) |
| 32 | { |
Changli Gao | e0e76c8 | 2010-11-15 12:23:24 +0100 | [diff] [blame] | 33 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 34 | return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE); |
Changli Gao | e0e76c8 | 2010-11-15 12:23:24 +0100 | [diff] [blame] | 35 | #else |
| 36 | return NULL; |
| 37 | #endif |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | static inline struct nf_conntrack_ecache * |
Patrick McHardy | 0cebe4b | 2010-02-03 13:51:51 +0100 | [diff] [blame] | 41 | nf_ct_ecache_ext_add(struct nf_conn *ct, u16 ctmask, u16 expmask, gfp_t gfp) |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 42 | { |
Changli Gao | e0e76c8 | 2010-11-15 12:23:24 +0100 | [diff] [blame] | 43 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 44 | struct net *net = nf_ct_net(ct); |
Patrick McHardy | 0cebe4b | 2010-02-03 13:51:51 +0100 | [diff] [blame] | 45 | struct nf_conntrack_ecache *e; |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 46 | |
Patrick McHardy | 0cebe4b | 2010-02-03 13:51:51 +0100 | [diff] [blame] | 47 | if (!ctmask && !expmask && net->ct.sysctl_events) { |
| 48 | ctmask = ~0; |
| 49 | expmask = ~0; |
| 50 | } |
| 51 | if (!ctmask && !expmask) |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 52 | return NULL; |
| 53 | |
Patrick McHardy | 0cebe4b | 2010-02-03 13:51:51 +0100 | [diff] [blame] | 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; |
Changli Gao | e0e76c8 | 2010-11-15 12:23:24 +0100 | [diff] [blame] | 60 | #else |
| 61 | return NULL; |
| 62 | #endif |
Pablo Neira Ayuso | 6bfea19 | 2009-06-02 20:08:44 +0200 | [diff] [blame] | 63 | }; |
| 64 | |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 65 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 66 | /* This structure is passed to event handler */ |
| 67 | struct nf_ct_event { |
| 68 | struct nf_conn *ct; |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 69 | u32 portid; |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 70 | int report; |
| 71 | }; |
| 72 | |
Pablo Neira Ayuso | e34d5c1 | 2009-06-03 10:32:06 +0200 | [diff] [blame] | 73 | struct nf_ct_event_notifier { |
| 74 | int (*fcn)(unsigned int events, struct nf_ct_event *item); |
| 75 | }; |
| 76 | |
Joe Perches | 4e77be4 | 2013-09-23 11:37:48 -0700 | [diff] [blame] | 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); |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 81 | |
Joe Perches | 4e77be4 | 2013-09-23 11:37:48 -0700 | [diff] [blame] | 82 | void nf_ct_deliver_cached_events(struct nf_conn *ct); |
Florian Westphal | 3c435e2 | 2016-04-11 21:52:35 +0200 | [diff] [blame] | 83 | int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, |
| 84 | u32 portid, int report); |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 85 | |
| 86 | static inline void |
Alexey Dobriyan | a71996f | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 87 | nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 88 | { |
Pablo Neira Ayuso | 70e9942 | 2011-11-22 00:16:51 +0100 | [diff] [blame] | 89 | struct net *net = nf_ct_net(ct); |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 90 | struct nf_conntrack_ecache *e; |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 91 | |
Pablo Neira Ayuso | 6bd0405 | 2012-07-05 15:42:10 +0200 | [diff] [blame] | 92 | if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb)) |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 93 | return; |
| 94 | |
| 95 | e = nf_ct_ecache_find(ct); |
| 96 | if (e == NULL) |
| 97 | return; |
| 98 | |
| 99 | set_bit(event, &e->cache); |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 100 | } |
| 101 | |
Pablo Neira Ayuso | dd7669a | 2009-06-13 12:30:52 +0200 | [diff] [blame] | 102 | static inline int |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 103 | nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 104 | u32 portid, int report) |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 105 | { |
Florian Westphal | 3c435e2 | 2016-04-11 21:52:35 +0200 | [diff] [blame] | 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 | |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 111 | return nf_conntrack_eventmask_report(1 << event, ct, portid, report); |
Pablo Neira Ayuso | a0891aa | 2009-06-13 12:26:29 +0200 | [diff] [blame] | 112 | } |
| 113 | |
Pablo Neira Ayuso | dd7669a | 2009-06-13 12:30:52 +0200 | [diff] [blame] | 114 | static inline int |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 115 | nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) |
| 116 | { |
Florian Westphal | 3c435e2 | 2016-04-11 21:52:35 +0200 | [diff] [blame] | 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 | |
Pablo Neira Ayuso | dd7669a | 2009-06-13 12:30:52 +0200 | [diff] [blame] | 122 | return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | struct nf_exp_event { |
| 126 | struct nf_conntrack_expect *exp; |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 127 | u32 portid; |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 128 | int report; |
| 129 | }; |
| 130 | |
Pablo Neira Ayuso | e34d5c1 | 2009-06-03 10:32:06 +0200 | [diff] [blame] | 131 | struct nf_exp_event_notifier { |
| 132 | int (*fcn)(unsigned int events, struct nf_exp_event *item); |
| 133 | }; |
| 134 | |
Joe Perches | 4e77be4 | 2013-09-23 11:37:48 -0700 | [diff] [blame] | 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); |
Patrick McHardy | 010c7d6 | 2007-03-14 16:40:10 -0700 | [diff] [blame] | 139 | |
Florian Westphal | ecdfb48 | 2016-04-11 21:52:36 +0200 | [diff] [blame] | 140 | void nf_ct_expect_event_report(enum ip_conntrack_expect_events event, |
| 141 | struct nf_conntrack_expect *exp, |
| 142 | u32 portid, int report); |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 143 | |
Joe Perches | 4e77be4 | 2013-09-23 11:37:48 -0700 | [diff] [blame] | 144 | int nf_conntrack_ecache_pernet_init(struct net *net); |
| 145 | void nf_conntrack_ecache_pernet_fini(struct net *net); |
Alexey Dobriyan | 6058fa6 | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 146 | |
Joe Perches | 4e77be4 | 2013-09-23 11:37:48 -0700 | [diff] [blame] | 147 | int nf_conntrack_ecache_init(void); |
| 148 | void nf_conntrack_ecache_fini(void); |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 149 | |
Florian Westphal | 9500507 | 2014-06-10 23:12:56 +0200 | [diff] [blame] | 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 */ |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 166 | static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, |
Linus Torvalds | 64f1b653 | 2008-10-11 09:46:24 -0700 | [diff] [blame] | 167 | struct nf_conn *ct) {} |
Pablo Neira Ayuso | dd7669a | 2009-06-13 12:30:52 +0200 | [diff] [blame] | 168 | static inline int nf_conntrack_eventmask_report(unsigned int eventmask, |
| 169 | struct nf_conn *ct, |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 170 | u32 portid, |
Pablo Neira Ayuso | dd7669a | 2009-06-13 12:30:52 +0200 | [diff] [blame] | 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, |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 176 | u32 portid, |
Pablo Neira Ayuso | dd7669a | 2009-06-13 12:30:52 +0200 | [diff] [blame] | 177 | int report) { return 0; } |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 178 | static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 179 | static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e, |
| 180 | struct nf_conntrack_expect *exp, |
Eric W. Biederman | 15e4730 | 2012-09-07 20:12:54 +0000 | [diff] [blame] | 181 | u32 portid, |
Pablo Neira Ayuso | 19abb7b | 2008-11-18 11:56:20 +0100 | [diff] [blame] | 182 | int report) {} |
Alexey Dobriyan | 6058fa6 | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 183 | |
Gao feng | 3fe0f94 | 2013-01-21 22:10:28 +0000 | [diff] [blame] | 184 | static inline int nf_conntrack_ecache_pernet_init(struct net *net) |
Alexey Dobriyan | 6058fa6 | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 185 | { |
| 186 | return 0; |
Guo-Fu Tseng | bb21c95 | 2008-10-09 21:10:36 -0700 | [diff] [blame] | 187 | } |
Alexey Dobriyan | 6058fa6 | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 188 | |
Gao feng | 3fe0f94 | 2013-01-21 22:10:28 +0000 | [diff] [blame] | 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) |
Alexey Dobriyan | 6058fa6 | 2008-10-08 11:35:07 +0200 | [diff] [blame] | 199 | { |
| 200 | } |
Florian Westphal | 9500507 | 2014-06-10 23:12:56 +0200 | [diff] [blame] | 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 | } |
Martin Josefsson | f618012 | 2006-11-29 02:35:01 +0100 | [diff] [blame] | 209 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ |
| 210 | |
| 211 | #endif /*_NF_CONNTRACK_ECACHE_H*/ |
| 212 | |