forked from mirrors/linux
		
	route: Add multipath_hash in flowi_common to make user-define hash
Current fib_multipath_hash_policy can make hash based on the L3 or L4. But it only work on the outer IP. So a specific tunnel always has the same hash value. But a specific tunnel may contain so many inner connections. This patch provide a generic multipath_hash in floi_common. It can make a user-define hash which can mix with L3 or L4 hash. Signed-off-by: wenxu <wenxu@ucloud.cn> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									8f4ef499c6
								
							
						
					
					
						commit
						24ba14406c
					
				
					 6 changed files with 13 additions and 6 deletions
				
			
		|  | @ -305,7 +305,7 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev, | |||
| 
 | ||||
| 	parms = mlxsw_sp_ipip_netdev_parms4(to_dev); | ||||
| 	ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, | ||||
| 			    0, 0, parms.link, tun->fwmark); | ||||
| 			    0, 0, parms.link, tun->fwmark, 0); | ||||
| 
 | ||||
| 	rt = ip_route_output_key(tun->net, &fl4); | ||||
| 	if (IS_ERR(rt)) | ||||
|  |  | |||
|  | @ -40,6 +40,7 @@ struct flowi_common { | |||
| 	__u32	flowic_secid; | ||||
| 	kuid_t  flowic_uid; | ||||
| 	struct flowi_tunnel flowic_tun_key; | ||||
| 	__u32		flowic_multipath_hash; | ||||
| }; | ||||
| 
 | ||||
| union flowi_uli { | ||||
|  | @ -78,6 +79,7 @@ struct flowi4 { | |||
| #define flowi4_secid		__fl_common.flowic_secid | ||||
| #define flowi4_tun_key		__fl_common.flowic_tun_key | ||||
| #define flowi4_uid		__fl_common.flowic_uid | ||||
| #define flowi4_multipath_hash	__fl_common.flowic_multipath_hash | ||||
| 
 | ||||
| 	/* (saddr,daddr) must be grouped, same order as in IP header */ | ||||
| 	__be32			saddr; | ||||
|  |  | |||
|  | @ -241,7 +241,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4, | |||
| 				       int proto, | ||||
| 				       __be32 daddr, __be32 saddr, | ||||
| 				       __be32 key, __u8 tos, int oif, | ||||
| 				       __u32 mark) | ||||
| 				       __u32 mark, __u32 tun_inner_hash) | ||||
| { | ||||
| 	memset(fl4, 0, sizeof(*fl4)); | ||||
| 	fl4->flowi4_oif = oif; | ||||
|  | @ -251,6 +251,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4, | |||
| 	fl4->flowi4_proto = proto; | ||||
| 	fl4->fl4_gre_key = key; | ||||
| 	fl4->flowi4_mark = mark; | ||||
| 	fl4->flowi4_multipath_hash = tun_inner_hash; | ||||
| } | ||||
| 
 | ||||
| int ip_tunnel_init(struct net_device *dev); | ||||
|  |  | |||
|  | @ -578,7 +578,7 @@ static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) | |||
| 	key = &info->key; | ||||
| 	ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, | ||||
| 			    tunnel_id_to_key32(key->tun_id), key->tos, 0, | ||||
| 			    skb->mark); | ||||
| 			    skb->mark, skb_get_hash(skb)); | ||||
| 	rt = ip_route_output_key(dev_net(dev), &fl4); | ||||
| 	if (IS_ERR(rt)) | ||||
| 		return PTR_ERR(rt); | ||||
|  |  | |||
|  | @ -310,7 +310,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) | |||
| 		ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, | ||||
| 				    iph->saddr, tunnel->parms.o_key, | ||||
| 				    RT_TOS(iph->tos), tunnel->parms.link, | ||||
| 				    tunnel->fwmark); | ||||
| 				    tunnel->fwmark, 0); | ||||
| 		rt = ip_route_output_key(tunnel->net, &fl4); | ||||
| 
 | ||||
| 		if (!IS_ERR(rt)) { | ||||
|  | @ -584,7 +584,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 	} | ||||
| 	ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, | ||||
| 			    tunnel_id_to_key32(key->tun_id), RT_TOS(tos), | ||||
| 			    0, skb->mark); | ||||
| 			    0, skb->mark, skb_get_hash(skb)); | ||||
| 	if (tunnel->encap.type != TUNNEL_ENCAP_NONE) | ||||
| 		goto tx_error; | ||||
| 
 | ||||
|  | @ -744,7 +744,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 
 | ||||
| 	ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, | ||||
| 			    tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link, | ||||
| 			    tunnel->fwmark); | ||||
| 			    tunnel->fwmark, skb_get_hash(skb)); | ||||
| 
 | ||||
| 	if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) | ||||
| 		goto tx_error; | ||||
|  |  | |||
|  | @ -1820,6 +1820,7 @@ static void ip_multipath_l3_keys(const struct sk_buff *skb, | |||
| int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, | ||||
| 		       const struct sk_buff *skb, struct flow_keys *flkeys) | ||||
| { | ||||
| 	u32 multipath_hash = fl4->flowi4_multipath_hash; | ||||
| 	struct flow_keys hash_keys; | ||||
| 	u32 mhash; | ||||
| 
 | ||||
|  | @ -1870,6 +1871,9 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, | |||
| 	} | ||||
| 	mhash = flow_hash_from_keys(&hash_keys); | ||||
| 
 | ||||
| 	if (multipath_hash) | ||||
| 		mhash = jhash_2words(mhash, multipath_hash, 0); | ||||
| 
 | ||||
| 	return mhash >> 1; | ||||
| } | ||||
| #endif /* CONFIG_IP_ROUTE_MULTIPATH */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 wenxu
						wenxu