diff mbox

sched/cls_flow.c : allow nfct-* keys work on ingress interfaces

Message ID 1498271449753849@web15j.yandex.ru
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Гаврилов Игорь Dec. 10, 2015, 1:24 p.m. UTC
Improved CTTUPLE macro with code from sched/act_connmark.c, so it be able to get unNATed addresses from nf_conntrack.

Comments

Cong Wang Dec. 10, 2015, 6:46 p.m. UTC | #1
Hello,

On Thu, Dec 10, 2015 at 5:24 AM, Гаврилов Игорь <iggorok@yandex.ua> wrote:
> Improved CTTUPLE macro with code from sched/act_connmark.c, so it be able to get unNATed addresses from nf_conntrack.

Please follow the guideline to submit a formal kernel patch:
https://www.kernel.org/doc/Documentation/SubmittingPatches

Hints:
a) The patch has to be inlined
b) You have to sign it off
c) Please Cc the maintainers, in this case, Jamal Hadi Salim <jhs@mojatatu.com>
d) Use checkpatch.pl to check coding styles etc.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- cls_flow.c	2015-11-02 02:05:25.000000000 +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 <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_zones.h>
 #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, &ctinfo);		\
-	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, &ctinfo);			\
+	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, &tuple)) \
+                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), &zone, &tuple);\
+        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);
 }