From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefano Brivio To: passt-dev@passt.top Subject: Re: [PATCH 17/18] tests: Correct determination of host interface name in tests Date: Tue, 19 Jul 2022 21:05:52 +0200 Message-ID: <20220719210552.45329b70@elisabeth> In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7722458479166696566==" --===============7722458479166696566== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable On Tue, 19 Jul 2022 16:20:45 +1000 David Gibson wrote: > On Fri, Jul 15, 2022 at 03:21:40PM +1000, David Gibson wrote: > > By default, passt itself attaches to the first host interface with a > > default route. However, when determining the host interface name the tes= ts > > implicitly select the *last* host interface: they use a jq expression whi= ch > > will list all interfaces with default routes, but the way output detection > > works in the scripts, it will only pick up the last line. > >=20 > > If there are multiple interfaces with default routes on the host, and they > > each have a different address, this can cause spurious test > > failures. =20 >=20 > It seems this change is not enough to always fix the tests when there > are multiple default routes. I'm still sometimes getting failures, > now because passt itself doesn't seem to be picking the interface > with the first default route. >=20 > I'm wondering if this is because ip(8) is sorting the output, not just > presenting it in the same order that the underlying netlink interface > does. I don't see that happening at least in my environment (and I also can't see any code that would sort it, that pretty much comes from rtnl_dump_filter_l() in lib/libnetlink.c). The netlink "filter", though, is slightly different. For IPv4: $ strace -e sendto ip route show >/dev/null sendto(3, [{{len=3D36, type=3DRTM_GETROUTE, flags=3DNLM_F_REQUEST|NLM_F_DUMP,= seq=3D1658257027, pid=3D0}, {rtm_family=3DAF_INET, rtm_dst_len=3D0, rtm_src_= len=3D0, rtm_tos=3D0, rtm_table=3DRT_TABLE_UNSPEC, rtm_protocol=3DRTPROT_UNSP= EC, rtm_scope=3DRT_SCOPE_UNIVERSE, rtm_type=3DRTN_UNSPEC, rtm_flags=3D0}, {{n= la_len=3D8, nla_type=3DRTA_TABLE}, RT_TABLE_MAIN}}, {len=3D0, type=3D0 /* NLM= SG_??? */, flags=3D0, seq=3D0, pid=3D0}], 156, 0, NULL, 0) =3D 156 $ strace -e sendto ./passt -f sendto(5, {{len=3D28, type=3DRTM_GETROUTE, flags=3DNLM_F_REQUEST|NLM_F_DUMP, = seq=3D0, pid=3D0}, {rtm_family=3DAF_INET, rtm_dst_len=3D0, rtm_src_len=3D0, r= tm_tos=3D0, rtm_table=3DRT_TABLE_MAIN, rtm_protocol=3DRTPROT_UNSPEC, rtm_scop= e=3DRT_SCOPE_UNIVERSE, rtm_type=3DRTN_UNICAST, rtm_flags=3D0}}, 28, 0, NULL, = 0) =3D 28 [...] and, while I don't think the FIB trie is actually descended in a different way, we might still have a slightly different result from the kernel (if I recall correctly, I didn't check right now). But letting that aside for a moment: if you have two default routes, I suppose they have different metrics. If not, what's the intended usage? If yes, we should probably implement a sorting logic in passt, so that the route with the lowest metric is picked, and then adjust the jq expression to also pick that one. --=20 Stefano --===============7722458479166696566==--