summaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2012-04-17 16:00:07 -0700
committerArve Hjønnevåg <arve@android.com>2013-07-01 13:40:42 -0700
commit8b041edbc71b48e75db68eeeb8673991abbc885d (patch)
tree318507c98b802a8632254c067796d5f3a7f00807 /net/netfilter
parentcc53cb8db65cc890148364ae6812ae46ef444554 (diff)
netfilter: xt_qtaguid: fix ipv6 protocol lookup
When updating the stats for a given uid it would incorrectly assume IPV4 and pick up the wrong protocol when IPV6. Change-Id: Iea4a635012b4123bf7aa93809011b7b2040bb3d5 Signed-off-by: JP Abgrall <jpa@google.com>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/xt_qtaguid.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 3d3928291efb..2c1170f89d0f 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -26,6 +26,10 @@
#include <net/tcp.h>
#include <net/udp.h>
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#endif
+
#include <linux/netfilter/xt_socket.h>
#include "xt_qtaguid_internal.h"
#include "xt_qtaguid_print.h"
@@ -1546,6 +1550,27 @@ static struct sock *qtaguid_find_sk(const struct sk_buff *skb,
return sk;
}
+static int ipx_proto(const struct sk_buff *skb,
+ struct xt_action_param *par)
+{
+ int thoff = 0, tproto;
+
+ switch (par->family) {
+ case NFPROTO_IPV6:
+ tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
+ if (tproto < 0)
+ MT_DEBUG("%s(): transport header not found in ipv6"
+ " skb=%p\n", __func__, skb);
+ break;
+ case NFPROTO_IPV4:
+ tproto = ip_hdr(skb)->protocol;
+ break;
+ default:
+ tproto = IPPROTO_RAW;
+ }
+ return tproto;
+}
+
static void account_for_uid(const struct sk_buff *skb,
const struct sock *alternate_sk, uid_t uid,
struct xt_action_param *par)
@@ -1572,15 +1597,15 @@ static void account_for_uid(const struct sk_buff *skb,
} else if (unlikely(!el_dev->name)) {
pr_info("qtaguid[%d]: no dev->name?!!\n", par->hooknum);
} else {
- MT_DEBUG("qtaguid[%d]: dev name=%s type=%d\n",
- par->hooknum,
- el_dev->name,
- el_dev->type);
+ int proto = ipx_proto(skb, par);
+ MT_DEBUG("qtaguid[%d]: dev name=%s type=%d fam=%d proto=%d\n",
+ par->hooknum, el_dev->name, el_dev->type,
+ par->family, proto);
if_tag_stat_update(el_dev->name, uid,
skb->sk ? skb->sk : alternate_sk,
par->in ? IFS_RX : IFS_TX,
- ip_hdr(skb)->protocol, skb->len);
+ proto, skb->len);
}
}
@@ -1625,8 +1650,8 @@ static bool qtaguid_mt(const struct sk_buff *skb, struct xt_action_param *par)
} 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);
+ MT_DEBUG("qtaguid[%d]: sk=%p got_sock=%d fam=%d proto=%d\n",
+ par->hooknum, sk, got_sock, par->family, ipx_proto(skb, par));
if (sk != NULL) {
MT_DEBUG("qtaguid[%d]: sk=%p->sk_socket=%p->file=%p\n",
par->hooknum, sk, sk->sk_socket,