diff options
| author | Florian Westphal <fw@strlen.de> | 2016-04-11 15:52:35 -0400 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-04-12 17:01:52 -0400 |
| commit | 3c435e2e414e82ec6c0e96a1dfc2be3ddc3c23b4 (patch) | |
| tree | a0f99fe0f71f91d082da086646c47a8fbf8f4202 | |
| parent | 85f1e7c29a46360b1b5f9cf87af6b27066c345fd (diff) | |
netfilter: conntrack: de-inline nf_conntrack_eventmask_report
Way too large; move it to nf_conntrack_ecache.c.
Reduces total object size by 1216 byte on my machine.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
| -rw-r--r-- | include/net/netfilter/nf_conntrack_ecache.h | 66 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_ecache.c | 54 |
2 files changed, 66 insertions, 54 deletions
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index 57c880378443..019a5b859868 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h | |||
| @@ -73,6 +73,8 @@ void nf_conntrack_unregister_notifier(struct net *net, | |||
| 73 | struct nf_ct_event_notifier *nb); | 73 | struct nf_ct_event_notifier *nb); |
| 74 | 74 | ||
| 75 | void nf_ct_deliver_cached_events(struct nf_conn *ct); | 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); | ||
| 76 | 78 | ||
| 77 | static inline void | 79 | static inline void |
| 78 | nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) | 80 | nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) |
| @@ -91,69 +93,25 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) | |||
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | static inline int | 95 | static inline int |
| 94 | nf_conntrack_eventmask_report(unsigned int eventmask, | ||
| 95 | struct nf_conn *ct, | ||
| 96 | u32 portid, | ||
| 97 | int report) | ||
| 98 | { | ||
| 99 | int ret = 0; | ||
| 100 | struct net *net = nf_ct_net(ct); | ||
| 101 | struct nf_ct_event_notifier *notify; | ||
| 102 | struct nf_conntrack_ecache *e; | ||
| 103 | |||
| 104 | rcu_read_lock(); | ||
| 105 | notify = rcu_dereference(net->ct.nf_conntrack_event_cb); | ||
| 106 | if (notify == NULL) | ||
| 107 | goto out_unlock; | ||
| 108 | |||
| 109 | e = nf_ct_ecache_find(ct); | ||
| 110 | if (e == NULL) | ||
| 111 | goto out_unlock; | ||
| 112 | |||
| 113 | if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) { | ||
| 114 | struct nf_ct_event item = { | ||
| 115 | .ct = ct, | ||
| 116 | .portid = e->portid ? e->portid : portid, | ||
| 117 | .report = report | ||
| 118 | }; | ||
| 119 | /* This is a resent of a destroy event? If so, skip missed */ | ||
| 120 | unsigned long missed = e->portid ? 0 : e->missed; | ||
| 121 | |||
| 122 | if (!((eventmask | missed) & e->ctmask)) | ||
| 123 | goto out_unlock; | ||
| 124 | |||
| 125 | ret = notify->fcn(eventmask | missed, &item); | ||
| 126 | if (unlikely(ret < 0 || missed)) { | ||
| 127 | spin_lock_bh(&ct->lock); | ||
| 128 | if (ret < 0) { | ||
| 129 | /* This is a destroy event that has been | ||
| 130 | * triggered by a process, we store the PORTID | ||
| 131 | * to include it in the retransmission. */ | ||
| 132 | if (eventmask & (1 << IPCT_DESTROY) && | ||
| 133 | e->portid == 0 && portid != 0) | ||
| 134 | e->portid = portid; | ||
| 135 | else | ||
| 136 | e->missed |= eventmask; | ||
| 137 | } else | ||
| 138 | e->missed &= ~missed; | ||
| 139 | spin_unlock_bh(&ct->lock); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | out_unlock: | ||
| 143 | rcu_read_unlock(); | ||
| 144 | return ret; | ||
| 145 | } | ||
| 146 | |||
| 147 | static inline int | ||
| 148 | nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, | 96 | nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct, |
| 149 | u32 portid, int report) | 97 | u32 portid, int report) |
| 150 | { | 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 | |||
| 151 | return nf_conntrack_eventmask_report(1 << event, ct, portid, report); | 104 | return nf_conntrack_eventmask_report(1 << event, ct, portid, report); |
| 152 | } | 105 | } |
| 153 | 106 | ||
| 154 | static inline int | 107 | static inline int |
| 155 | nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) | 108 | nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct) |
| 156 | { | 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 | |||
| 157 | return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); | 115 | return nf_conntrack_eventmask_report(1 << event, ct, 0, 0); |
| 158 | } | 116 | } |
| 159 | 117 | ||
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index 4e78c57b818f..a0ebab96a92f 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c | |||
| @@ -113,6 +113,60 @@ static void ecache_work(struct work_struct *work) | |||
| 113 | schedule_delayed_work(&ctnet->ecache_dwork, delay); | 113 | schedule_delayed_work(&ctnet->ecache_dwork, delay); |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct, | ||
| 117 | u32 portid, int report) | ||
| 118 | { | ||
| 119 | int ret = 0; | ||
| 120 | struct net *net = nf_ct_net(ct); | ||
| 121 | struct nf_ct_event_notifier *notify; | ||
| 122 | struct nf_conntrack_ecache *e; | ||
| 123 | |||
| 124 | rcu_read_lock(); | ||
| 125 | notify = rcu_dereference(net->ct.nf_conntrack_event_cb); | ||
| 126 | if (!notify) | ||
| 127 | goto out_unlock; | ||
| 128 | |||
| 129 | e = nf_ct_ecache_find(ct); | ||
| 130 | if (!e) | ||
| 131 | goto out_unlock; | ||
| 132 | |||
| 133 | if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) { | ||
| 134 | struct nf_ct_event item = { | ||
| 135 | .ct = ct, | ||
| 136 | .portid = e->portid ? e->portid : portid, | ||
| 137 | .report = report | ||
| 138 | }; | ||
| 139 | /* This is a resent of a destroy event? If so, skip missed */ | ||
| 140 | unsigned long missed = e->portid ? 0 : e->missed; | ||
| 141 | |||
| 142 | if (!((eventmask | missed) & e->ctmask)) | ||
| 143 | goto out_unlock; | ||
| 144 | |||
| 145 | ret = notify->fcn(eventmask | missed, &item); | ||
| 146 | if (unlikely(ret < 0 || missed)) { | ||
| 147 | spin_lock_bh(&ct->lock); | ||
| 148 | if (ret < 0) { | ||
| 149 | /* This is a destroy event that has been | ||
| 150 | * triggered by a process, we store the PORTID | ||
| 151 | * to include it in the retransmission. | ||
| 152 | */ | ||
| 153 | if (eventmask & (1 << IPCT_DESTROY) && | ||
| 154 | e->portid == 0 && portid != 0) | ||
| 155 | e->portid = portid; | ||
| 156 | else | ||
| 157 | e->missed |= eventmask; | ||
| 158 | } else { | ||
| 159 | e->missed &= ~missed; | ||
| 160 | } | ||
| 161 | spin_unlock_bh(&ct->lock); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | out_unlock: | ||
| 165 | rcu_read_unlock(); | ||
| 166 | return ret; | ||
| 167 | } | ||
| 168 | EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report); | ||
| 169 | |||
| 116 | /* deliver cached events and clear cache entry - must be called with locally | 170 | /* deliver cached events and clear cache entry - must be called with locally |
| 117 | * disabled softirqs */ | 171 | * disabled softirqs */ |
| 118 | void nf_ct_deliver_cached_events(struct nf_conn *ct) | 172 | void nf_ct_deliver_cached_events(struct nf_conn *ct) |
