netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 3/4] cls_flow: use skb_flow_dissect()
@ 2011-11-28 15:24 Eric Dumazet
  2011-11-29  0:10 ` David Miller
  2011-12-03 15:42 ` Dan Siemon
  0 siblings, 2 replies; 3+ messages in thread
From: Eric Dumazet @ 2011-11-28 15:24 UTC (permalink / raw)
  To: David Miller
  Cc: chrisw-H+wXaHxf7aLQT0dZR+AlfA, dev-yBygre7rU0TnMu66kgdUjQ, netdev,
	Florian Westphal, jhs-jkUAjuhPggJWk0Htik3J/w,
	john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
	herbert-F6s6mLieUQo7FNHlEwC/lvQIK84fMopw, Stephen Hemminger,
	Dan Siemon

Instead of using a custom flow dissector, use skb_flow_dissect() and
benefit from tunnelling support.

This lack of tunnelling support was mentioned by Dan Siemon.

Signed-off-by: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 net/sched/cls_flow.c |  180 ++++++++++-------------------------------
 1 file changed, 48 insertions(+), 132 deletions(-)

diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 7b58230..a120ec5 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -26,6 +26,8 @@
 #include <net/pkt_cls.h>
 #include <net/ip.h>
 #include <net/route.h>
+#include <net/flow_keys.h>
+
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 #include <net/netfilter/nf_conntrack.h>
 #endif
@@ -66,134 +68,37 @@ static inline u32 addr_fold(void *addr)
 	return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
 }
 
-static u32 flow_get_src(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_src(const struct sk_buff *skb, const struct flow_keys *flow)
 {
-	__be32 *data = NULL, hdata;
-
-	switch (skb->protocol) {
-	case htons(ETH_P_IP):
-		data = skb_header_pointer(skb,
-					  nhoff + offsetof(struct iphdr,
-							   saddr),
-					  4, &hdata);
-		break;
-	case htons(ETH_P_IPV6):
-		data = skb_header_pointer(skb,
-					 nhoff + offsetof(struct ipv6hdr,
-							  saddr.s6_addr32[3]),
-					 4, &hdata);
-		break;
-	}
-
-	if (data)
-		return ntohl(*data);
+	if (flow->src)
+		return ntohl(flow->src);
 	return addr_fold(skb->sk);
 }
 
-static u32 flow_get_dst(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_dst(const struct sk_buff *skb, const struct flow_keys *flow)
 {
-	__be32 *data = NULL, hdata;
-
-	switch (skb->protocol) {
-	case htons(ETH_P_IP):
-		data = skb_header_pointer(skb,
-					  nhoff + offsetof(struct iphdr,
-							   daddr),
-					  4, &hdata);
-		break;
-	case htons(ETH_P_IPV6):
-		data = skb_header_pointer(skb,
-					 nhoff + offsetof(struct ipv6hdr,
-							  daddr.s6_addr32[3]),
-					 4, &hdata);
-		break;
-	}
-
-	if (data)
-		return ntohl(*data);
+	if (flow->dst)
+		return ntohl(flow->dst);
 	return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
 }
 
-static u32 flow_get_proto(const struct sk_buff *skb, int nhoff)
-{
-	__u8 *data = NULL, hdata;
-
-	switch (skb->protocol) {
-	case htons(ETH_P_IP):
-		data = skb_header_pointer(skb,
-					  nhoff + offsetof(struct iphdr,
-							   protocol),
-					  1, &hdata);
-		break;
-	case htons(ETH_P_IPV6):
-		data = skb_header_pointer(skb,
-					 nhoff + offsetof(struct ipv6hdr,
-							  nexthdr),
-					 1, &hdata);
-		break;
-	}
-	if (data)
-		return *data;
-	return 0;
-}
-
-/* helper function to get either src or dst port */
-static __be16 *flow_get_proto_common(const struct sk_buff *skb, int nhoff,
-				     __be16 *_port, int dst)
+static u32 flow_get_proto(const struct sk_buff *skb, const struct flow_keys *flow)
 {
-	__be16 *port = NULL;
-	int poff;
-
-	switch (skb->protocol) {
-	case htons(ETH_P_IP): {
-		struct iphdr *iph, _iph;
-
-		iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
-		if (!iph)
-			break;
-		if (ip_is_fragment(iph))
-			break;
-		poff = proto_ports_offset(iph->protocol);
-		if (poff >= 0)
-			port = skb_header_pointer(skb,
-					nhoff + iph->ihl * 4 + poff + dst,
-					sizeof(*_port), _port);
-		break;
-	}
-	case htons(ETH_P_IPV6): {
-		struct ipv6hdr *iph, _iph;
-
-		iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
-		if (!iph)
-			break;
-		poff = proto_ports_offset(iph->nexthdr);
-		if (poff >= 0)
-			port = skb_header_pointer(skb,
-					nhoff + sizeof(*iph) + poff + dst,
-					sizeof(*_port), _port);
-		break;
-	}
-	}
-
-	return port;
+	return flow->ip_proto;
 }
 
-static u32 flow_get_proto_src(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_proto_src(const struct sk_buff *skb, const struct flow_keys *flow)
 {
-	__be16 _port, *port = flow_get_proto_common(skb, nhoff, &_port, 0);
-
-	if (port)
-		return ntohs(*port);
+	if (flow->ports)
+		return ntohs(flow->port16[0]);
 
 	return addr_fold(skb->sk);
 }
 
-static u32 flow_get_proto_dst(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_proto_dst(const struct sk_buff *skb, const struct flow_keys *flow)
 {
-	__be16 _port, *port = flow_get_proto_common(skb, nhoff, &_port, 2);
-
-	if (port)
-		return ntohs(*port);
+	if (flow->ports)
+		return ntohs(flow->port16[1]);
 
 	return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
 }
@@ -239,7 +144,7 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
 })
 #endif
 
-static u32 flow_get_nfct_src(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_nfct_src(const struct sk_buff *skb, const struct flow_keys *flow)
 {
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
@@ -248,10 +153,10 @@ static u32 flow_get_nfct_src(const struct sk_buff *skb, int nhoff)
 		return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
 	}
 fallback:
-	return flow_get_src(skb, nhoff);
+	return flow_get_src(skb, flow);
 }
 
-static u32 flow_get_nfct_dst(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_nfct_dst(const struct sk_buff *skb, const struct flow_keys *flow)
 {
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
@@ -260,21 +165,21 @@ static u32 flow_get_nfct_dst(const struct sk_buff *skb, int nhoff)
 		return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
 	}
 fallback:
-	return flow_get_dst(skb, nhoff);
+	return flow_get_dst(skb, flow);
 }
 
-static u32 flow_get_nfct_proto_src(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_nfct_proto_src(const struct sk_buff *skb, const struct flow_keys *flow)
 {
 	return ntohs(CTTUPLE(skb, src.u.all));
 fallback:
-	return flow_get_proto_src(skb, nhoff);
+	return flow_get_proto_src(skb, flow);
 }
 
-static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb, int nhoff)
+static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb, const struct flow_keys *flow)
 {
 	return ntohs(CTTUPLE(skb, dst.u.all));
 fallback:
-	return flow_get_proto_dst(skb, nhoff);
+	return flow_get_proto_dst(skb, flow);
 }
 
 static u32 flow_get_rtclassid(const struct sk_buff *skb)
@@ -314,21 +219,19 @@ static u32 flow_get_rxhash(struct sk_buff *skb)
 	return skb_get_rxhash(skb);
 }
 
-static u32 flow_key_get(struct sk_buff *skb, int key)
+static u32 flow_key_get(struct sk_buff *skb, int key, struct flow_keys *flow)
 {
-	int nhoff = skb_network_offset(skb);
-
 	switch (key) {
 	case FLOW_KEY_SRC:
-		return flow_get_src(skb, nhoff);
+		return flow_get_src(skb, flow);
 	case FLOW_KEY_DST:
-		return flow_get_dst(skb, nhoff);
+		return flow_get_dst(skb, flow);
 	case FLOW_KEY_PROTO:
-		return flow_get_proto(skb, nhoff);
+		return flow_get_proto(skb, flow);
 	case FLOW_KEY_PROTO_SRC:
-		return flow_get_proto_src(skb, nhoff);
+		return flow_get_proto_src(skb, flow);
 	case FLOW_KEY_PROTO_DST:
-		return flow_get_proto_dst(skb, nhoff);
+		return flow_get_proto_dst(skb, flow);
 	case FLOW_KEY_IIF:
 		return flow_get_iif(skb);
 	case FLOW_KEY_PRIORITY:
@@ -338,13 +241,13 @@ static u32 flow_key_get(struct sk_buff *skb, int key)
 	case FLOW_KEY_NFCT:
 		return flow_get_nfct(skb);
 	case FLOW_KEY_NFCT_SRC:
-		return flow_get_nfct_src(skb, nhoff);
+		return flow_get_nfct_src(skb, flow);
 	case FLOW_KEY_NFCT_DST:
-		return flow_get_nfct_dst(skb, nhoff);
+		return flow_get_nfct_dst(skb, flow);
 	case FLOW_KEY_NFCT_PROTO_SRC:
-		return flow_get_nfct_proto_src(skb, nhoff);
+		return flow_get_nfct_proto_src(skb, flow);
 	case FLOW_KEY_NFCT_PROTO_DST:
-		return flow_get_nfct_proto_dst(skb, nhoff);
+		return flow_get_nfct_proto_dst(skb, flow);
 	case FLOW_KEY_RTCLASSID:
 		return flow_get_rtclassid(skb);
 	case FLOW_KEY_SKUID:
@@ -361,6 +264,16 @@ static u32 flow_key_get(struct sk_buff *skb, int key)
 	}
 }
 
+#define FLOW_KEYS_NEEDED ((1 << FLOW_KEY_SRC) | 		\
+			  (1 << FLOW_KEY_DST) |			\
+			  (1 << FLOW_KEY_PROTO) |		\
+			  (1 << FLOW_KEY_PROTO_SRC) |		\
+			  (1 << FLOW_KEY_PROTO_DST) | 		\
+			  (1 << FLOW_KEY_NFCT_SRC) |		\
+			  (1 << FLOW_KEY_NFCT_DST) |		\
+			  (1 << FLOW_KEY_NFCT_PROTO_SRC) |	\
+			  (1 << FLOW_KEY_NFCT_PROTO_DST))
+ 
 static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 			 struct tcf_result *res)
 {
@@ -373,16 +286,19 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 
 	list_for_each_entry(f, &head->filters, list) {
 		u32 keys[f->nkeys];
+		struct flow_keys flow_keys;
 
 		if (!tcf_em_tree_match(skb, &f->ematches, NULL))
 			continue;
 
 		keymask = f->keymask;
+		if (keymask & FLOW_KEYS_NEEDED)
+			skb_flow_dissect(skb, &flow_keys);
 
 		for (n = 0; n < f->nkeys; n++) {
 			key = ffs(keymask) - 1;
 			keymask &= ~(1 << key);
-			keys[n] = flow_key_get(skb, key);
+			keys[n] = flow_key_get(skb, key, &flow_keys);
 		}
 
 		if (f->mode == FLOW_MODE_HASH)

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net-next 3/4] cls_flow: use skb_flow_dissect()
  2011-11-28 15:24 [PATCH net-next 3/4] cls_flow: use skb_flow_dissect() Eric Dumazet
@ 2011-11-29  0:10 ` David Miller
  2011-12-03 15:42 ` Dan Siemon
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2011-11-29  0:10 UTC (permalink / raw)
  To: eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w
  Cc: chrisw-H+wXaHxf7aLQT0dZR+AlfA, dev-yBygre7rU0TnMu66kgdUjQ,
	netdev-u79uwXL29TY76Z2rM5mHXA, fw-HFFVJYpyMKqzQB+pC5nmwQ,
	jhs-jkUAjuhPggJWk0Htik3J/w,
	john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
	herbert-F6s6mLieUQo7FNHlEwC/lvQIK84fMopw,
	shemminger-ZtmgI6mnKB3QT0dZR+AlfA, dan-BZ4SNL/Vixll57MIdRCFDg

From: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Mon, 28 Nov 2011 16:24:18 +0100

> Instead of using a custom flow dissector, use skb_flow_dissect() and
> benefit from tunnelling support.
> 
> This lack of tunnelling support was mentioned by Dan Siemon.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Applied.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net-next 3/4] cls_flow: use skb_flow_dissect()
  2011-11-28 15:24 [PATCH net-next 3/4] cls_flow: use skb_flow_dissect() Eric Dumazet
  2011-11-29  0:10 ` David Miller
@ 2011-12-03 15:42 ` Dan Siemon
  1 sibling, 0 replies; 3+ messages in thread
From: Dan Siemon @ 2011-12-03 15:42 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: chrisw-H+wXaHxf7aLQT0dZR+AlfA, dev-yBygre7rU0TnMu66kgdUjQ, netdev,
	Florian Westphal, jhs-jkUAjuhPggJWk0Htik3J/w,
	john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w,
	herbert-F6s6mLieUQo7FNHlEwC/lvQIK84fMopw, Stephen Hemminger,
	David Miller


[-- Attachment #1.1: Type: text/plain, Size: 10679 bytes --]

On Mon, 2011-11-28 at 16:24 +0100, Eric Dumazet wrote:
> Instead of using a custom flow dissector, use skb_flow_dissect() and
> benefit from tunnelling support.
> 
> This lack of tunnelling support was mentioned by Dan Siemon.

Thanks Eric. I don't think having the existing keys automatically use
inner tunnel headers meets some key use cases - this is why I had
separate keys in my patch. The most common situation this will cause
trouble is when the admin wants to enforce per-host fairness using the
src or dst keywords. Automatically including the inner headers means any
user behind the router can easily escape from the desired limitations
just by running traffic through a tunnel. Also, I expect the perf hit is
small but in 95% of deployments people won't actually want to look at
the inner headers so it may not make sense to do this for every packet.

Thanks for making a better version of my patch.

> Signed-off-by: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  net/sched/cls_flow.c |  180 ++++++++++-------------------------------
>  1 file changed, 48 insertions(+), 132 deletions(-)
> 
> diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
> index 7b58230..a120ec5 100644
> --- a/net/sched/cls_flow.c
> +++ b/net/sched/cls_flow.c
> @@ -26,6 +26,8 @@
>  #include <net/pkt_cls.h>
>  #include <net/ip.h>
>  #include <net/route.h>
> +#include <net/flow_keys.h>
> +
>  #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
>  #include <net/netfilter/nf_conntrack.h>
>  #endif
> @@ -66,134 +68,37 @@ static inline u32 addr_fold(void *addr)
>  	return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
>  }
>  
> -static u32 flow_get_src(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_src(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
> -	__be32 *data = NULL, hdata;
> -
> -	switch (skb->protocol) {
> -	case htons(ETH_P_IP):
> -		data = skb_header_pointer(skb,
> -					  nhoff + offsetof(struct iphdr,
> -							   saddr),
> -					  4, &hdata);
> -		break;
> -	case htons(ETH_P_IPV6):
> -		data = skb_header_pointer(skb,
> -					 nhoff + offsetof(struct ipv6hdr,
> -							  saddr.s6_addr32[3]),
> -					 4, &hdata);
> -		break;
> -	}
> -
> -	if (data)
> -		return ntohl(*data);
> +	if (flow->src)
> +		return ntohl(flow->src);
>  	return addr_fold(skb->sk);
>  }
>  
> -static u32 flow_get_dst(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_dst(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
> -	__be32 *data = NULL, hdata;
> -
> -	switch (skb->protocol) {
> -	case htons(ETH_P_IP):
> -		data = skb_header_pointer(skb,
> -					  nhoff + offsetof(struct iphdr,
> -							   daddr),
> -					  4, &hdata);
> -		break;
> -	case htons(ETH_P_IPV6):
> -		data = skb_header_pointer(skb,
> -					 nhoff + offsetof(struct ipv6hdr,
> -							  daddr.s6_addr32[3]),
> -					 4, &hdata);
> -		break;
> -	}
> -
> -	if (data)
> -		return ntohl(*data);
> +	if (flow->dst)
> +		return ntohl(flow->dst);
>  	return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
>  }
>  
> -static u32 flow_get_proto(const struct sk_buff *skb, int nhoff)
> -{
> -	__u8 *data = NULL, hdata;
> -
> -	switch (skb->protocol) {
> -	case htons(ETH_P_IP):
> -		data = skb_header_pointer(skb,
> -					  nhoff + offsetof(struct iphdr,
> -							   protocol),
> -					  1, &hdata);
> -		break;
> -	case htons(ETH_P_IPV6):
> -		data = skb_header_pointer(skb,
> -					 nhoff + offsetof(struct ipv6hdr,
> -							  nexthdr),
> -					 1, &hdata);
> -		break;
> -	}
> -	if (data)
> -		return *data;
> -	return 0;
> -}
> -
> -/* helper function to get either src or dst port */
> -static __be16 *flow_get_proto_common(const struct sk_buff *skb, int nhoff,
> -				     __be16 *_port, int dst)
> +static u32 flow_get_proto(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
> -	__be16 *port = NULL;
> -	int poff;
> -
> -	switch (skb->protocol) {
> -	case htons(ETH_P_IP): {
> -		struct iphdr *iph, _iph;
> -
> -		iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
> -		if (!iph)
> -			break;
> -		if (ip_is_fragment(iph))
> -			break;
> -		poff = proto_ports_offset(iph->protocol);
> -		if (poff >= 0)
> -			port = skb_header_pointer(skb,
> -					nhoff + iph->ihl * 4 + poff + dst,
> -					sizeof(*_port), _port);
> -		break;
> -	}
> -	case htons(ETH_P_IPV6): {
> -		struct ipv6hdr *iph, _iph;
> -
> -		iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
> -		if (!iph)
> -			break;
> -		poff = proto_ports_offset(iph->nexthdr);
> -		if (poff >= 0)
> -			port = skb_header_pointer(skb,
> -					nhoff + sizeof(*iph) + poff + dst,
> -					sizeof(*_port), _port);
> -		break;
> -	}
> -	}
> -
> -	return port;
> +	return flow->ip_proto;
>  }
>  
> -static u32 flow_get_proto_src(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_proto_src(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
> -	__be16 _port, *port = flow_get_proto_common(skb, nhoff, &_port, 0);
> -
> -	if (port)
> -		return ntohs(*port);
> +	if (flow->ports)
> +		return ntohs(flow->port16[0]);
>  
>  	return addr_fold(skb->sk);
>  }
>  
> -static u32 flow_get_proto_dst(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_proto_dst(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
> -	__be16 _port, *port = flow_get_proto_common(skb, nhoff, &_port, 2);
> -
> -	if (port)
> -		return ntohs(*port);
> +	if (flow->ports)
> +		return ntohs(flow->port16[1]);
>  
>  	return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
>  }
> @@ -239,7 +144,7 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
>  })
>  #endif
>  
> -static u32 flow_get_nfct_src(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_nfct_src(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
>  	switch (skb->protocol) {
>  	case htons(ETH_P_IP):
> @@ -248,10 +153,10 @@ static u32 flow_get_nfct_src(const struct sk_buff *skb, int nhoff)
>  		return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
>  	}
>  fallback:
> -	return flow_get_src(skb, nhoff);
> +	return flow_get_src(skb, flow);
>  }
>  
> -static u32 flow_get_nfct_dst(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_nfct_dst(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
>  	switch (skb->protocol) {
>  	case htons(ETH_P_IP):
> @@ -260,21 +165,21 @@ static u32 flow_get_nfct_dst(const struct sk_buff *skb, int nhoff)
>  		return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
>  	}
>  fallback:
> -	return flow_get_dst(skb, nhoff);
> +	return flow_get_dst(skb, flow);
>  }
>  
> -static u32 flow_get_nfct_proto_src(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_nfct_proto_src(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
>  	return ntohs(CTTUPLE(skb, src.u.all));
>  fallback:
> -	return flow_get_proto_src(skb, nhoff);
> +	return flow_get_proto_src(skb, flow);
>  }
>  
> -static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb, int nhoff)
> +static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb, const struct flow_keys *flow)
>  {
>  	return ntohs(CTTUPLE(skb, dst.u.all));
>  fallback:
> -	return flow_get_proto_dst(skb, nhoff);
> +	return flow_get_proto_dst(skb, flow);
>  }
>  
>  static u32 flow_get_rtclassid(const struct sk_buff *skb)
> @@ -314,21 +219,19 @@ static u32 flow_get_rxhash(struct sk_buff *skb)
>  	return skb_get_rxhash(skb);
>  }
>  
> -static u32 flow_key_get(struct sk_buff *skb, int key)
> +static u32 flow_key_get(struct sk_buff *skb, int key, struct flow_keys *flow)
>  {
> -	int nhoff = skb_network_offset(skb);
> -
>  	switch (key) {
>  	case FLOW_KEY_SRC:
> -		return flow_get_src(skb, nhoff);
> +		return flow_get_src(skb, flow);
>  	case FLOW_KEY_DST:
> -		return flow_get_dst(skb, nhoff);
> +		return flow_get_dst(skb, flow);
>  	case FLOW_KEY_PROTO:
> -		return flow_get_proto(skb, nhoff);
> +		return flow_get_proto(skb, flow);
>  	case FLOW_KEY_PROTO_SRC:
> -		return flow_get_proto_src(skb, nhoff);
> +		return flow_get_proto_src(skb, flow);
>  	case FLOW_KEY_PROTO_DST:
> -		return flow_get_proto_dst(skb, nhoff);
> +		return flow_get_proto_dst(skb, flow);
>  	case FLOW_KEY_IIF:
>  		return flow_get_iif(skb);
>  	case FLOW_KEY_PRIORITY:
> @@ -338,13 +241,13 @@ static u32 flow_key_get(struct sk_buff *skb, int key)
>  	case FLOW_KEY_NFCT:
>  		return flow_get_nfct(skb);
>  	case FLOW_KEY_NFCT_SRC:
> -		return flow_get_nfct_src(skb, nhoff);
> +		return flow_get_nfct_src(skb, flow);
>  	case FLOW_KEY_NFCT_DST:
> -		return flow_get_nfct_dst(skb, nhoff);
> +		return flow_get_nfct_dst(skb, flow);
>  	case FLOW_KEY_NFCT_PROTO_SRC:
> -		return flow_get_nfct_proto_src(skb, nhoff);
> +		return flow_get_nfct_proto_src(skb, flow);
>  	case FLOW_KEY_NFCT_PROTO_DST:
> -		return flow_get_nfct_proto_dst(skb, nhoff);
> +		return flow_get_nfct_proto_dst(skb, flow);
>  	case FLOW_KEY_RTCLASSID:
>  		return flow_get_rtclassid(skb);
>  	case FLOW_KEY_SKUID:
> @@ -361,6 +264,16 @@ static u32 flow_key_get(struct sk_buff *skb, int key)
>  	}
>  }
>  
> +#define FLOW_KEYS_NEEDED ((1 << FLOW_KEY_SRC) | 		\
> +			  (1 << FLOW_KEY_DST) |			\
> +			  (1 << FLOW_KEY_PROTO) |		\
> +			  (1 << FLOW_KEY_PROTO_SRC) |		\
> +			  (1 << FLOW_KEY_PROTO_DST) | 		\
> +			  (1 << FLOW_KEY_NFCT_SRC) |		\
> +			  (1 << FLOW_KEY_NFCT_DST) |		\
> +			  (1 << FLOW_KEY_NFCT_PROTO_SRC) |	\
> +			  (1 << FLOW_KEY_NFCT_PROTO_DST))
> + 
>  static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
>  			 struct tcf_result *res)
>  {
> @@ -373,16 +286,19 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
>  
>  	list_for_each_entry(f, &head->filters, list) {
>  		u32 keys[f->nkeys];
> +		struct flow_keys flow_keys;
>  
>  		if (!tcf_em_tree_match(skb, &f->ematches, NULL))
>  			continue;
>  
>  		keymask = f->keymask;
> +		if (keymask & FLOW_KEYS_NEEDED)
> +			skb_flow_dissect(skb, &flow_keys);
>  
>  		for (n = 0; n < f->nkeys; n++) {
>  			key = ffs(keymask) - 1;
>  			keymask &= ~(1 << key);
> -			keys[n] = flow_key_get(skb, key);
> +			keys[n] = flow_key_get(skb, key, &flow_keys);
>  		}
>  
>  		if (f->mode == FLOW_MODE_HASH)
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-12-03 15:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-28 15:24 [PATCH net-next 3/4] cls_flow: use skb_flow_dissect() Eric Dumazet
2011-11-29  0:10 ` David Miller
2011-12-03 15:42 ` Dan Siemon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).