mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] ipv4: fix source address and gateway mismatch under multiple default gateways
@ 2022-10-26  3:20 Ziyang Xuan
  2022-10-26 10:15 ` Julian Anastasov
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Ziyang Xuan @ 2022-10-26  3:20 UTC (permalink / raw)
  To: davem, yoshfuji, dsahern, edumazet, kuba, pabeni, netdev
  Cc: linux-kernel, Robert.Olsson, ja

We found a problem that source address doesn't match with selected gateway
under multiple default gateways. The reproducer is as following:

Setup in client as following:

$ ip link add link eth2 dev eth2.71 type vlan id 71
$ ip link add link eth2 dev eth2.72 type vlan id 72
$ ip addr add 192.168.71.41/24 dev eth2.71
$ ip addr add 192.168.72.41/24 dev eth2.72
$ ip link set eth2.71 up
$ ip link set eth2.72 up
$ route add -net default gw 192.168.71.1 dev eth2.71
$ route add -net default gw 192.168.72.1 dev eth2.72

Add a nameserver configuration in the following file:
$ cat /etc/resolv.conf
nameserver 8.8.8.8

Setup in peer server as following:

$ ip link add link eth2 dev eth2.71 type vlan id 71
$ ip link add link eth2 dev eth2.72 type vlan id 72
$ ip addr add 192.168.71.1/24 dev eth2.71
$ ip addr add 192.168.72.1/24 dev eth2.72
$ ip link set eth2.71 up
$ ip link set eth2.72 up

Use the following command trigger DNS packet in client:
$ ping www.baidu.com

Capture packets with tcpdump in client when ping:
$ tcpdump -i eth2 -vne
...
20:30:22.996044 52:54:00:20:23:a9 > 52:54:00:d2:4f:e3, ethertype 802.1Q (0x8100), length 77: vlan 71, p 0, ethertype IPv4, (tos 0x0, ttl 64, id 25407, offset 0, flags [DF], proto UDP (17), length 59)
    192.168.72.41.42666 > 8.8.8.8.domain: 58562+ A? www.baidu.com. (31)
...

We get the problem that IPv4 saddr "192.168.72.41" do not match with
selected VLAN device "eth2.71".

In above scenario, the process does __ip_route_output_key() twice in
ip_route_connect(), the two processes have chosen different default gateway,
and the last choice is not the best.

Add flowi4->saddr and fib_nh_common->nhc_gw.ipv4 matching consideration in
fib_select_default() to fix that.

Fixes: 19baf839ff4a ("[IPV4]: Add LC-Trie FIB lookup algorithm.")
Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
---
 net/ipv4/fib_semantics.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index e9a7f70a54df..8bd94875a009 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -2046,6 +2046,7 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
 	int order = -1, last_idx = -1;
 	struct fib_alias *fa, *fa1 = NULL;
 	u32 last_prio = res->fi->fib_priority;
+	u8 prefix, max_prefix = 0;
 	dscp_t last_dscp = 0;
 
 	hlist_for_each_entry_rcu(fa, fa_head, fa_list) {
@@ -2078,6 +2079,11 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
 		if (!nhc->nhc_gw_family || nhc->nhc_scope != RT_SCOPE_LINK)
 			continue;
 
+		prefix = __ffs(flp->saddr ^ nhc->nhc_gw.ipv4);
+		if (prefix < max_prefix)
+			continue;
+		max_prefix = max_t(u8, prefix, max_prefix);
+
 		fib_alias_accessed(fa);
 
 		if (!fi) {
-- 
2.25.1


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

end of thread, other threads:[~2022-11-13 20:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-26  3:20 [PATCH net] ipv4: fix source address and gateway mismatch under multiple default gateways Ziyang Xuan
2022-10-26 10:15 ` Julian Anastasov
2022-10-29  2:38   ` Ziyang Xuan (William)
2022-11-13 20:01     ` Julian Anastasov
2022-10-26 15:48 ` kernel test robot
2022-10-26 16:49 ` kernel test robot
2022-10-26 17:29 ` kernel test robot
2022-10-27 15:54 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®