Improved CTTUPLE macro with code from sched/act_connmark.c, so it be able to
get unNATed addresses from nf_conntrack.--- cls_flow.c 2015-11-02 02:05:25.0 +0200
+++ net/sched/cls_flow.c 2015-12-10 17:04:03.075202330 +0200
@@ -30,6 +30,8 @@
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include
+#include
+#include
#endif
struct flow_head {
@@ -132,16 +134,43 @@
}
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-#define CTTUPLE(skb, member) \
+#define CTTUPLE(skb, direction, member) \
({ \
enum ip_conntrack_info ctinfo; \
- const struct nf_conn *ct = nf_ct_get(skb, ); \
- if (ct == NULL) \
- goto fallback; \
- ct->tuplehash[CTINFO2DIR(ctinfo)].tuple.member; \
+ struct nf_conntrack_tuple tuple;\
+ struct nf_conntrack_zone zone; \
+ const struct nf_conntrack_tuple_hash *thash; \
+ __be32 result; \
+ int proto; \
+ struct nf_conn *ct = nf_ct_get(skb, ); \
+ if (ct == NULL){ \
+ switch (tc_skb_protocol(skb)) { \
+ case htons(ETH_P_IP):\
+ proto = NFPROTO_IPV4; \
+break; \
+ case htons(ETH_P_IPV6):\
+proto = NFPROTO_IPV6; \
+break; \
+ default: goto fallback;\
+ } \
+ \
+ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), proto, )) \
+goto fallback; \
+zone.id = NF_CT_DEFAULT_ZONE_ID;\
+zone.dir = NF_CT_DEFAULT_ZONE_DIR;\
+ \
+thash = nf_conntrack_find_get(dev_net(skb->dev), , );\
+if (!thash) goto fallback; \
+ct = nf_ct_tuplehash_to_ctrack(thash);\
+ result = ct->tuplehash[(thash->tuple.dst.dir == IP_CT_DIR_REPLY) ? IP_CT_DIR_ORIGINAL : IP_CT_DIR_REPLY].tuple.src.member; \
+ nf_ct_put(ct); \
+ } else { \
+ result = ct->tuplehash[CTINFO2DIR(ctinfo)].tuple.direction.member; \
+ }\
+ result;\
})
#else
-#define CTTUPLE(skb, member) \
+#define CTTUPLE(skb, direction, member) \
({ \
goto fallback; \
0;\
@@ -152,9 +181,9 @@
{
switch (tc_skb_protocol(skb)) {
case htons(ETH_P_IP):
- return ntohl(CTTUPLE(skb, src.u3.ip));
+ return ntohl(CTTUPLE(skb, src, u3.ip));
case htons(ETH_P_IPV6):
- return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
+ return ntohl(CTTUPLE(skb, src, u3.ip6[3]));
}
fallback:
return flow_get_src(skb, flow);
@@ -162,11 +191,12 @@
static u32 flow_get_nfct_dst(const struct sk_buff *skb, const struct flow_keys *flow)
{
+
switch (tc_skb_protocol(skb)) {
case htons(ETH_P_IP):
- return ntohl(CTTUPLE(skb, dst.u3.ip));
+ return ntohl(CTTUPLE(skb, dst, u3.ip));
case htons(ETH_P_IPV6):
- return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
+ return ntohl(CTTUPLE(skb, dst, u3.ip6[3]));
}
fallback:
return flow_get_dst(skb, flow);
@@ -174,14 +204,14 @@
static u32 flow_get_nfct_proto_src(const struct sk_buff *skb, const struct flow_keys *flow)
{
- return ntohs(CTTUPLE(skb, src.u.all));
+ return ntohs(CTTUPLE(skb, src, u.all));
fallback:
return flow_get_proto_src(skb, flow);
}
static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb, const struct flow_keys *flow)
{
- return ntohs(CTTUPLE(skb, dst.u.all));
+ return ntohs(CTTUPLE(skb, dst, u.all));
fallback:
return flow_get_proto_dst(skb, flow);
}