Skip to content

Commit

Permalink
connectivity: fix encryption validation when running in ENI mode
Browse files Browse the repository at this point in the history
When running in ENI mode, the outgoing interface of pod originating traffic
is different from the one that would be used by host originating traffic
towards the same destination. This breaks the current pod-to-pod
encryption validation, as the source interface for the tcpdump filter is
determined based on the routes towards the given destination only.

Let's update the source interface determination to additionally consider
the source address. This approach had been initially suggested by Paul
Chaignon in cilium#1241, but then reverted in [1] because `ip route get` returns
and error in case the `from` address is not assigned to any local interface.
We can work around this by specifying an input interface: let's use lo
as it should be always present.

[1]: 2fc0835 ("connectivity: Fix iface derivation in encrypt tests")

Signed-off-by: Marco Iorio <[email protected]>
  • Loading branch information
giorio94 committed Oct 13, 2023
1 parent 728f3c6 commit 6280b8a
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions connectivity/tests/encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,19 @@ const (
// which interface the traffic is routed to. Additionally, we translate
// the interface name to the tunneling interface name, if the route goes
// through "cilium_host" and tunneling is enabled.
func getInterNodeIface(ctx context.Context, t *check.Test, clientHost *check.Pod, dstIP string) string {
func getInterNodeIface(ctx context.Context, t *check.Test, clientHost *check.Pod, ipFam features.IPFamily, srcIP, dstIP string) string {
ipRouteGetCmd := fmt.Sprintf("ip -o route get %s from %s", dstIP, srcIP)
if srcIP != clientHost.Address(ipFam) {
// The "iif lo" part is required when the source address is not one
// of the addresses of the host. If an interface is not specified
// "ip route" returns "RTNETLINK answers: Network is unreachable" in
// case the "from" address is not assigned to any local interface.
ipRouteGetCmd = fmt.Sprintf("%s iif lo", ipRouteGetCmd)
}

cmd := []string{
"/bin/sh", "-c",
fmt.Sprintf("ip -o route get %s | grep -oE 'dev [^ ]*' | cut -d' ' -f2",
dstIP),
fmt.Sprintf("%s | grep -oE 'dev [^ ]*' | cut -d' ' -f2", ipRouteGetCmd),
}
t.Debugf("Running %s", strings.Join(cmd, " "))
dev, err := clientHost.K8sClient.ExecInPod(ctx, clientHost.Pod.Namespace,
Expand Down Expand Up @@ -130,7 +138,7 @@ func testNoTrafficLeak(ctx context.Context, t *check.Test, s check.Scenario,
client, server, clientHost *check.Pod, reqType requestType, ipFam features.IPFamily,
) {
dstAddr := server.Address(ipFam)
iface := getInterNodeIface(ctx, t, clientHost, dstAddr)
iface := getInterNodeIface(ctx, t, clientHost, ipFam, client.Address(ipFam), dstAddr)
srcFilter := getSourceAddressFilter(ctx, t, client, clientHost, ipFam, dstAddr)

bgStdout := &safeBuffer{}
Expand Down

0 comments on commit 6280b8a

Please sign in to comment.