aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2010-10-19 04:19:06 -0400
committerPatrick McHardy <kaber@trash.net>2010-10-19 04:19:06 -0400
commitebbf41df4aabb6d506fa18ea8cb4c2b4388a18b9 (patch)
tree16ea6ca8a2382e399798a087fcbeb63380b21f03 /net
parent43f974cdb4ab6d65f849610deb9ef738d62b2e65 (diff)
netfilter: ctnetlink: add expectation deletion events
This patch allows to listen to events that inform about expectations destroyed. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_conntrack_expect.c6
-rw-r--r--net/netfilter/nf_conntrack_netlink.c30
2 files changed, 25 insertions, 11 deletions
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index b30a1f2aac00..46e8966912b1 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -41,7 +41,8 @@ static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
41static HLIST_HEAD(nf_ct_userspace_expect_list); 41static HLIST_HEAD(nf_ct_userspace_expect_list);
42 42
43/* nf_conntrack_expect helper functions */ 43/* nf_conntrack_expect helper functions */
44void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) 44void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
45 u32 pid, int report)
45{ 46{
46 struct nf_conn_help *master_help = nfct_help(exp->master); 47 struct nf_conn_help *master_help = nfct_help(exp->master);
47 struct net *net = nf_ct_exp_net(exp); 48 struct net *net = nf_ct_exp_net(exp);
@@ -55,11 +56,12 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
55 if (!(exp->flags & NF_CT_EXPECT_USERSPACE)) 56 if (!(exp->flags & NF_CT_EXPECT_USERSPACE))
56 master_help->expecting[exp->class]--; 57 master_help->expecting[exp->class]--;
57 58
59 nf_ct_expect_event_report(IPEXP_DESTROY, exp, pid, report);
58 nf_ct_expect_put(exp); 60 nf_ct_expect_put(exp);
59 61
60 NF_CT_STAT_INC(net, expect_delete); 62 NF_CT_STAT_INC(net, expect_delete);
61} 63}
62EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); 64EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report);
63 65
64static void nf_ct_expectation_timed_out(unsigned long ul_expect) 66static void nf_ct_expectation_timed_out(unsigned long ul_expect)
65{ 67{
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index b4077be5f663..62bad229106b 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1632,17 +1632,20 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
1632 struct nlmsghdr *nlh; 1632 struct nlmsghdr *nlh;
1633 struct nfgenmsg *nfmsg; 1633 struct nfgenmsg *nfmsg;
1634 struct sk_buff *skb; 1634 struct sk_buff *skb;
1635 unsigned int type; 1635 unsigned int type, group;
1636 int flags = 0; 1636 int flags = 0;
1637 1637
1638 if (events & (1 << IPEXP_NEW)) { 1638 if (events & (1 << IPEXP_DESTROY)) {
1639 type = IPCTNL_MSG_EXP_DELETE;
1640 group = NFNLGRP_CONNTRACK_EXP_DESTROY;
1641 } else if (events & (1 << IPEXP_NEW)) {
1639 type = IPCTNL_MSG_EXP_NEW; 1642 type = IPCTNL_MSG_EXP_NEW;
1640 flags = NLM_F_CREATE|NLM_F_EXCL; 1643 flags = NLM_F_CREATE|NLM_F_EXCL;
1644 group = NFNLGRP_CONNTRACK_EXP_NEW;
1641 } else 1645 } else
1642 return 0; 1646 return 0;
1643 1647
1644 if (!item->report && 1648 if (!item->report && !nfnetlink_has_listeners(net, group))
1645 !nfnetlink_has_listeners(net, NFNLGRP_CONNTRACK_EXP_NEW))
1646 return 0; 1649 return 0;
1647 1650
1648 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 1651 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
@@ -1665,8 +1668,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
1665 rcu_read_unlock(); 1668 rcu_read_unlock();
1666 1669
1667 nlmsg_end(skb, nlh); 1670 nlmsg_end(skb, nlh);
1668 nfnetlink_send(skb, net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, 1671 nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC);
1669 item->report, GFP_ATOMIC);
1670 return 0; 1672 return 0;
1671 1673
1672nla_put_failure: 1674nla_put_failure:
@@ -1849,7 +1851,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1849 } 1851 }
1850 1852
1851 /* after list removal, usage count == 1 */ 1853 /* after list removal, usage count == 1 */
1852 nf_ct_unexpect_related(exp); 1854 spin_lock_bh(&nf_conntrack_lock);
1855 if (del_timer(&exp->timeout)) {
1856 nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid,
1857 nlmsg_report(nlh));
1858 nf_ct_expect_put(exp);
1859 }
1860 spin_unlock_bh(&nf_conntrack_lock);
1853 /* have to put what we 'get' above. 1861 /* have to put what we 'get' above.
1854 * after this line usage count == 0 */ 1862 * after this line usage count == 0 */
1855 nf_ct_expect_put(exp); 1863 nf_ct_expect_put(exp);
@@ -1866,7 +1874,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1866 m_help = nfct_help(exp->master); 1874 m_help = nfct_help(exp->master);
1867 if (!strcmp(m_help->helper->name, name) && 1875 if (!strcmp(m_help->helper->name, name) &&
1868 del_timer(&exp->timeout)) { 1876 del_timer(&exp->timeout)) {
1869 nf_ct_unlink_expect(exp); 1877 nf_ct_unlink_expect_report(exp,
1878 NETLINK_CB(skb).pid,
1879 nlmsg_report(nlh));
1870 nf_ct_expect_put(exp); 1880 nf_ct_expect_put(exp);
1871 } 1881 }
1872 } 1882 }
@@ -1880,7 +1890,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1880 &net->ct.expect_hash[i], 1890 &net->ct.expect_hash[i],
1881 hnode) { 1891 hnode) {
1882 if (del_timer(&exp->timeout)) { 1892 if (del_timer(&exp->timeout)) {
1883 nf_ct_unlink_expect(exp); 1893 nf_ct_unlink_expect_report(exp,
1894 NETLINK_CB(skb).pid,
1895 nlmsg_report(nlh));
1884 nf_ct_expect_put(exp); 1896 nf_ct_expect_put(exp);
1885 } 1897 }
1886 } 1898 }