Subject: [PATCH v3 0/4] tcp: md5: Fix overlap between vrf and non-vrf keys

From: Leonard Crestez <[email-masked]>
Date: Fri, 15 Oct 2021 10:26:03 +0300

With net.ipv4.tcp_l3mdev_accept=1 it is possible for a listen socket to
accept connection from the same client address in different VRFs. It is
also possible to set different MD5 keys for these clients which differ only
in the tcpm_l3index field.

This appears to work when distinguishing between different VRFs but not
between non-VRF and VRF connections. In particular:

* tcp_md5_do_lookup_exact will match a non-vrf key against a vrf key. This
means that adding a key with l3index != 0 after a key with l3index == 0
will cause the earlier key to be deleted. Both keys can be present if the
non-vrf key is added later.
* _tcp_md5_do_lookup can match a non-vrf key before a vrf key. This casues
failures if the passwords differ.

This can be fixed by making tcp_md5_do_lookup_exact perform an actual exact
comparison on l3index and by making  __tcp_md5_do_lookup perfer vrf-bound
keys above other considerations like prefixlen.

The fact that keys with l3index==0 affect VRF connections is usually not
desirable, VRFs are meant to be completely independent. This behavior needs
to preserved for backwards compatibility. Also, applications can just bind
listen sockets to VRF and never specify TCP_MD5SIG_FLAG_IFINDEX at all.

So far the combination of TCP_MD5SIG_FLAG_IFINDEX with tcpm_ifindex == 0
was an error, accept this to mean "key only applies to default VRF". This
is what applications using VRFs for traffic separation want.

This also contains tests for the second part. It does not contain tests for
overlapping keys, that would require more changes in nettest to add
multiple keys. These scenarios are also covered by my tests for TCP-AO,
especially around this area:
https://github.com/cdleonard/tcp-authopt-test/blob/main/tcp_authopt_test/test_vrf_bind.py

Changes since V2:
* Rename --do-bind-key-ifindex to --force-bind-key-ifindex
* Fix referencing TCP_MD5SIG_FLAG_IFINDEX as TCP_MD5SIG_IFINDEX
Link to v2: https://lore.kernel.org/netdev/[email-masked]/

Changes since V1:
* Accept (TCP_MD5SIG_IFINDEX with tcpm_ifindex == 0)
* Add flags for explicitly including or excluding TCP_MD5SIG_FLAG_IFINDEX
to nettest
* Add few more tests in fcnal-test.sh.
Link to v1: https://lore.kernel.org/netdev/3[email-masked]/

Leonard Crestez (4):
  tcp: md5: Fix overlap between vrf and non-vrf keys
  tcp: md5: Allow MD5SIG_FLAG_IFINDEX with ifindex=0
  selftests: nettest: Add --{force,no}-bind-key-ifindex
  selftests: net/fcnal: Test --{force,no}-bind-key-ifindex

 include/net/tcp.h                         |  5 +-
 net/ipv4/tcp_ipv4.c                       | 45 ++++++++++++-----
 net/ipv6/tcp_ipv6.c                       | 15 +++---
 tools/testing/selftests/net/fcnal-test.sh | 60 +++++++++++++++++++++++
 tools/testing/selftests/net/nettest.c     | 28 ++++++++++-
 5 files changed, 130 insertions(+), 23 deletions(-)

base-commit: 40088915f547b52635f022c1e1e18df65ae3153a
-- 
2.25.1