mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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