<div dir="ltr"><br><div>Hello team, I'd appreciate any help, suggestions or hints regarding my TCP RST issue with multipath routing.<br></div><div><br></div><div>I see random TCP connection resets, and while investigating I am stuck with understanding what part of the kernel can call the `ip_forward()` other than `ip_route_input_noref()`. <br></div><div><br></div><div>I have the following setup:</div><div><br></div><div>Kernel 6.4.0.<br></div><div><br></div>```<br>sysctl -w net.ipv4.ip_forward=1 <br>sysctl -w net.ipv4.fib_multipath_hash_policy=1<br>```<br><br>```<br># ip r<br><br><a href="http://192.168.200.0/24">192.168.200.0/24</a> dev enp0s8 proto kernel scope link src 192.168.200.5 # network with backends<br><a href="http://192.168.222.0/24">192.168.222.0/24</a> dev enp0s9 proto kernel scope link src 192.168.222.5 # client network<br><a href="http://10.100.100.0/24">10.100.100.0/24</a> proto bird # VIP network<br>        nexthop via 192.168.200.101 dev enp0s8 weight 1<br>        nexthop via 192.168.200.102 dev enp0s8 weight 1<br>```<br><br>```<br>192.168.222.99 - client IP<br>192.168.200.101 and 192.168.200.102 - real IPs of 2 backends.<br>10.100.100.1 - a VIP, backends have it on lo dev.<br>```<br><br>Backends and a client have the router as a default gateway.<br><br>Example of a RST with my investigations are the following.<br><br>Using `bpftrace` I can see that `ip_route_input_noref()` is run 3 times before the connection reset:<br><br>```<br>ack_seq: 0,         <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff<br>ack_seq: 322960818, <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff<br>ack_seq: 0,         <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff<br>```<br><br>but `ip_forward()` runs 4 times with a wrong `gw` in the `skb->_skb_refdst` at the middle of a connection. It should be 192.168.200.101, but it uses 192.168.200.102 instead:<br><br>```<br>ack_seq: 0,         <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw: 192.168.200.101<br>ack_seq: 322960818, <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw: 192.168.200.101<br>ack_seq: 322960827, <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw: 192.168.200.102<br>ack_seq: 0,         <a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>,  8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw: 192.168.200.101<br>```<br><br>I locally added logging to `__mkroute_input()` to understand if it's a hashing problem, but it also shows me only 3 calls and a correct `rt_gw4` in `rth rtable` and `nhc`:<br><br>```<br><a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>, mac: 8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw4: 192.168.200.101, rt_gw4:192.168.200.101<br><a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>, mac: 8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw4: 192.168.200.101, rt_gw4:192.168.200.101<br><a href="http://192.168.222.99:46308">192.168.222.99:46308</a> -> <a href="http://10.100.100.1:8080">10.100.100.1:8080</a>, mac: 8:0:27:a8:29:e5 -> 8:0:27:86:65:ff, gw4: 192.168.200.101, rt_gw4:192.168.200.101<br>````<br><br>I am stuck with understanding how it's possible that the kernel makes an additional incorrect `ip_forward()` call, when neither `__mkroute_input()` nor `ip_route_input_noref()` calls it.<br clear="all"><div><br></div><div><br></div><div>Thank you for any hints. <br></div><div><span class="gmail_signature_prefix"><br></span></div><div><span class="gmail_signature_prefix">-- </span></div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr">Viacheslav Biriukov<br>BR</div></div></div></div></div>