forked from mirrors/linux
		
	flow_dissector: Add flags argument to skb_flow_dissector functions
The flags argument will allow control of the dissection process (for instance whether to parse beyond L3). Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									a6e544b0a8
								
							
						
					
					
						commit
						cd79a2382a
					
				
					 9 changed files with 23 additions and 19 deletions
				
			
		| 
						 | 
				
			
			@ -3095,7 +3095,7 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
 | 
			
		|||
	int noff, proto = -1;
 | 
			
		||||
 | 
			
		||||
	if (bond->params.xmit_policy > BOND_XMIT_POLICY_LAYER23)
 | 
			
		||||
		return skb_flow_dissect_flow_keys(skb, fk);
 | 
			
		||||
		return skb_flow_dissect_flow_keys(skb, fk, 0);
 | 
			
		||||
 | 
			
		||||
	fk->ports.ports = 0;
 | 
			
		||||
	noff = skb_network_offset(skb);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -177,7 +177,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 | 
			
		|||
	int res, i;
 | 
			
		||||
 | 
			
		||||
	enic = netdev_priv(dev);
 | 
			
		||||
	res = skb_flow_dissect_flow_keys(skb, &keys);
 | 
			
		||||
	res = skb_flow_dissect_flow_keys(skb, &keys, 0);
 | 
			
		||||
	if (!res || keys.basic.n_proto != htons(ETH_P_IP) ||
 | 
			
		||||
	    (keys.basic.ip_proto != IPPROTO_TCP &&
 | 
			
		||||
	     keys.basic.ip_proto != IPPROTO_UDP))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,7 +239,7 @@ static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
 | 
			
		|||
	struct flow_keys flow;
 | 
			
		||||
	int data_len;
 | 
			
		||||
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys(skb, &flow) ||
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys(skb, &flow, 0) ||
 | 
			
		||||
	    !(flow.basic.n_proto == htons(ETH_P_IP) ||
 | 
			
		||||
	      flow.basic.n_proto == htons(ETH_P_IPV6)))
 | 
			
		||||
		return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -991,31 +991,34 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
 | 
			
		|||
bool __skb_flow_dissect(const struct sk_buff *skb,
 | 
			
		||||
			struct flow_dissector *flow_dissector,
 | 
			
		||||
			void *target_container,
 | 
			
		||||
			void *data, __be16 proto, int nhoff, int hlen);
 | 
			
		||||
			void *data, __be16 proto, int nhoff, int hlen,
 | 
			
		||||
			unsigned int flags);
 | 
			
		||||
 | 
			
		||||
static inline bool skb_flow_dissect(const struct sk_buff *skb,
 | 
			
		||||
				    struct flow_dissector *flow_dissector,
 | 
			
		||||
				    void *target_container)
 | 
			
		||||
				    void *target_container, unsigned int flags)
 | 
			
		||||
{
 | 
			
		||||
	return __skb_flow_dissect(skb, flow_dissector, target_container,
 | 
			
		||||
				  NULL, 0, 0, 0);
 | 
			
		||||
				  NULL, 0, 0, 0, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool skb_flow_dissect_flow_keys(const struct sk_buff *skb,
 | 
			
		||||
					      struct flow_keys *flow)
 | 
			
		||||
					      struct flow_keys *flow,
 | 
			
		||||
					      unsigned int flags)
 | 
			
		||||
{
 | 
			
		||||
	memset(flow, 0, sizeof(*flow));
 | 
			
		||||
	return __skb_flow_dissect(skb, &flow_keys_dissector, flow,
 | 
			
		||||
				  NULL, 0, 0, 0);
 | 
			
		||||
				  NULL, 0, 0, 0, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline bool skb_flow_dissect_flow_keys_buf(struct flow_keys *flow,
 | 
			
		||||
						  void *data, __be16 proto,
 | 
			
		||||
						  int nhoff, int hlen)
 | 
			
		||||
						  int nhoff, int hlen,
 | 
			
		||||
						  unsigned int flags)
 | 
			
		||||
{
 | 
			
		||||
	memset(flow, 0, sizeof(*flow));
 | 
			
		||||
	return __skb_flow_dissect(NULL, &flow_keys_buf_dissector, flow,
 | 
			
		||||
				  data, proto, nhoff, hlen);
 | 
			
		||||
				  data, proto, nhoff, hlen, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline __u32 skb_get_hash(struct sk_buff *skb)
 | 
			
		||||
| 
						 | 
				
			
			@ -2046,7 +2049,7 @@ static inline void skb_probe_transport_header(struct sk_buff *skb,
 | 
			
		|||
 | 
			
		||||
	if (skb_transport_header_was_set(skb))
 | 
			
		||||
		return;
 | 
			
		||||
	else if (skb_flow_dissect_flow_keys(skb, &keys))
 | 
			
		||||
	else if (skb_flow_dissect_flow_keys(skb, &keys, 0))
 | 
			
		||||
		skb_set_transport_header(skb, keys.control.thoff);
 | 
			
		||||
	else
 | 
			
		||||
		skb_set_transport_header(skb, offset_hint);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,8 @@ EXPORT_SYMBOL(__skb_flow_get_ports);
 | 
			
		|||
bool __skb_flow_dissect(const struct sk_buff *skb,
 | 
			
		||||
			struct flow_dissector *flow_dissector,
 | 
			
		||||
			void *target_container,
 | 
			
		||||
			void *data, __be16 proto, int nhoff, int hlen)
 | 
			
		||||
			void *data, __be16 proto, int nhoff, int hlen,
 | 
			
		||||
			unsigned int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct flow_dissector_key_control *key_control;
 | 
			
		||||
	struct flow_dissector_key_basic *key_basic;
 | 
			
		||||
| 
						 | 
				
			
			@ -556,7 +557,7 @@ EXPORT_SYMBOL(flow_hash_from_keys);
 | 
			
		|||
static inline u32 ___skb_get_hash(const struct sk_buff *skb,
 | 
			
		||||
				  struct flow_keys *keys, u32 keyval)
 | 
			
		||||
{
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys(skb, keys))
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys(skb, keys, 0))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return __flow_hash_from_keys(keys, keyval);
 | 
			
		||||
| 
						 | 
				
			
			@ -726,7 +727,7 @@ u32 skb_get_poff(const struct sk_buff *skb)
 | 
			
		|||
{
 | 
			
		||||
	struct flow_keys keys;
 | 
			
		||||
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys(skb, &keys))
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys(skb, &keys, 0))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ u32 eth_get_headlen(void *data, unsigned int len)
 | 
			
		|||
 | 
			
		||||
	/* parse any remaining L2/L3 headers, check for L4 */
 | 
			
		||||
	if (!skb_flow_dissect_flow_keys_buf(&keys, data, eth->h_proto,
 | 
			
		||||
					    sizeof(*eth), len))
 | 
			
		||||
					    sizeof(*eth), len, 0))
 | 
			
		||||
		return max_t(u32, keys.control.thoff, sizeof(*eth));
 | 
			
		||||
 | 
			
		||||
	/* parse for any L4 headers */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -301,7 +301,7 @@ static int flow_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 | 
			
		|||
 | 
			
		||||
		keymask = f->keymask;
 | 
			
		||||
		if (keymask & FLOW_KEYS_NEEDED)
 | 
			
		||||
			skb_flow_dissect_flow_keys(skb, &flow_keys);
 | 
			
		||||
			skb_flow_dissect_flow_keys(skb, &flow_keys, 0);
 | 
			
		||||
 | 
			
		||||
		for (n = 0; n < f->nkeys; n++) {
 | 
			
		||||
			key = ffs(keymask) - 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,7 +129,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
 | 
			
		|||
	 * so do it rather here.
 | 
			
		||||
	 */
 | 
			
		||||
	skb_key.basic.n_proto = skb->protocol;
 | 
			
		||||
	skb_flow_dissect(skb, &head->dissector, &skb_key);
 | 
			
		||||
	skb_flow_dissect(skb, &head->dissector, &skb_key, 0);
 | 
			
		||||
 | 
			
		||||
	fl_set_masked_key(&skb_mkey, &skb_key, &head->mask);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,13 +170,13 @@ static bool choke_match_flow(struct sk_buff *skb1,
 | 
			
		|||
 | 
			
		||||
	if (!choke_skb_cb(skb1)->keys_valid) {
 | 
			
		||||
		choke_skb_cb(skb1)->keys_valid = 1;
 | 
			
		||||
		skb_flow_dissect_flow_keys(skb1, &temp);
 | 
			
		||||
		skb_flow_dissect_flow_keys(skb1, &temp, 0);
 | 
			
		||||
		make_flow_keys_digest(&choke_skb_cb(skb1)->keys, &temp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!choke_skb_cb(skb2)->keys_valid) {
 | 
			
		||||
		choke_skb_cb(skb2)->keys_valid = 1;
 | 
			
		||||
		skb_flow_dissect_flow_keys(skb2, &temp);
 | 
			
		||||
		skb_flow_dissect_flow_keys(skb2, &temp, 0);
 | 
			
		||||
		make_flow_keys_digest(&choke_skb_cb(skb2)->keys, &temp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue