mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 17:01:14 +00:00
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>
This commit is contained in:
parent
85f1e7c29a
commit
3c435e2e41
2 changed files with 66 additions and 54 deletions
|
@ -73,6 +73,8 @@ void nf_conntrack_unregister_notifier(struct net *net,
|
|||
struct nf_ct_event_notifier *nb);
|
||||
|
||||
void nf_ct_deliver_cached_events(struct nf_conn *ct);
|
||||
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
u32 portid, int report);
|
||||
|
||||
static inline void
|
||||
nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
|
||||
|
@ -90,70 +92,26 @@ nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
|
|||
set_bit(event, &e->cache);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nf_conntrack_eventmask_report(unsigned int eventmask,
|
||||
struct nf_conn *ct,
|
||||
u32 portid,
|
||||
int report)
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct nf_ct_event_notifier *notify;
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
rcu_read_lock();
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (notify == NULL)
|
||||
goto out_unlock;
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (e == NULL)
|
||||
goto out_unlock;
|
||||
|
||||
if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
|
||||
struct nf_ct_event item = {
|
||||
.ct = ct,
|
||||
.portid = e->portid ? e->portid : portid,
|
||||
.report = report
|
||||
};
|
||||
/* This is a resent of a destroy event? If so, skip missed */
|
||||
unsigned long missed = e->portid ? 0 : e->missed;
|
||||
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
/* This is a destroy event that has been
|
||||
* triggered by a process, we store the PORTID
|
||||
* to include it in the retransmission. */
|
||||
if (eventmask & (1 << IPCT_DESTROY) &&
|
||||
e->portid == 0 && portid != 0)
|
||||
e->portid = portid;
|
||||
else
|
||||
e->missed |= eventmask;
|
||||
} else
|
||||
e->missed &= ~missed;
|
||||
spin_unlock_bh(&ct->lock);
|
||||
}
|
||||
}
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
|
||||
u32 portid, int report)
|
||||
{
|
||||
const struct net *net = nf_ct_net(ct);
|
||||
|
||||
if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
return 0;
|
||||
|
||||
return nf_conntrack_eventmask_report(1 << event, ct, portid, report);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
|
||||
{
|
||||
const struct net *net = nf_ct_net(ct);
|
||||
|
||||
if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb))
|
||||
return 0;
|
||||
|
||||
return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,60 @@ static void ecache_work(struct work_struct *work)
|
|||
schedule_delayed_work(&ctnet->ecache_dwork, delay);
|
||||
}
|
||||
|
||||
int nf_conntrack_eventmask_report(unsigned int eventmask, struct nf_conn *ct,
|
||||
u32 portid, int report)
|
||||
{
|
||||
int ret = 0;
|
||||
struct net *net = nf_ct_net(ct);
|
||||
struct nf_ct_event_notifier *notify;
|
||||
struct nf_conntrack_ecache *e;
|
||||
|
||||
rcu_read_lock();
|
||||
notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
|
||||
if (!notify)
|
||||
goto out_unlock;
|
||||
|
||||
e = nf_ct_ecache_find(ct);
|
||||
if (!e)
|
||||
goto out_unlock;
|
||||
|
||||
if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
|
||||
struct nf_ct_event item = {
|
||||
.ct = ct,
|
||||
.portid = e->portid ? e->portid : portid,
|
||||
.report = report
|
||||
};
|
||||
/* This is a resent of a destroy event? If so, skip missed */
|
||||
unsigned long missed = e->portid ? 0 : e->missed;
|
||||
|
||||
if (!((eventmask | missed) & e->ctmask))
|
||||
goto out_unlock;
|
||||
|
||||
ret = notify->fcn(eventmask | missed, &item);
|
||||
if (unlikely(ret < 0 || missed)) {
|
||||
spin_lock_bh(&ct->lock);
|
||||
if (ret < 0) {
|
||||
/* This is a destroy event that has been
|
||||
* triggered by a process, we store the PORTID
|
||||
* to include it in the retransmission.
|
||||
*/
|
||||
if (eventmask & (1 << IPCT_DESTROY) &&
|
||||
e->portid == 0 && portid != 0)
|
||||
e->portid = portid;
|
||||
else
|
||||
e->missed |= eventmask;
|
||||
} else {
|
||||
e->missed &= ~missed;
|
||||
}
|
||||
spin_unlock_bh(&ct->lock);
|
||||
}
|
||||
}
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
|
||||
|
||||
/* deliver cached events and clear cache entry - must be called with locally
|
||||
* disabled softirqs */
|
||||
void nf_ct_deliver_cached_events(struct nf_conn *ct)
|
||||
|
|
Loading…
Reference in a new issue