From d5c0662a71c1ec87de2baa631292e2703a0dc2e8 Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Fri, 19 Aug 2011 20:21:06 -0700 Subject: netfilter: xt_qtaguid: add some tagging/matching stats /proc/net/xt_qtaguid/ctrl will now show: active tagged sockets: lines of "sock=%p tag=0x%llx (uid=%u)" sockets_tagged, : the number of sockets successfully tagged. sockets_untagged: the number of sockets successfully untagged. counter_set_changes: ctrl counter set change requests. delete_cmds: ctrl delete commands completed. iface_events: number of NETDEV_* events handled. match_found_sk: sk found in skbuff without ct assist. match_found_sk_in_ct: the number of times the connection tracker found a socket for us. This happens when the skbuff didn't have info. match_found_sk_none: the number of times no sk could be determined successfully looked up. This indicates we don't know who the data actually belongs to. This could be unsolicited traffic. Change-Id: I3a65613bb24852e1eea768ab0320a6a7073ab9be Signed-off-by: JP Abgrall --- net/netfilter/xt_qtaguid.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'net/netfilter') diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 968693cb1bc0..5afd4192f353 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -222,6 +222,28 @@ struct sock_tag { tag_t tag; }; +struct qtaguid_event_counts { + /* Various successful events */ + atomic64_t sockets_tagged; + atomic64_t sockets_untagged; + atomic64_t counter_set_changes; + atomic64_t delete_cmds; + atomic64_t iface_events; /* Number of NETDEV_* events handled */ + /* + * match_found_sk_*: numbers related to the netfilter matching + * function finding a sock for the sk_buff. + */ + atomic64_t match_found_sk; /* An sk was already in the sk_buff. */ + /* The connection tracker had the sk. */ + atomic64_t match_found_sk_in_ct; + /* + * No sk could be found. No apparent owner. Could happen with + * unsolicited traffic. + */ + atomic64_t match_found_sk_none; +}; +static struct qtaguid_event_counts qtu_events; + static struct rb_root sock_tag_tree = RB_ROOT; static DEFINE_SPINLOCK(sock_tag_list_lock); @@ -954,6 +976,7 @@ static int iface_inet6addr_event_handler(struct notifier_block *nb, BUG_ON(!ifa || !ifa->idev); dev = (struct net_device *)ifa->idev->dev; iface_stat_create_ipv6(dev, ifa); + atomic64_inc(&qtu_events.iface_events); break; } return NOTIFY_DONE; @@ -977,6 +1000,7 @@ static int iface_inetaddr_event_handler(struct notifier_block *nb, BUG_ON(!ifa || !ifa->ifa_dev); dev = ifa->ifa_dev->dev; iface_stat_create(dev, ifa); + atomic64_inc(&qtu_events.iface_events); break; } return NOTIFY_DONE; @@ -1149,6 +1173,10 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par) * it back, as nf_tproxy_get_sock_v4() got it. */ got_sock = sk; + if (sk) + atomic64_inc(&qtu_events.match_found_sk_in_ct); + } else { + atomic64_inc(&qtu_events.match_found_sk); } MT_DEBUG("qtaguid[%d]: sk=%p got_sock=%d proto=%d\n", par->hooknum, sk, got_sock, ip_hdr(skb)->protocol); @@ -1178,6 +1206,7 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par) par->hooknum, sk ? sk->sk_socket : NULL); res = (info->match ^ info->invert) == 0; + atomic64_inc(&qtu_events.match_found_sk_none); goto put_sock_ret_res; } else if (info->match & info->invert & XT_QTAGUID_SOCKET) { res = false; @@ -1254,6 +1283,7 @@ static int qtaguid_ctrl_proc_read(char *page, char **num_items_returned, return 0; } + /* TODO: support skipping num_items_returned on entry. */ CT_DEBUG("qtaguid: proc ctrl page=%p off=%ld char_count=%d *eof=%d\n", page, items_to_skip, char_count, *eof); @@ -1286,6 +1316,34 @@ static int qtaguid_ctrl_proc_read(char *page, char **num_items_returned, (*num_items_returned)++; } spin_unlock_bh(&sock_tag_list_lock); + + if (item_index++ >= items_to_skip) { + len = snprintf(outp, char_count, + "events: sockets_tagged=%llu " + "sockets_untagged=%llu " + "counter_set_changes=%llu " + "delete_cmds=%llu " + "iface_events=%llu " + "match_found_sk=%llu " + "match_found_sk_in_ct=%llu " + "match_found_sk_none=%llu\n", + atomic64_read(&qtu_events.sockets_tagged), + atomic64_read(&qtu_events.sockets_untagged), + atomic64_read(&qtu_events.counter_set_changes), + atomic64_read(&qtu_events.delete_cmds), + atomic64_read(&qtu_events.iface_events), + atomic64_read(&qtu_events.match_found_sk), + atomic64_read(&qtu_events.match_found_sk_in_ct), + atomic64_read(&qtu_events.match_found_sk_none)); + if (len >= char_count) { + *outp = '\0'; + return outp - page; + } + outp += len; + char_count -= len; + (*num_items_returned)++; + } + *eof = 1; return outp - page; } @@ -1428,7 +1486,7 @@ static int ctrl_cmd_delete(const char *input) spin_unlock_bh(&iface_entry->tag_stat_list_lock); } spin_unlock_bh(&iface_stat_list_lock); - + atomic64_inc(&qtu_events.delete_cmds); res = 0; err: @@ -1487,7 +1545,7 @@ static int ctrl_cmd_counter_set(const char *input) } tcs->active_set = counter_set; spin_unlock_bh(&tag_counter_set_list_lock); - + atomic64_inc(&qtu_events.counter_set_changes); res = 0; err: @@ -1573,6 +1631,7 @@ static int ctrl_cmd_tag(const char *input) sock_tag_entry->tag = combine_atag_with_uid(acct_tag, uid); sock_tag_tree_insert(sock_tag_entry, &sock_tag_tree); + atomic64_inc(&qtu_events.sockets_tagged); } spin_unlock_bh(&sock_tag_list_lock); /* We keep the ref to the socket (file) until it is untagged */ @@ -1638,6 +1697,7 @@ static int ctrl_cmd_untag(const char *input) sockfd_put(el_socket); refcnt -= 2; kfree(sock_tag_entry); + atomic64_inc(&qtu_events.sockets_untagged); CT_DEBUG("qtaguid: ctrl_untag(%s): done. socket->...->f_count=%d\n", input, refcnt); -- cgit v1.2.3