Bug 216557 - tcp connection not working over ip_vti interface
Summary: tcp connection not working over ip_vti interface
Status: NEW
Alias: None
Product: Networking
Classification: Unclassified
Component: IPV4 (show other bugs)
Hardware: All Linux
: P1 high
Assignee: Stephen Hemminger
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-10-07 20:51 UTC by MonilPatel
Modified: 2022-10-07 20:52 UTC (History)
0 users

See Also:
Kernel Version: 5.15.53
Subsystem:
Regression: Yes
Bisected commit-id:


Attachments

Description MonilPatel 2022-10-07 20:51:12 UTC
TCP protocol is not working, when ipsec tunnel has been setup and ip_vti tunnel is used for route based ipsec.

After the below changes merged with latest kernel. xfrm4_policy_check in tcp_v4_rcv drops all packets except first syn packet under XfrmInTmplMismatch when local destined packets are received over ip_vti tunnel.

author	Eyal Birger <eyal.birger@gmail.com>	2022-05-13 23:34:02 +0300
committer	Greg Kroah-Hartman <gregkh@linuxfoundation.org>	2022-05-25 09:57:30 +0200
commit	952c2464963895271c31698970e7ec1ad6f0fe45 (patch)
tree	9e8300c45a0eb5a9555eae017f8ae561f3e8bc51 /include/net/xfrm.h
parent	36d8cca5b46fe41b59f8011553495ede3b693703 (diff)
download	linux-952c2464963895271c31698970e7ec1ad6f0fe45.tar.gz
xfrm: fix "disable_policy" flag use when arriving from different devices


setup:
1) create road warrior ipsec tunnel with local ip x.x.x.x remote ip y.y.y.y.
2) create vti interface using ip tunnel add vti_test local x.x.x.x remote y.y.y.y mode vti 
3) echo 1 > /proc/sys/net/ipv4/conf/vti_test/disable_policy
4) Add default route over vti_test.
5) ping remote ip, ping works.
6) ssh remote ip, ssh dont work. check tcp connection not working.

Root cause:
-> with above mentioned commit, now xfrm4_policy_check depends on skb's IPSKB_NOPOLICY flag which need to be set per skb and it only gets set in ip_route_input_noref .

-> before above change, xfrm4_policy_check was using DST_NOPOLICY which was checked against dst set in skb.

-> ip_rcv_finish_core calls ip_route_input_noref only if dst is not valid in skb.

-> By default in kernel sysctl_ip_early_demux = 1, which means when skb with syn is received, tcp stack will set DST from skb to sk and in subsequent packets it will copy dst from sk to skb and skip calling ip_route_input_nore inside ip_rcv_finish_core.

-> so for all the subsequent  received packets, IPSKB_NOPOLICY will not get set and they will get drop.

workaround:
only work-aroud is to disable early tcp demux.
echo 0 > /proc/sys/net/ipv4/ip_early_demux

Note You need to log in before you can comment on or make changes to this bug.