diff --git a/felix/bpf-gpl/tc.c b/felix/bpf-gpl/tc.c index 50e84680fca..db4e3f5c5f9 100644 --- a/felix/bpf-gpl/tc.c +++ b/felix/bpf-gpl/tc.c @@ -1319,12 +1319,22 @@ int calico_tc_skb_new_flow_entrypoint(struct __sk_buff *skb) if (CALI_F_TO_HOST && state->flags & CALI_ST_SKIP_FIB) { ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; } - /* Packets received at WEP with CALI_CT_FLAG_SKIP_FIB mark signal - * that all traffic on this connection must flow via host namespace as it was - * originally meant for host, but got redirected to a WEP by a 3rd party DNAT rule. - */ - if (CALI_F_TO_WEP && ((ctx->skb->mark & CALI_SKB_MARK_SKIP_FIB) == CALI_SKB_MARK_SKIP_FIB)) { - ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; + if (CALI_F_TO_WEP) { + if (!(ctx->skb->mark & CALI_SKB_MARK_SEEN)) { + /* If the packet wasn't seen, must come from host. There is no + * need to do FIB lookup for returning traffic. In fact, it may + * not be always correct, e.g. when some mesh and custom iptables + * rules are used by the host. So don't mess with it. + */ + ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; + } else if ((ctx->skb->mark & CALI_SKB_MARK_SKIP_FIB) == CALI_SKB_MARK_SKIP_FIB) { + /* Packets received at WEP with CALI_CT_FLAG_SKIP_FIB mark signal + * that all traffic on this connection must flow via host + * namespace as it was originally meant for host, but got + * redirected to a WEP by a 3rd party DNAT rule. + */ + ct_ctx_nat->flags |= CALI_CT_FLAG_SKIP_FIB; + } } if (CALI_F_TO_HOST && CALI_F_NAT_IF) { ct_ctx_nat->flags |= CALI_CT_FLAG_VIA_NAT_IF; diff --git a/felix/fv/bpf_test.go b/felix/fv/bpf_test.go index fc01c780b43..7ced122b6d6 100644 --- a/felix/fv/bpf_test.go +++ b/felix/fv/bpf_test.go @@ -938,6 +938,22 @@ func describeBPFTests(opts ...bpfTestOpt) bool { cc.ResetExpectations() } }) + + It("should respond back to host is the original traffic came from the host", func() { + if testOpts.ipv6 { + return + } + + By("Setting up istio-like rules that SNAT host as link-local IP") + + tc.Felixes[0].Exec("iptables", "-t", "nat", "-A", "POSTROUTING", "-d", w[0].IP, "-j", + "SNAT", "--to-source", "169.254.7.127") + + By("Testing connectivity from host to pod") + + cc.Expect(Some, hostW, w[0], ExpectWithSrcIPs("169.254.7.127")) + cc.CheckConnectivity() + }) } if testOpts.nonProtoTests {