ANDROID: revert all xt_qtaguid stuff
Revert "ANDROID: xt_qtaguid: fix UAF race" This reverts commit5efc888dcb. Revert "ANDROID: xt_qtaguid: Remove tag_entry from process list on untag" This reverts commit 5a7c121b2903285f0f97c3352e560274116ab984. Revert "ANDROID: xt_qtaguid: Remove unnecessary null checks to device's name" This reverts commit441e17f79c. Revert "ANDROID: qtaguid: Fix the UAF probelm with tag_ref_tree" This reverts commitb4d74821e0. Revert "ANDROID: netfilter: xt_qtaguid: Fix 4.14 compilation" This reverts commit2f6e1d62d4. Revert "ANDROID: netfilter: xt_qtaguid: Use sk_uid to replace uid get from socket file" This reverts commit109379668e. Revert "ANDROID: netfilter: xt_qtaguid: fix handling for cases where tunnels are used." This reverts commit972ca00dc9. Revert "ANDROID: netfilter: xt_qtaguid: handle properly request sockets" This reverts commit5824b89fe0. Revert "ANDROID: netfilter: xt_qtaguid: Add untag hacks to inet_release function" This reverts commitf2ad6ade89. Revert "ANDROID: netfilter: xt_qtaguid: don't check if embedded arrays are NULL" This reverts commit65a7a5ee5b. Revert "ANDROID: netfilter: xt_qtaguid: fix the deadlock when enable DDEBUG" This reverts commit8ccc999c5e. Revert "ANDROID: netfilter: xt_qtaguid: Don't show empty tag stats for unprivileged uids" This reverts commit6cdbac6f3e. Revert "ANDROID: netfilter: xt_qtaguid: Fix panic caused by processing non-full socket." This reverts commitf20252d7da. Revert "ANDROID: netfilter: xt_qtaguid: Fix panic caused by synack processing" This reverts commitaf798507c0. Revert "ANDROID: netfilter: xt_qtaguid: fix a race condition in if_tag_stat_update" This reverts commitca58d2242f. Revert "ANDROID: netfilter: xt_qtaguid: xt_socket: build fixes" This reverts commit5dfb5c0e04. Revert "ANDROID: netfilter: xt_qtaguid: Use sk_callback_lock read locks before reading sk->sk_socket" This reverts commit06ac276ee6. Revert "ANDROID: netfilter: xt_qtaguid/xt_socket: Build fixups" This reverts commit9b19736f43. Revert "ANDROID: netfilter: xt_qtaguid: Fix boot panic" This reverts commit6fc67945ea. Revert "ANDROID: netfilter: xt_qtaguid: fix bad tcp_time_wait sock handling" This reverts commita89db3e49d. Revert "ANDROID: netfilter: xt_qtaguid: 3.10 fixes" This reverts commit1474b38fe6. Revert "ANDROID: netfilter: xt_qtaguid: rate limit some of the printks" This reverts commitbc1e31b839. Revert "ANDROID: netfilter: xt_qtaguid: Allow tracking loopback" This reverts commit11a32dfd17. Revert "ANDROID: netfilter: xt_qtaguid: extend iface stat to report protocols" This reverts commit2170698b06. Revert "ANDROID: netfilter: xt_qtaguid: remove AID_* dependency for access control" This reverts commit5fecf3b1a1. Revert "ANDROID: netfilter: xt_qtaguid: Don't BUG_ON if create_if_tag_stat fails" This reverts commit61a97f2011. Revert "ANDROID: netfilter: xt_qtaguid: fix error exit that would keep a spinlock." This reverts commit260b664522. Revert "ANDROID: netfilter: xt_qtaguid: report only uid tags to non-privileged processes" This reverts commit22ecb1cbf8. Revert "ANDROID: netfilter: xt_qtaguid: start tracking iface rx/tx at low level" This reverts commita2d25419f8. Revert "ANDROID: netfilter: xt_qtaguid: fix ipv6 protocol lookup" This reverts commit588f1e1dbb. Revert "ANDROID: netfilter: xt_qtaguid: add qtaguid matching module" This reverts commit00f57e8b30. Based on: athina:/git/AND-B5R3 ((0a5c1622fe85...))$ git log --oneline --no-merges remotes/android/kernel/common/android-4.19-q..HEAD | egrep qtaguid441e17f79cANDROID: xt_qtaguid: Remove unnecessary null checks to device's nameb4d74821e0ANDROID: qtaguid: Fix the UAF probelm with tag_ref_tree2f6e1d62d4ANDROID: netfilter: xt_qtaguid: Fix 4.14 compilation109379668eANDROID: netfilter: xt_qtaguid: Use sk_uid to replace uid get from socket file972ca00dc9ANDROID: netfilter: xt_qtaguid: fix handling for cases where tunnels are used.5824b89fe0ANDROID: netfilter: xt_qtaguid: handle properly request socketsf2ad6ade89ANDROID: netfilter: xt_qtaguid: Add untag hacks to inet_release function65a7a5ee5bANDROID: netfilter: xt_qtaguid: don't check if embedded arrays are NULL8ccc999c5eANDROID: netfilter: xt_qtaguid: fix the deadlock when enable DDEBUG6cdbac6f3eANDROID: netfilter: xt_qtaguid: Don't show empty tag stats for unprivileged uidsf20252d7daANDROID: netfilter: xt_qtaguid: Fix panic caused by processing non-full socket.af798507c0ANDROID: netfilter: xt_qtaguid: Fix panic caused by synack processingca58d2242fANDROID: netfilter: xt_qtaguid: fix a race condition in if_tag_stat_update5dfb5c0e04ANDROID: netfilter: xt_qtaguid: xt_socket: build fixes06ac276ee6ANDROID: netfilter: xt_qtaguid: Use sk_callback_lock read locks before reading sk->sk_socket9b19736f43ANDROID: netfilter: xt_qtaguid/xt_socket: Build fixups6fc67945eaANDROID: netfilter: xt_qtaguid: Fix boot panica89db3e49dANDROID: netfilter: xt_qtaguid: fix bad tcp_time_wait sock handling1474b38fe6ANDROID: netfilter: xt_qtaguid: 3.10 fixesbc1e31b839ANDROID: netfilter: xt_qtaguid: rate limit some of the printks11a32dfd17ANDROID: netfilter: xt_qtaguid: Allow tracking loopback2170698b06ANDROID: netfilter: xt_qtaguid: extend iface stat to report protocols5fecf3b1a1ANDROID: netfilter: xt_qtaguid: remove AID_* dependency for access control61a97f2011ANDROID: netfilter: xt_qtaguid: Don't BUG_ON if create_if_tag_stat fails260b664522ANDROID: netfilter: xt_qtaguid: fix error exit that would keep a spinlock.22ecb1cbf8ANDROID: netfilter: xt_qtaguid: report only uid tags to non-privileged processesa2d25419f8ANDROID: netfilter: xt_qtaguid: start tracking iface rx/tx at low level588f1e1dbbANDROID: netfilter: xt_qtaguid: fix ipv6 protocol lookup00f57e8b30ANDROID: netfilter: xt_qtaguid: add qtaguid matching module Generated via: git log --oneline --no-merges remotes/android/kernel/common/android-4.19-q..HEAD \ | egrep qtaguid | while read a b; do git revert $a; done and squashing the result. Test: $ git grep -i qtaguid arch/arm/configs/ranchu_defconfig:108:CONFIG_NETFILTER_XT_MATCH_QTAGUID=y arch/arm64/configs/ranchu64_defconfig:110:CONFIG_NETFILTER_XT_MATCH_QTAGUID=y arch/x86/configs/i386_ranchu_defconfig:142:CONFIG_NETFILTER_XT_MATCH_QTAGUID=y arch/x86/configs/x86_64_ranchu_defconfig:140:CONFIG_NETFILTER_XT_MATCH_QTAGUID=y Bug: 138428914 Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: Ida83e0ba51c5debbc509f99b35d6013be01ddedf
This commit is contained in:
committed by
Hridaya Prajapati
parent
a2f94eff3a
commit
c036663544
@@ -22,7 +22,5 @@
|
||||
#define AID_INET KGIDT_INIT(3003)
|
||||
#define AID_NET_RAW KGIDT_INIT(3004)
|
||||
#define AID_NET_ADMIN KGIDT_INIT(3005)
|
||||
#define AID_NET_BW_STATS KGIDT_INIT(3006) /* read bandwidth statistics */
|
||||
#define AID_NET_BW_ACCT KGIDT_INIT(3007) /* change bandwidth statistics accounting */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef _XT_QTAGUID_MATCH_H
|
||||
#define _XT_QTAGUID_MATCH_H
|
||||
|
||||
/* For now we just replace the xt_owner.
|
||||
* FIXME: make iptables aware of qtaguid. */
|
||||
#include <linux/netfilter/xt_owner.h>
|
||||
|
||||
#define XT_QTAGUID_UID XT_OWNER_UID
|
||||
#define XT_QTAGUID_GID XT_OWNER_GID
|
||||
#define XT_QTAGUID_SOCKET XT_OWNER_SOCKET
|
||||
#define xt_qtaguid_match_info xt_owner_match_info
|
||||
|
||||
int qtaguid_untag(struct socket *sock, bool kernel);
|
||||
#endif /* _XT_QTAGUID_MATCH_H */
|
||||
@@ -89,7 +89,6 @@
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/netfilter/xt_qtaguid.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
@@ -429,9 +428,6 @@ int inet_release(struct socket *sock)
|
||||
if (sk) {
|
||||
long timeout;
|
||||
|
||||
#ifdef CONFIG_NETFILTER_XT_MATCH_QTAGUID
|
||||
qtaguid_untag(sock, true);
|
||||
#endif
|
||||
/* Applications forget to leave groups before exiting */
|
||||
ip_mc_drop_socket(sk);
|
||||
|
||||
|
||||
@@ -1431,8 +1431,6 @@ config NETFILTER_XT_MATCH_OWNER
|
||||
based on who created the socket: the user or group. It is also
|
||||
possible to check whether a socket actually exists.
|
||||
|
||||
Conflicts with '"quota, tag, uid" match'
|
||||
|
||||
config NETFILTER_XT_MATCH_POLICY
|
||||
tristate 'IPsec "policy" match support'
|
||||
depends on XFRM
|
||||
@@ -1466,22 +1464,6 @@ config NETFILTER_XT_MATCH_PKTTYPE
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
config NETFILTER_XT_MATCH_QTAGUID
|
||||
bool '"quota, tag, owner" match and stats support'
|
||||
depends on NETFILTER_XT_MATCH_SOCKET
|
||||
depends on NETFILTER_XT_MATCH_OWNER=n
|
||||
help
|
||||
This option replaces the `owner' match. In addition to matching
|
||||
on uid, it keeps stats based on a tag assigned to a socket.
|
||||
The full tag is comprised of a UID and an accounting tag.
|
||||
The tags are assignable to sockets from user space (e.g. a download
|
||||
manager can assign the socket to another UID for accounting).
|
||||
Stats and control are done via /proc/net/xt_qtaguid/.
|
||||
It replaces owner as it takes the same arguments, but should
|
||||
really be recognized by the iptables tool.
|
||||
|
||||
If unsure, say `N'.
|
||||
|
||||
config NETFILTER_XT_MATCH_QUOTA
|
||||
tristate '"quota" match support'
|
||||
depends on NETFILTER_ADVANCED
|
||||
|
||||
@@ -191,7 +191,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CGROUP) += xt_cgroup.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_QTAGUID) += xt_qtaguid_print.o xt_qtaguid.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA2) += xt_quota2.o
|
||||
obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* Kernel iptables module to track stats for packets based on user tags.
|
||||
*
|
||||
* (C) 2011 Google, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __XT_QTAGUID_INTERNAL_H__
|
||||
#define __XT_QTAGUID_INTERNAL_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
/* Iface handling */
|
||||
#define IDEBUG_MASK (1<<0)
|
||||
/* Iptable Matching. Per packet. */
|
||||
#define MDEBUG_MASK (1<<1)
|
||||
/* Red-black tree handling. Per packet. */
|
||||
#define RDEBUG_MASK (1<<2)
|
||||
/* procfs ctrl/stats handling */
|
||||
#define CDEBUG_MASK (1<<3)
|
||||
/* dev and resource tracking */
|
||||
#define DDEBUG_MASK (1<<4)
|
||||
|
||||
/* E.g (IDEBUG_MASK | CDEBUG_MASK | DDEBUG_MASK) */
|
||||
#define DEFAULT_DEBUG_MASK 0
|
||||
|
||||
/*
|
||||
* (Un)Define these *DEBUG to compile out/in the pr_debug calls.
|
||||
* All undef: text size ~ 0x3030; all def: ~ 0x4404.
|
||||
*/
|
||||
#define IDEBUG
|
||||
#define MDEBUG
|
||||
#define RDEBUG
|
||||
#define CDEBUG
|
||||
#define DDEBUG
|
||||
|
||||
#define MSK_DEBUG(mask, ...) do { \
|
||||
if (unlikely(qtaguid_debug_mask & (mask))) \
|
||||
pr_debug(__VA_ARGS__); \
|
||||
} while (0)
|
||||
#ifdef IDEBUG
|
||||
#define IF_DEBUG(...) MSK_DEBUG(IDEBUG_MASK, __VA_ARGS__)
|
||||
#else
|
||||
#define IF_DEBUG(...) no_printk(__VA_ARGS__)
|
||||
#endif
|
||||
#ifdef MDEBUG
|
||||
#define MT_DEBUG(...) MSK_DEBUG(MDEBUG_MASK, __VA_ARGS__)
|
||||
#else
|
||||
#define MT_DEBUG(...) no_printk(__VA_ARGS__)
|
||||
#endif
|
||||
#ifdef RDEBUG
|
||||
#define RB_DEBUG(...) MSK_DEBUG(RDEBUG_MASK, __VA_ARGS__)
|
||||
#else
|
||||
#define RB_DEBUG(...) no_printk(__VA_ARGS__)
|
||||
#endif
|
||||
#ifdef CDEBUG
|
||||
#define CT_DEBUG(...) MSK_DEBUG(CDEBUG_MASK, __VA_ARGS__)
|
||||
#else
|
||||
#define CT_DEBUG(...) no_printk(__VA_ARGS__)
|
||||
#endif
|
||||
#ifdef DDEBUG
|
||||
#define DR_DEBUG(...) MSK_DEBUG(DDEBUG_MASK, __VA_ARGS__)
|
||||
#else
|
||||
#define DR_DEBUG(...) no_printk(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
extern uint qtaguid_debug_mask;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Tags:
|
||||
*
|
||||
* They represent what the data usage counters will be tracked against.
|
||||
* By default a tag is just based on the UID.
|
||||
* The UID is used as the base for policing, and can not be ignored.
|
||||
* So a tag will always at least represent a UID (uid_tag).
|
||||
*
|
||||
* A tag can be augmented with an "accounting tag" which is associated
|
||||
* with a UID.
|
||||
* User space can set the acct_tag portion of the tag which is then used
|
||||
* with sockets: all data belonging to that socket will be counted against the
|
||||
* tag. The policing is then based on the tag's uid_tag portion,
|
||||
* and stats are collected for the acct_tag portion separately.
|
||||
*
|
||||
* There could be
|
||||
* a: {acct_tag=1, uid_tag=10003}
|
||||
* b: {acct_tag=2, uid_tag=10003}
|
||||
* c: {acct_tag=3, uid_tag=10003}
|
||||
* d: {acct_tag=0, uid_tag=10003}
|
||||
* a, b, and c represent tags associated with specific sockets.
|
||||
* d is for the totals for that uid, including all untagged traffic.
|
||||
* Typically d is used with policing/quota rules.
|
||||
*
|
||||
* We want tag_t big enough to distinguish uid_t and acct_tag.
|
||||
* It might become a struct if needed.
|
||||
* Nothing should be using it as an int.
|
||||
*/
|
||||
typedef uint64_t tag_t; /* Only used via accessors */
|
||||
|
||||
#define TAG_UID_MASK 0xFFFFFFFFULL
|
||||
#define TAG_ACCT_MASK (~0xFFFFFFFFULL)
|
||||
|
||||
static inline int tag_compare(tag_t t1, tag_t t2)
|
||||
{
|
||||
return t1 < t2 ? -1 : t1 == t2 ? 0 : 1;
|
||||
}
|
||||
|
||||
static inline tag_t combine_atag_with_uid(tag_t acct_tag, uid_t uid)
|
||||
{
|
||||
return acct_tag | uid;
|
||||
}
|
||||
static inline tag_t make_tag_from_uid(uid_t uid)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
static inline uid_t get_uid_from_tag(tag_t tag)
|
||||
{
|
||||
return tag & TAG_UID_MASK;
|
||||
}
|
||||
static inline tag_t get_utag_from_tag(tag_t tag)
|
||||
{
|
||||
return tag & TAG_UID_MASK;
|
||||
}
|
||||
static inline tag_t get_atag_from_tag(tag_t tag)
|
||||
{
|
||||
return tag & TAG_ACCT_MASK;
|
||||
}
|
||||
|
||||
static inline bool valid_atag(tag_t tag)
|
||||
{
|
||||
return !(tag & TAG_UID_MASK);
|
||||
}
|
||||
static inline tag_t make_atag_from_value(uint32_t value)
|
||||
{
|
||||
return (uint64_t)value << 32;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Maximum number of socket tags that a UID is allowed to have active.
|
||||
* Multiple processes belonging to the same UID contribute towards this limit.
|
||||
* Special UIDs that can impersonate a UID also contribute (e.g. download
|
||||
* manager, ...)
|
||||
*/
|
||||
#define DEFAULT_MAX_SOCK_TAGS 1024
|
||||
|
||||
/*
|
||||
* For now we only track 2 sets of counters.
|
||||
* The default set is 0.
|
||||
* Userspace can activate another set for a given uid being tracked.
|
||||
*/
|
||||
#define IFS_MAX_COUNTER_SETS 2
|
||||
|
||||
enum ifs_tx_rx {
|
||||
IFS_TX,
|
||||
IFS_RX,
|
||||
IFS_MAX_DIRECTIONS
|
||||
};
|
||||
|
||||
/* For now, TCP, UDP, the rest */
|
||||
enum ifs_proto {
|
||||
IFS_TCP,
|
||||
IFS_UDP,
|
||||
IFS_PROTO_OTHER,
|
||||
IFS_MAX_PROTOS
|
||||
};
|
||||
|
||||
struct byte_packet_counters {
|
||||
uint64_t bytes;
|
||||
uint64_t packets;
|
||||
};
|
||||
|
||||
struct data_counters {
|
||||
struct byte_packet_counters bpc[IFS_MAX_COUNTER_SETS][IFS_MAX_DIRECTIONS][IFS_MAX_PROTOS];
|
||||
};
|
||||
|
||||
static inline uint64_t dc_sum_bytes(struct data_counters *counters,
|
||||
int set,
|
||||
enum ifs_tx_rx direction)
|
||||
{
|
||||
return counters->bpc[set][direction][IFS_TCP].bytes
|
||||
+ counters->bpc[set][direction][IFS_UDP].bytes
|
||||
+ counters->bpc[set][direction][IFS_PROTO_OTHER].bytes;
|
||||
}
|
||||
|
||||
static inline uint64_t dc_sum_packets(struct data_counters *counters,
|
||||
int set,
|
||||
enum ifs_tx_rx direction)
|
||||
{
|
||||
return counters->bpc[set][direction][IFS_TCP].packets
|
||||
+ counters->bpc[set][direction][IFS_UDP].packets
|
||||
+ counters->bpc[set][direction][IFS_PROTO_OTHER].packets;
|
||||
}
|
||||
|
||||
|
||||
/* Generic X based nodes used as a base for rb_tree ops */
|
||||
struct tag_node {
|
||||
struct rb_node node;
|
||||
tag_t tag;
|
||||
};
|
||||
|
||||
struct tag_stat {
|
||||
struct tag_node tn;
|
||||
struct data_counters counters;
|
||||
/*
|
||||
* If this tag is acct_tag based, we need to count against the
|
||||
* matching parent uid_tag.
|
||||
*/
|
||||
struct data_counters *parent_counters;
|
||||
};
|
||||
|
||||
struct iface_stat {
|
||||
struct list_head list; /* in iface_stat_list */
|
||||
char *ifname;
|
||||
bool active;
|
||||
/* net_dev is only valid for active iface_stat */
|
||||
struct net_device *net_dev;
|
||||
|
||||
struct byte_packet_counters totals_via_dev[IFS_MAX_DIRECTIONS];
|
||||
struct data_counters totals_via_skb;
|
||||
/*
|
||||
* We keep the last_known, because some devices reset their counters
|
||||
* just before NETDEV_UP, while some will reset just before
|
||||
* NETDEV_REGISTER (which is more normal).
|
||||
* So now, if the device didn't do a NETDEV_UNREGISTER and we see
|
||||
* its current dev stats smaller that what was previously known, we
|
||||
* assume an UNREGISTER and just use the last_known.
|
||||
*/
|
||||
struct byte_packet_counters last_known[IFS_MAX_DIRECTIONS];
|
||||
/* last_known is usable when last_known_valid is true */
|
||||
bool last_known_valid;
|
||||
|
||||
struct proc_dir_entry *proc_ptr;
|
||||
|
||||
struct rb_root tag_stat_tree;
|
||||
spinlock_t tag_stat_list_lock;
|
||||
};
|
||||
|
||||
/* This is needed to create proc_dir_entries from atomic context. */
|
||||
struct iface_stat_work {
|
||||
struct work_struct iface_work;
|
||||
struct iface_stat *iface_entry;
|
||||
};
|
||||
|
||||
/*
|
||||
* Track tag that this socket is transferring data for, and not necessarily
|
||||
* the uid that owns the socket.
|
||||
* This is the tag against which tag_stat.counters will be billed.
|
||||
* These structs need to be looked up by sock and pid.
|
||||
*/
|
||||
struct sock_tag {
|
||||
struct rb_node sock_node;
|
||||
struct sock *sk; /* Only used as a number, never dereferenced */
|
||||
/* Used to associate with a given pid */
|
||||
struct list_head list; /* in proc_qtu_data.sock_tag_list */
|
||||
pid_t pid;
|
||||
|
||||
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 */
|
||||
|
||||
atomic64_t match_calls; /* Number of times iptables called mt */
|
||||
/* Number of times iptables called mt from pre or post routing hooks */
|
||||
atomic64_t match_calls_prepost;
|
||||
/*
|
||||
* match_found_sk_*: numbers related to the netfilter matching
|
||||
* function finding a sock for the sk_buff.
|
||||
* Total skbs processed is sum(match_found*).
|
||||
*/
|
||||
atomic64_t match_found_sk; /* An sk was already in the sk_buff. */
|
||||
/* The connection tracker had or didn't have the sk. */
|
||||
atomic64_t match_found_sk_in_ct;
|
||||
atomic64_t match_found_no_sk_in_ct;
|
||||
/*
|
||||
* No sk could be found. No apparent owner. Could happen with
|
||||
* unsolicited traffic.
|
||||
*/
|
||||
atomic64_t match_no_sk;
|
||||
/*
|
||||
* The file ptr in the sk_socket wasn't there and we couldn't get GID.
|
||||
* This might happen for traffic while the socket is being closed.
|
||||
*/
|
||||
atomic64_t match_no_sk_gid;
|
||||
};
|
||||
|
||||
/* Track the set active_set for the given tag. */
|
||||
struct tag_counter_set {
|
||||
struct tag_node tn;
|
||||
int active_set;
|
||||
};
|
||||
|
||||
/*----------------------------------------------*/
|
||||
/*
|
||||
* The qtu uid data is used to track resources that are created directly or
|
||||
* indirectly by processes (uid tracked).
|
||||
* It is shared by the processes with the same uid.
|
||||
* Some of the resource will be counted to prevent further rogue allocations,
|
||||
* some will need freeing once the owner process (uid) exits.
|
||||
*/
|
||||
struct uid_tag_data {
|
||||
struct rb_node node;
|
||||
uid_t uid;
|
||||
|
||||
/*
|
||||
* For the uid, how many accounting tags have been set.
|
||||
*/
|
||||
int num_active_tags;
|
||||
/* Track the number of proc_qtu_data that reference it */
|
||||
int num_pqd;
|
||||
struct rb_root tag_ref_tree;
|
||||
/* No tag_node_tree_lock; use uid_tag_data_tree_lock */
|
||||
};
|
||||
|
||||
struct tag_ref {
|
||||
struct tag_node tn;
|
||||
|
||||
/*
|
||||
* This tracks the number of active sockets that have a tag on them
|
||||
* which matches this tag_ref.tn.tag.
|
||||
* A tag ref can live on after the sockets are untagged.
|
||||
* A tag ref can only be removed during a tag delete command.
|
||||
*/
|
||||
int num_sock_tags;
|
||||
};
|
||||
|
||||
struct proc_qtu_data {
|
||||
struct rb_node node;
|
||||
pid_t pid;
|
||||
|
||||
struct uid_tag_data *parent_tag_data;
|
||||
|
||||
/* Tracks the sock_tags that need freeing upon this proc's death */
|
||||
struct list_head sock_tag_list;
|
||||
/* No spinlock_t sock_tag_list_lock; use the global one. */
|
||||
};
|
||||
|
||||
/*----------------------------------------------*/
|
||||
#endif /* ifndef __XT_QTAGUID_INTERNAL_H__ */
|
||||
@@ -1,565 +0,0 @@
|
||||
/*
|
||||
* Pretty printing Support for iptables xt_qtaguid module.
|
||||
*
|
||||
* (C) 2011 Google, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Most of the functions in this file just waste time if DEBUG is not defined.
|
||||
* The matching xt_qtaguid_print.h will static inline empty funcs if the needed
|
||||
* debug flags ore not defined.
|
||||
* Those funcs that fail to allocate memory will panic as there is no need to
|
||||
* hobble allong just pretending to do the requested work.
|
||||
*/
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include "xt_qtaguid_internal.h"
|
||||
#include "xt_qtaguid_print.h"
|
||||
|
||||
#ifdef DDEBUG
|
||||
|
||||
static void _bug_on_err_or_null(void *ptr)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(ptr)) {
|
||||
pr_err("qtaguid: kmalloc failed\n");
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
char *pp_tag_t(tag_t *tag)
|
||||
{
|
||||
char *res;
|
||||
|
||||
if (!tag)
|
||||
res = kasprintf(GFP_ATOMIC, "tag_t@null{}");
|
||||
else
|
||||
res = kasprintf(GFP_ATOMIC,
|
||||
"tag_t@%p{tag=0x%llx, uid=%u}",
|
||||
tag, *tag, get_uid_from_tag(*tag));
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_data_counters(struct data_counters *dc, bool showValues)
|
||||
{
|
||||
char *res;
|
||||
|
||||
if (!dc)
|
||||
res = kasprintf(GFP_ATOMIC, "data_counters@null{}");
|
||||
else if (showValues)
|
||||
res = kasprintf(
|
||||
GFP_ATOMIC, "data_counters@%p{"
|
||||
"set0{"
|
||||
"rx{"
|
||||
"tcp{b=%llu, p=%llu}, "
|
||||
"udp{b=%llu, p=%llu},"
|
||||
"other{b=%llu, p=%llu}}, "
|
||||
"tx{"
|
||||
"tcp{b=%llu, p=%llu}, "
|
||||
"udp{b=%llu, p=%llu},"
|
||||
"other{b=%llu, p=%llu}}}, "
|
||||
"set1{"
|
||||
"rx{"
|
||||
"tcp{b=%llu, p=%llu}, "
|
||||
"udp{b=%llu, p=%llu},"
|
||||
"other{b=%llu, p=%llu}}, "
|
||||
"tx{"
|
||||
"tcp{b=%llu, p=%llu}, "
|
||||
"udp{b=%llu, p=%llu},"
|
||||
"other{b=%llu, p=%llu}}}}",
|
||||
dc,
|
||||
dc->bpc[0][IFS_RX][IFS_TCP].bytes,
|
||||
dc->bpc[0][IFS_RX][IFS_TCP].packets,
|
||||
dc->bpc[0][IFS_RX][IFS_UDP].bytes,
|
||||
dc->bpc[0][IFS_RX][IFS_UDP].packets,
|
||||
dc->bpc[0][IFS_RX][IFS_PROTO_OTHER].bytes,
|
||||
dc->bpc[0][IFS_RX][IFS_PROTO_OTHER].packets,
|
||||
dc->bpc[0][IFS_TX][IFS_TCP].bytes,
|
||||
dc->bpc[0][IFS_TX][IFS_TCP].packets,
|
||||
dc->bpc[0][IFS_TX][IFS_UDP].bytes,
|
||||
dc->bpc[0][IFS_TX][IFS_UDP].packets,
|
||||
dc->bpc[0][IFS_TX][IFS_PROTO_OTHER].bytes,
|
||||
dc->bpc[0][IFS_TX][IFS_PROTO_OTHER].packets,
|
||||
dc->bpc[1][IFS_RX][IFS_TCP].bytes,
|
||||
dc->bpc[1][IFS_RX][IFS_TCP].packets,
|
||||
dc->bpc[1][IFS_RX][IFS_UDP].bytes,
|
||||
dc->bpc[1][IFS_RX][IFS_UDP].packets,
|
||||
dc->bpc[1][IFS_RX][IFS_PROTO_OTHER].bytes,
|
||||
dc->bpc[1][IFS_RX][IFS_PROTO_OTHER].packets,
|
||||
dc->bpc[1][IFS_TX][IFS_TCP].bytes,
|
||||
dc->bpc[1][IFS_TX][IFS_TCP].packets,
|
||||
dc->bpc[1][IFS_TX][IFS_UDP].bytes,
|
||||
dc->bpc[1][IFS_TX][IFS_UDP].packets,
|
||||
dc->bpc[1][IFS_TX][IFS_PROTO_OTHER].bytes,
|
||||
dc->bpc[1][IFS_TX][IFS_PROTO_OTHER].packets);
|
||||
else
|
||||
res = kasprintf(GFP_ATOMIC, "data_counters@%p{...}", dc);
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_tag_node(struct tag_node *tn)
|
||||
{
|
||||
char *tag_str;
|
||||
char *res;
|
||||
|
||||
if (!tn) {
|
||||
res = kasprintf(GFP_ATOMIC, "tag_node@null{}");
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
tag_str = pp_tag_t(&tn->tag);
|
||||
res = kasprintf(GFP_ATOMIC,
|
||||
"tag_node@%p{tag=%s}",
|
||||
tn, tag_str);
|
||||
_bug_on_err_or_null(res);
|
||||
kfree(tag_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_tag_ref(struct tag_ref *tr)
|
||||
{
|
||||
char *tn_str;
|
||||
char *res;
|
||||
|
||||
if (!tr) {
|
||||
res = kasprintf(GFP_ATOMIC, "tag_ref@null{}");
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
tn_str = pp_tag_node(&tr->tn);
|
||||
res = kasprintf(GFP_ATOMIC,
|
||||
"tag_ref@%p{%s, num_sock_tags=%d}",
|
||||
tr, tn_str, tr->num_sock_tags);
|
||||
_bug_on_err_or_null(res);
|
||||
kfree(tn_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_tag_stat(struct tag_stat *ts)
|
||||
{
|
||||
char *tn_str;
|
||||
char *counters_str;
|
||||
char *parent_counters_str;
|
||||
char *res;
|
||||
|
||||
if (!ts) {
|
||||
res = kasprintf(GFP_ATOMIC, "tag_stat@null{}");
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
tn_str = pp_tag_node(&ts->tn);
|
||||
counters_str = pp_data_counters(&ts->counters, true);
|
||||
parent_counters_str = pp_data_counters(ts->parent_counters, false);
|
||||
res = kasprintf(GFP_ATOMIC,
|
||||
"tag_stat@%p{%s, counters=%s, parent_counters=%s}",
|
||||
ts, tn_str, counters_str, parent_counters_str);
|
||||
_bug_on_err_or_null(res);
|
||||
kfree(tn_str);
|
||||
kfree(counters_str);
|
||||
kfree(parent_counters_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_iface_stat(struct iface_stat *is)
|
||||
{
|
||||
char *res;
|
||||
if (!is) {
|
||||
res = kasprintf(GFP_ATOMIC, "iface_stat@null{}");
|
||||
} else {
|
||||
struct data_counters *cnts = &is->totals_via_skb;
|
||||
res = kasprintf(GFP_ATOMIC, "iface_stat@%p{"
|
||||
"list=list_head{...}, "
|
||||
"ifname=%s, "
|
||||
"total_dev={rx={bytes=%llu, "
|
||||
"packets=%llu}, "
|
||||
"tx={bytes=%llu, "
|
||||
"packets=%llu}}, "
|
||||
"total_skb={rx={bytes=%llu, "
|
||||
"packets=%llu}, "
|
||||
"tx={bytes=%llu, "
|
||||
"packets=%llu}}, "
|
||||
"last_known_valid=%d, "
|
||||
"last_known={rx={bytes=%llu, "
|
||||
"packets=%llu}, "
|
||||
"tx={bytes=%llu, "
|
||||
"packets=%llu}}, "
|
||||
"active=%d, "
|
||||
"net_dev=%p, "
|
||||
"proc_ptr=%p, "
|
||||
"tag_stat_tree=rb_root{...}}",
|
||||
is,
|
||||
is->ifname,
|
||||
is->totals_via_dev[IFS_RX].bytes,
|
||||
is->totals_via_dev[IFS_RX].packets,
|
||||
is->totals_via_dev[IFS_TX].bytes,
|
||||
is->totals_via_dev[IFS_TX].packets,
|
||||
dc_sum_bytes(cnts, 0, IFS_RX),
|
||||
dc_sum_packets(cnts, 0, IFS_RX),
|
||||
dc_sum_bytes(cnts, 0, IFS_TX),
|
||||
dc_sum_packets(cnts, 0, IFS_TX),
|
||||
is->last_known_valid,
|
||||
is->last_known[IFS_RX].bytes,
|
||||
is->last_known[IFS_RX].packets,
|
||||
is->last_known[IFS_TX].bytes,
|
||||
is->last_known[IFS_TX].packets,
|
||||
is->active,
|
||||
is->net_dev,
|
||||
is->proc_ptr);
|
||||
}
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_sock_tag(struct sock_tag *st)
|
||||
{
|
||||
char *tag_str;
|
||||
char *res;
|
||||
|
||||
if (!st) {
|
||||
res = kasprintf(GFP_ATOMIC, "sock_tag@null{}");
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
tag_str = pp_tag_t(&st->tag);
|
||||
res = kasprintf(GFP_ATOMIC, "sock_tag@%p{"
|
||||
"sock_node=rb_node{...}, "
|
||||
"sk=%p (f_count=%d), list=list_head{...}, "
|
||||
"pid=%u, tag=%s}",
|
||||
st, st->sk, refcount_read(&st->sk->sk_refcnt),
|
||||
st->pid, tag_str);
|
||||
_bug_on_err_or_null(res);
|
||||
kfree(tag_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_uid_tag_data(struct uid_tag_data *utd)
|
||||
{
|
||||
char *res;
|
||||
|
||||
if (!utd)
|
||||
res = kasprintf(GFP_ATOMIC, "uid_tag_data@null{}");
|
||||
else
|
||||
res = kasprintf(GFP_ATOMIC, "uid_tag_data@%p{"
|
||||
"uid=%u, num_active_acct_tags=%d, "
|
||||
"num_pqd=%d, "
|
||||
"tag_node_tree=rb_root{...}, "
|
||||
"proc_qtu_data_tree=rb_root{...}}",
|
||||
utd, utd->uid,
|
||||
utd->num_active_tags, utd->num_pqd);
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
char *pp_proc_qtu_data(struct proc_qtu_data *pqd)
|
||||
{
|
||||
char *parent_tag_data_str;
|
||||
char *res;
|
||||
|
||||
if (!pqd) {
|
||||
res = kasprintf(GFP_ATOMIC, "proc_qtu_data@null{}");
|
||||
_bug_on_err_or_null(res);
|
||||
return res;
|
||||
}
|
||||
parent_tag_data_str = pp_uid_tag_data(pqd->parent_tag_data);
|
||||
res = kasprintf(GFP_ATOMIC, "proc_qtu_data@%p{"
|
||||
"node=rb_node{...}, pid=%u, "
|
||||
"parent_tag_data=%s, "
|
||||
"sock_tag_list=list_head{...}}",
|
||||
pqd, pqd->pid, parent_tag_data_str
|
||||
);
|
||||
_bug_on_err_or_null(res);
|
||||
kfree(parent_tag_data_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*------------------------------------------*/
|
||||
void prdebug_sock_tag_tree(int indent_level,
|
||||
struct rb_root *sock_tag_tree)
|
||||
{
|
||||
struct rb_node *node;
|
||||
struct sock_tag *sock_tag_entry;
|
||||
char *str;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (RB_EMPTY_ROOT(sock_tag_tree)) {
|
||||
str = "sock_tag_tree=rb_root{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "sock_tag_tree=rb_root{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
for (node = rb_first(sock_tag_tree);
|
||||
node;
|
||||
node = rb_next(node)) {
|
||||
sock_tag_entry = rb_entry(node, struct sock_tag, sock_node);
|
||||
str = pp_sock_tag(sock_tag_entry);
|
||||
pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
|
||||
kfree(str);
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
void prdebug_sock_tag_list(int indent_level,
|
||||
struct list_head *sock_tag_list)
|
||||
{
|
||||
struct sock_tag *sock_tag_entry;
|
||||
char *str;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (list_empty(sock_tag_list)) {
|
||||
str = "sock_tag_list=list_head{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "sock_tag_list=list_head{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
list_for_each_entry(sock_tag_entry, sock_tag_list, list) {
|
||||
str = pp_sock_tag(sock_tag_entry);
|
||||
pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
|
||||
kfree(str);
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
void prdebug_proc_qtu_data_tree(int indent_level,
|
||||
struct rb_root *proc_qtu_data_tree)
|
||||
{
|
||||
char *str;
|
||||
struct rb_node *node;
|
||||
struct proc_qtu_data *proc_qtu_data_entry;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (RB_EMPTY_ROOT(proc_qtu_data_tree)) {
|
||||
str = "proc_qtu_data_tree=rb_root{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "proc_qtu_data_tree=rb_root{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
for (node = rb_first(proc_qtu_data_tree);
|
||||
node;
|
||||
node = rb_next(node)) {
|
||||
proc_qtu_data_entry = rb_entry(node,
|
||||
struct proc_qtu_data,
|
||||
node);
|
||||
str = pp_proc_qtu_data(proc_qtu_data_entry);
|
||||
pr_debug("%*d: %s,\n", indent_level*2, indent_level,
|
||||
str);
|
||||
kfree(str);
|
||||
indent_level++;
|
||||
prdebug_sock_tag_list(indent_level,
|
||||
&proc_qtu_data_entry->sock_tag_list);
|
||||
indent_level--;
|
||||
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
void prdebug_tag_ref_tree(int indent_level, struct rb_root *tag_ref_tree)
|
||||
{
|
||||
char *str;
|
||||
struct rb_node *node;
|
||||
struct tag_ref *tag_ref_entry;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (RB_EMPTY_ROOT(tag_ref_tree)) {
|
||||
str = "tag_ref_tree{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "tag_ref_tree{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
for (node = rb_first(tag_ref_tree);
|
||||
node;
|
||||
node = rb_next(node)) {
|
||||
tag_ref_entry = rb_entry(node,
|
||||
struct tag_ref,
|
||||
tn.node);
|
||||
str = pp_tag_ref(tag_ref_entry);
|
||||
pr_debug("%*d: %s,\n", indent_level*2, indent_level,
|
||||
str);
|
||||
kfree(str);
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
void prdebug_uid_tag_data_tree(int indent_level,
|
||||
struct rb_root *uid_tag_data_tree)
|
||||
{
|
||||
char *str;
|
||||
struct rb_node *node;
|
||||
struct uid_tag_data *uid_tag_data_entry;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (RB_EMPTY_ROOT(uid_tag_data_tree)) {
|
||||
str = "uid_tag_data_tree=rb_root{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "uid_tag_data_tree=rb_root{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
for (node = rb_first(uid_tag_data_tree);
|
||||
node;
|
||||
node = rb_next(node)) {
|
||||
uid_tag_data_entry = rb_entry(node, struct uid_tag_data,
|
||||
node);
|
||||
str = pp_uid_tag_data(uid_tag_data_entry);
|
||||
pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
|
||||
kfree(str);
|
||||
if (!RB_EMPTY_ROOT(&uid_tag_data_entry->tag_ref_tree)) {
|
||||
indent_level++;
|
||||
prdebug_tag_ref_tree(indent_level,
|
||||
&uid_tag_data_entry->tag_ref_tree);
|
||||
indent_level--;
|
||||
}
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
void prdebug_tag_stat_tree(int indent_level,
|
||||
struct rb_root *tag_stat_tree)
|
||||
{
|
||||
char *str;
|
||||
struct rb_node *node;
|
||||
struct tag_stat *ts_entry;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (RB_EMPTY_ROOT(tag_stat_tree)) {
|
||||
str = "tag_stat_tree{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "tag_stat_tree{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
for (node = rb_first(tag_stat_tree);
|
||||
node;
|
||||
node = rb_next(node)) {
|
||||
ts_entry = rb_entry(node, struct tag_stat, tn.node);
|
||||
str = pp_tag_stat(ts_entry);
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level,
|
||||
str);
|
||||
kfree(str);
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
void prdebug_iface_stat_list(int indent_level,
|
||||
struct list_head *iface_stat_list)
|
||||
{
|
||||
char *str;
|
||||
struct iface_stat *iface_entry;
|
||||
|
||||
if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
|
||||
return;
|
||||
|
||||
if (list_empty(iface_stat_list)) {
|
||||
str = "iface_stat_list=list_head{}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
return;
|
||||
}
|
||||
|
||||
str = "iface_stat_list=list_head{";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
indent_level++;
|
||||
list_for_each_entry(iface_entry, iface_stat_list, list) {
|
||||
str = pp_iface_stat(iface_entry);
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
kfree(str);
|
||||
|
||||
spin_lock_bh(&iface_entry->tag_stat_list_lock);
|
||||
if (!RB_EMPTY_ROOT(&iface_entry->tag_stat_tree)) {
|
||||
indent_level++;
|
||||
prdebug_tag_stat_tree(indent_level,
|
||||
&iface_entry->tag_stat_tree);
|
||||
indent_level--;
|
||||
}
|
||||
spin_unlock_bh(&iface_entry->tag_stat_list_lock);
|
||||
}
|
||||
indent_level--;
|
||||
str = "}";
|
||||
pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
|
||||
}
|
||||
|
||||
#endif /* ifdef DDEBUG */
|
||||
/*------------------------------------------*/
|
||||
static const char * const netdev_event_strings[] = {
|
||||
"netdev_unknown",
|
||||
"NETDEV_UP",
|
||||
"NETDEV_DOWN",
|
||||
"NETDEV_REBOOT",
|
||||
"NETDEV_CHANGE",
|
||||
"NETDEV_REGISTER",
|
||||
"NETDEV_UNREGISTER",
|
||||
"NETDEV_CHANGEMTU",
|
||||
"NETDEV_CHANGEADDR",
|
||||
"NETDEV_GOING_DOWN",
|
||||
"NETDEV_CHANGENAME",
|
||||
"NETDEV_FEAT_CHANGE",
|
||||
"NETDEV_BONDING_FAILOVER",
|
||||
"NETDEV_PRE_UP",
|
||||
"NETDEV_PRE_TYPE_CHANGE",
|
||||
"NETDEV_POST_TYPE_CHANGE",
|
||||
"NETDEV_POST_INIT",
|
||||
"NETDEV_UNREGISTER_BATCH",
|
||||
"NETDEV_RELEASE",
|
||||
"NETDEV_NOTIFY_PEERS",
|
||||
"NETDEV_JOIN",
|
||||
};
|
||||
|
||||
const char *netdev_evt_str(int netdev_event)
|
||||
{
|
||||
if (netdev_event < 0
|
||||
|| netdev_event >= ARRAY_SIZE(netdev_event_strings))
|
||||
return "bad event num";
|
||||
return netdev_event_strings[netdev_event];
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Pretty printing Support for iptables xt_qtaguid module.
|
||||
*
|
||||
* (C) 2011 Google, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef __XT_QTAGUID_PRINT_H__
|
||||
#define __XT_QTAGUID_PRINT_H__
|
||||
|
||||
#include "xt_qtaguid_internal.h"
|
||||
|
||||
#ifdef DDEBUG
|
||||
|
||||
char *pp_tag_t(tag_t *tag);
|
||||
char *pp_data_counters(struct data_counters *dc, bool showValues);
|
||||
char *pp_tag_node(struct tag_node *tn);
|
||||
char *pp_tag_ref(struct tag_ref *tr);
|
||||
char *pp_tag_stat(struct tag_stat *ts);
|
||||
char *pp_iface_stat(struct iface_stat *is);
|
||||
char *pp_sock_tag(struct sock_tag *st);
|
||||
char *pp_uid_tag_data(struct uid_tag_data *qtd);
|
||||
char *pp_proc_qtu_data(struct proc_qtu_data *pqd);
|
||||
|
||||
/*------------------------------------------*/
|
||||
void prdebug_sock_tag_list(int indent_level,
|
||||
struct list_head *sock_tag_list);
|
||||
void prdebug_sock_tag_tree(int indent_level,
|
||||
struct rb_root *sock_tag_tree);
|
||||
void prdebug_proc_qtu_data_tree(int indent_level,
|
||||
struct rb_root *proc_qtu_data_tree);
|
||||
void prdebug_tag_ref_tree(int indent_level, struct rb_root *tag_ref_tree);
|
||||
void prdebug_uid_tag_data_tree(int indent_level,
|
||||
struct rb_root *uid_tag_data_tree);
|
||||
void prdebug_tag_stat_tree(int indent_level,
|
||||
struct rb_root *tag_stat_tree);
|
||||
void prdebug_iface_stat_list(int indent_level,
|
||||
struct list_head *iface_stat_list);
|
||||
|
||||
#else
|
||||
|
||||
/*------------------------------------------*/
|
||||
static inline char *pp_tag_t(tag_t *tag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_data_counters(struct data_counters *dc, bool showValues)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_tag_node(struct tag_node *tn)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_tag_ref(struct tag_ref *tr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_tag_stat(struct tag_stat *ts)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_iface_stat(struct iface_stat *is)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_sock_tag(struct sock_tag *st)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_uid_tag_data(struct uid_tag_data *qtd)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline char *pp_proc_qtu_data(struct proc_qtu_data *pqd)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*------------------------------------------*/
|
||||
static inline
|
||||
void prdebug_sock_tag_list(int indent_level,
|
||||
struct list_head *sock_tag_list)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void prdebug_sock_tag_tree(int indent_level,
|
||||
struct rb_root *sock_tag_tree)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void prdebug_proc_qtu_data_tree(int indent_level,
|
||||
struct rb_root *proc_qtu_data_tree)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void prdebug_tag_ref_tree(int indent_level, struct rb_root *tag_ref_tree)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void prdebug_uid_tag_data_tree(int indent_level,
|
||||
struct rb_root *uid_tag_data_tree)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void prdebug_tag_stat_tree(int indent_level,
|
||||
struct rb_root *tag_stat_tree)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
void prdebug_iface_stat_list(int indent_level,
|
||||
struct list_head *iface_stat_list)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
/*------------------------------------------*/
|
||||
const char *netdev_evt_str(int netdev_event);
|
||||
#endif /* ifndef __XT_QTAGUID_PRINT_H__ */
|
||||
Reference in New Issue
Block a user