diff options
author | wenxu <wenxu@ucloud.cn> | 2019-02-23 22:36:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-02-27 15:50:17 -0500 |
commit | 24ba14406c5c8e33fcbe064f77b3ab01b84ec830 (patch) | |
tree | 88eee234f6c4e037ad2467b8c370ed1541f5e366 | |
parent | 8f4ef499c6ca56325c76600777237deaeb58a69b (diff) |
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>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | 2 | ||||
-rw-r--r-- | include/net/flow.h | 2 | ||||
-rw-r--r-- | include/net/ip_tunnels.h | 3 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 2 | ||||
-rw-r--r-- | net/ipv4/ip_tunnel.c | 6 | ||||
-rw-r--r-- | net/ipv4/route.c | 4 |
6 files changed, 13 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c index ad5a9b9e1466..536c23c578c3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | |||
@@ -305,7 +305,7 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev, | |||
305 | 305 | ||
306 | parms = mlxsw_sp_ipip_netdev_parms4(to_dev); | 306 | parms = mlxsw_sp_ipip_netdev_parms4(to_dev); |
307 | ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, | 307 | ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp, |
308 | 0, 0, parms.link, tun->fwmark); | 308 | 0, 0, parms.link, tun->fwmark, 0); |
309 | 309 | ||
310 | rt = ip_route_output_key(tun->net, &fl4); | 310 | rt = ip_route_output_key(tun->net, &fl4); |
311 | if (IS_ERR(rt)) | 311 | if (IS_ERR(rt)) |
diff --git a/include/net/flow.h b/include/net/flow.h index 93f2c9a0f098..a50fb77a0b27 100644 --- a/include/net/flow.h +++ b/include/net/flow.h | |||
@@ -40,6 +40,7 @@ struct flowi_common { | |||
40 | __u32 flowic_secid; | 40 | __u32 flowic_secid; |
41 | kuid_t flowic_uid; | 41 | kuid_t flowic_uid; |
42 | struct flowi_tunnel flowic_tun_key; | 42 | struct flowi_tunnel flowic_tun_key; |
43 | __u32 flowic_multipath_hash; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | union flowi_uli { | 46 | union flowi_uli { |
@@ -78,6 +79,7 @@ struct flowi4 { | |||
78 | #define flowi4_secid __fl_common.flowic_secid | 79 | #define flowi4_secid __fl_common.flowic_secid |
79 | #define flowi4_tun_key __fl_common.flowic_tun_key | 80 | #define flowi4_tun_key __fl_common.flowic_tun_key |
80 | #define flowi4_uid __fl_common.flowic_uid | 81 | #define flowi4_uid __fl_common.flowic_uid |
82 | #define flowi4_multipath_hash __fl_common.flowic_multipath_hash | ||
81 | 83 | ||
82 | /* (saddr,daddr) must be grouped, same order as in IP header */ | 84 | /* (saddr,daddr) must be grouped, same order as in IP header */ |
83 | __be32 saddr; | 85 | __be32 saddr; |
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index f069f64ebf29..af645604f328 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h | |||
@@ -241,7 +241,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4, | |||
241 | int proto, | 241 | int proto, |
242 | __be32 daddr, __be32 saddr, | 242 | __be32 daddr, __be32 saddr, |
243 | __be32 key, __u8 tos, int oif, | 243 | __be32 key, __u8 tos, int oif, |
244 | __u32 mark) | 244 | __u32 mark, __u32 tun_inner_hash) |
245 | { | 245 | { |
246 | memset(fl4, 0, sizeof(*fl4)); | 246 | memset(fl4, 0, sizeof(*fl4)); |
247 | fl4->flowi4_oif = oif; | 247 | fl4->flowi4_oif = oif; |
@@ -251,6 +251,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4, | |||
251 | fl4->flowi4_proto = proto; | 251 | fl4->flowi4_proto = proto; |
252 | fl4->fl4_gre_key = key; | 252 | fl4->fl4_gre_key = key; |
253 | fl4->flowi4_mark = mark; | 253 | fl4->flowi4_mark = mark; |
254 | fl4->flowi4_multipath_hash = tun_inner_hash; | ||
254 | } | 255 | } |
255 | 256 | ||
256 | int ip_tunnel_init(struct net_device *dev); | 257 | int ip_tunnel_init(struct net_device *dev); |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 0f4925a0d6b2..fd219f7bd3ea 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -578,7 +578,7 @@ static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) | |||
578 | key = &info->key; | 578 | key = &info->key; |
579 | ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, | 579 | ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, |
580 | tunnel_id_to_key32(key->tun_id), key->tos, 0, | 580 | tunnel_id_to_key32(key->tun_id), key->tos, 0, |
581 | skb->mark); | 581 | skb->mark, skb_get_hash(skb)); |
582 | rt = ip_route_output_key(dev_net(dev), &fl4); | 582 | rt = ip_route_output_key(dev_net(dev), &fl4); |
583 | if (IS_ERR(rt)) | 583 | if (IS_ERR(rt)) |
584 | return PTR_ERR(rt); | 584 | return PTR_ERR(rt); |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 2973067b831d..2756fb725bf0 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -310,7 +310,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev) | |||
310 | ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, | 310 | ip_tunnel_init_flow(&fl4, iph->protocol, iph->daddr, |
311 | iph->saddr, tunnel->parms.o_key, | 311 | iph->saddr, tunnel->parms.o_key, |
312 | RT_TOS(iph->tos), tunnel->parms.link, | 312 | RT_TOS(iph->tos), tunnel->parms.link, |
313 | tunnel->fwmark); | 313 | tunnel->fwmark, 0); |
314 | rt = ip_route_output_key(tunnel->net, &fl4); | 314 | rt = ip_route_output_key(tunnel->net, &fl4); |
315 | 315 | ||
316 | if (!IS_ERR(rt)) { | 316 | if (!IS_ERR(rt)) { |
@@ -584,7 +584,7 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
584 | } | 584 | } |
585 | ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, | 585 | ip_tunnel_init_flow(&fl4, proto, key->u.ipv4.dst, key->u.ipv4.src, |
586 | tunnel_id_to_key32(key->tun_id), RT_TOS(tos), | 586 | tunnel_id_to_key32(key->tun_id), RT_TOS(tos), |
587 | 0, skb->mark); | 587 | 0, skb->mark, skb_get_hash(skb)); |
588 | if (tunnel->encap.type != TUNNEL_ENCAP_NONE) | 588 | if (tunnel->encap.type != TUNNEL_ENCAP_NONE) |
589 | goto tx_error; | 589 | goto tx_error; |
590 | 590 | ||
@@ -744,7 +744,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
744 | 744 | ||
745 | ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, | 745 | ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr, |
746 | tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link, | 746 | tunnel->parms.o_key, RT_TOS(tos), tunnel->parms.link, |
747 | tunnel->fwmark); | 747 | tunnel->fwmark, skb_get_hash(skb)); |
748 | 748 | ||
749 | if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) | 749 | if (ip_tunnel_encap(skb, tunnel, &protocol, &fl4) < 0) |
750 | goto tx_error; | 750 | goto tx_error; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ecc12a768191..7cf4c8305071 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1820,6 +1820,7 @@ out: | |||
1820 | int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, | 1820 | int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, |
1821 | const struct sk_buff *skb, struct flow_keys *flkeys) | 1821 | const struct sk_buff *skb, struct flow_keys *flkeys) |
1822 | { | 1822 | { |
1823 | u32 multipath_hash = fl4->flowi4_multipath_hash; | ||
1823 | struct flow_keys hash_keys; | 1824 | struct flow_keys hash_keys; |
1824 | u32 mhash; | 1825 | u32 mhash; |
1825 | 1826 | ||
@@ -1870,6 +1871,9 @@ int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4, | |||
1870 | } | 1871 | } |
1871 | mhash = flow_hash_from_keys(&hash_keys); | 1872 | mhash = flow_hash_from_keys(&hash_keys); |
1872 | 1873 | ||
1874 | if (multipath_hash) | ||
1875 | mhash = jhash_2words(mhash, multipath_hash, 0); | ||
1876 | |||
1873 | return mhash >> 1; | 1877 | return mhash >> 1; |
1874 | } | 1878 | } |
1875 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ | 1879 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ |