diff --git a/pkg/controller/installation/core_controller.go b/pkg/controller/installation/core_controller.go index a766f061f4..9d4a4b802a 100644 --- a/pkg/controller/installation/core_controller.go +++ b/pkg/controller/installation/core_controller.go @@ -2173,6 +2173,16 @@ func (r *ReconcileInstallation) setDefaultsOnFelixConfiguration(ctx context.Cont return false, err } updated = true + + // A fresh eBPF install opts into sourcing host-networked overlay traffic from the + // node's own address instead of an IP assigned to the tunnel device. Felix defaults + // this to TunnelAddress, which existing/upgraded clusters keep so their host-networked + // flows are not disrupted; brand new clusters have no such flows to preserve. Only set + // it when unset so a user-provided value is never overridden. + if fc.Spec.BPFOverlayHostSourceIP == nil { + hostSourceIP := v3.BPFOverlayHostSourceIPHostAddress + fc.Spec.BPFOverlayHostSourceIP = &hostSourceIP + } } } else { bpfEnabledOnDaemonsetWithEnvVar, err := bpfEnabledOnDaemonsetWithEnvVar(ds) diff --git a/pkg/controller/installation/core_controller_test.go b/pkg/controller/installation/core_controller_test.go index bda4f6065b..9baf9d5ae8 100644 --- a/pkg/controller/installation/core_controller_test.go +++ b/pkg/controller/installation/core_controller_test.go @@ -1675,6 +1675,52 @@ var _ = Describe("Testing core-controller installation", func() { Expect(fc.Annotations[render.BPFOperatorAnnotation]).To(Equal("true")) Expect(fc.Spec.BPFEnabled).NotTo(BeNil()) Expect(*fc.Spec.BPFEnabled).To(BeTrue()) + + // A fresh eBPF install should opt into sourcing host-networked overlay traffic + // from the node's address rather than a tunnel device IP. + Expect(fc.Spec.BPFOverlayHostSourceIP).NotTo(BeNil()) + Expect(*fc.Spec.BPFOverlayHostSourceIP).To(Equal(v3.BPFOverlayHostSourceIPHostAddress)) + }) + + It("should not set BPFOverlayHostSourceIP on FelixConfiguration when calico-node already exists (upgrade)", func() { + createNodeDaemonSet() + + network := operator.LinuxDataplaneBPF + cr.Spec.CalicoNetwork = &operator.CalicoNetworkSpec{LinuxDataplane: &network} + Expect(c.Create(ctx, cr)).NotTo(HaveOccurred()) + _, err := r.Reconcile(ctx, reconcile.Request{}) + Expect(err).ShouldNot(HaveOccurred()) + + fc := &v3.FelixConfiguration{} + err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) + Expect(err).ShouldNot(HaveOccurred()) + + // An existing cluster keeps Felix's TunnelAddress default (field left unset) so + // its host-networked overlay flows are not disrupted. + Expect(fc.Spec.BPFOverlayHostSourceIP).To(BeNil()) + }) + + It("should not override a user-set BPFOverlayHostSourceIP on a fresh install", func() { + tunnelAddress := v3.BPFOverlayHostSourceIPTunnelAddress + existingFC := &v3.FelixConfiguration{ + ObjectMeta: metav1.ObjectMeta{Name: "default"}, + Spec: v3.FelixConfigurationSpec{BPFOverlayHostSourceIP: &tunnelAddress}, + } + Expect(c.Create(ctx, existingFC)).NotTo(HaveOccurred()) + + network := operator.LinuxDataplaneBPF + cr.Spec.CalicoNetwork = &operator.CalicoNetworkSpec{LinuxDataplane: &network} + Expect(c.Create(ctx, cr)).NotTo(HaveOccurred()) + _, err := r.Reconcile(ctx, reconcile.Request{}) + Expect(err).ShouldNot(HaveOccurred()) + + fc := &v3.FelixConfiguration{} + err = c.Get(ctx, types.NamespacedName{Name: "default"}, fc) + Expect(err).ShouldNot(HaveOccurred()) + + // The operator must not stomp a value the user already set. + Expect(fc.Spec.BPFOverlayHostSourceIP).NotTo(BeNil()) + Expect(*fc.Spec.BPFOverlayHostSourceIP).To(Equal(v3.BPFOverlayHostSourceIPTunnelAddress)) }) It("should set BPFEnabled to false on FelixConfiguration if BPF is disabled on installation", func() {