Skip to content

Commit

Permalink
Merge pull request #8588 from tomastigera/auto-pick-of-#8564-release-…
Browse files Browse the repository at this point in the history
…v3.27

[release-v3.27] Auto pick #8564: host can access self via a service without CTLB
  • Loading branch information
tomastigera authored Mar 8, 2024
2 parents 414b586 + bc1f90a commit 9ccd963
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
16 changes: 16 additions & 0 deletions felix/bpf-gpl/tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ int calico_tc_main(struct __sk_buff *skb)
*/
skb->mark = SKB_MARK;
#endif

if (CALI_F_LO && CALI_F_TO_HOST) {
/* Do nothing, it is a packet that just looped around. */
return TC_ACT_UNSPEC;
}

/* Optimisation: if another BPF program has already pre-approved the packet,
* skip all processing. */
if (CALI_F_FROM_HOST && skb->mark == CALI_SKB_MARK_BYPASS) {
Expand Down Expand Up @@ -263,6 +269,16 @@ static CALI_BPF_INLINE void calico_tc_process_ct_lookup(struct cali_tc_ctx *ctx)
skb_mark_equals(ctx->skb, CALI_SKB_MARK_BYPASS_MASK, CALI_SKB_MARK_SKIP_FIB)));

if (HAS_HOST_CONFLICT_PROG &&
/* Do not do conflict resolution for host-self loop. Unlike with
* traffic to another backend, we are not able to tell traffic to
* self via service from straight to self.
*/
!CALI_F_LO &&
/* Do conflict resolution on other device if it clashes with
* traffic looped via the NAT_IF but it hasn't been seen yet and
* is not looped via the NAT_IF, that is, it is from host, but not
* to a service.
*/
(ctx->state->ct_result.flags & CALI_CT_FLAG_VIA_NAT_IF) &&
!(ctx->skb->mark & (CALI_SKB_MARK_FROM_NAT_IFACE_OUT | CALI_SKB_MARK_SEEN))) {
CALI_DEBUG("Host source SNAT conflict\n");
Expand Down
29 changes: 29 additions & 0 deletions felix/fv/bpf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4257,6 +4257,35 @@ func describeBPFTests(opts ...bpfTestOpt) bool {
})
})

It("should have connectivity from host-networked pods via service to host-networked backend", func() {
By("Setting up the service")
hostW[0].ConfigureInInfra(infra)
testSvc := k8sService("host-svc", clusterIP, hostW[0], 80, 8055, 0, testOpts.protocol)
testSvcNamespace := testSvc.ObjectMeta.Namespace
k8sClient := infra.(*infrastructure.K8sDatastoreInfra).K8sClient
_, err := k8sClient.CoreV1().Services(testSvcNamespace).Create(context.Background(), testSvc, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
Eventually(k8sGetEpsForServiceFunc(k8sClient, testSvc), "10s").Should(HaveLen(1),
"Service endpoints didn't get created? Is controller-manager happy?")

By("Testing connectivity")
port := uint16(testSvc.Spec.Ports[0].Port)

hostW0SrcIP := ExpectWithSrcIPs(felixIP(0))
hostW1SrcIP := ExpectWithSrcIPs(felixIP(1))
if !testOpts.connTimeEnabled {
switch testOpts.tunnel {
case "ipip":
hostW0SrcIP = ExpectWithSrcIPs(tc.Felixes[0].ExpectedIPIPTunnelAddr)
hostW1SrcIP = ExpectWithSrcIPs(tc.Felixes[1].ExpectedIPIPTunnelAddr)
}
}

cc.Expect(Some, hostW[0], TargetIP(clusterIP), ExpectWithPorts(port), hostW0SrcIP)
cc.Expect(Some, hostW[1], TargetIP(clusterIP), ExpectWithPorts(port), hostW1SrcIP)
cc.CheckConnectivity()
})

})

Describe("with BPF disabled to begin with", func() {
Expand Down

0 comments on commit 9ccd963

Please sign in to comment.