diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2010-10-19 04:19:06 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-10-19 04:19:06 -0400 |
commit | ebbf41df4aabb6d506fa18ea8cb4c2b4388a18b9 (patch) | |
tree | 16ea6ca8a2382e399798a087fcbeb63380b21f03 /net | |
parent | 43f974cdb4ab6d65f849610deb9ef738d62b2e65 (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.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 30 |
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; | |||
41 | static HLIST_HEAD(nf_ct_userspace_expect_list); | 41 | static HLIST_HEAD(nf_ct_userspace_expect_list); |
42 | 42 | ||
43 | /* nf_conntrack_expect helper functions */ | 43 | /* nf_conntrack_expect helper functions */ |
44 | void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) | 44 | void 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 | } |
62 | EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); | 64 | EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report); |
63 | 65 | ||
64 | static void nf_ct_expectation_timed_out(unsigned long ul_expect) | 66 | static 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 | ||
1672 | nla_put_failure: | 1674 | nla_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 | } |