Skip to content

Commit

Permalink
Allow Node SNAT for Static Egress case
Browse files Browse the repository at this point in the history
Implemented best effort scenario, where in case of
static Egress also, if there is no egress node then
the packets will be sent using normal Node SNAT, as
in case of dynamic Egress.

Signed-off-by: Pulkit Jain <[email protected]>
  • Loading branch information
jainpulkit22 committed Dec 12, 2024
1 parent e404ccc commit 2480ead
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 27 deletions.
64 changes: 37 additions & 27 deletions pkg/agent/controller/egress/egress_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ var emptyWatch = watch.NewEmptyWatch()

var newIPAssigner = ipassigner.NewIPAssigner

var egressNodeAvailability = hasEgressNode

// egressState keeps the actual state of an Egress that has been realized.
type egressState struct {
// The actual egress IP of the Egress. If it's different from the desired IP, there is an update to EgressIP, and we
Expand Down Expand Up @@ -989,6 +991,12 @@ func (c *EgressController) updateEgressStatus(egress *crdv1b1.Egress, egressIP s
return nil
}

func hasEgressNode(egress *crdv1b1.Egress) bool {
if egress.Status.EgressNode == "" {
return false
}
return true
}
func (c *EgressController) syncEgress(egressName string) error {
startTime := time.Now()
defer func() {
Expand Down Expand Up @@ -1118,39 +1126,41 @@ func (c *EgressController) syncEgress(egressName string) error {
}()

egressIP := net.ParseIP(eState.egressIP)
// Install SNAT flows for desired Pods.
for pod := range pods {
eState.pods.Insert(pod)
stalePods.Delete(pod)
if egressNodeAvailability(egress) {
// Install SNAT flows for desired Pods.
for pod := range pods {
eState.pods.Insert(pod)
stalePods.Delete(pod)

// If the Egress is not the effective one for the Pod, do nothing.
if !c.bindPodEgress(pod, egressName) {
continue
}

// If the Egress is not the effective one for the Pod, do nothing.
if !c.bindPodEgress(pod, egressName) {
continue
}
// Get the Pod's openflow port.
parts := strings.Split(pod, "/")
podNamespace, podName := parts[0], parts[1]
ifaces := c.ifaceStore.GetContainerInterfacesByPod(podName, podNamespace)
if len(ifaces) == 0 {
klog.Infof("Interfaces of Pod %s/%s not found", podNamespace, podName)
continue
}

// Get the Pod's openflow port.
parts := strings.Split(pod, "/")
podNamespace, podName := parts[0], parts[1]
ifaces := c.ifaceStore.GetContainerInterfacesByPod(podName, podNamespace)
if len(ifaces) == 0 {
klog.Infof("Interfaces of Pod %s/%s not found", podNamespace, podName)
continue
ofPort := ifaces[0].OFPort
if eState.ofPorts.Has(ofPort) {
staleOFPorts.Delete(ofPort)
continue
}
if err := c.ofClient.InstallPodSNATFlows(uint32(ofPort), egressIP, mark); err != nil {
return err
}
eState.ofPorts.Insert(ofPort)
}

ofPort := ifaces[0].OFPort
if eState.ofPorts.Has(ofPort) {
staleOFPorts.Delete(ofPort)
continue
}
if err := c.ofClient.InstallPodSNATFlows(uint32(ofPort), egressIP, mark); err != nil {
// Uninstall SNAT flows for stale Pods.
if err := c.uninstallPodFlows(egressName, eState, staleOFPorts, stalePods); err != nil {
return err
}
eState.ofPorts.Insert(ofPort)
}

// Uninstall SNAT flows for stale Pods.
if err := c.uninstallPodFlows(egressName, eState, staleOFPorts, stalePods); err != nil {
return err
}
return nil
}
Expand Down
27 changes: 27 additions & 0 deletions pkg/agent/controller/egress/egress_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,15 @@ func TestSyncEgress(t *testing.T) {
},
},
}

egressNodeAvailability := func(egress *crdv1b1.Egress) {

Check failure on line 1105 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

declared and not used: egressNodeAvailability

Check failure on line 1105 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

declared and not used: egressNodeAvailability

Check failure on line 1105 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

declared and not used: egressNodeAvailability

Check failure on line 1105 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

declared and not used: egressNodeAvailability

Check failure on line 1105 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

declared and not used: egressNodeAvailability
return true

Check failure on line 1106 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

too many return values

Check failure on line 1106 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

too many return values

Check failure on line 1106 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

too many return values

Check failure on line 1106 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

too many return values

Check failure on line 1106 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

too many return values
}

defer func() {
egressNodeAvailability = hasEgressNode

Check failure on line 1110 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1110 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1110 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1110 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1110 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment
}()

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
initObjects := []runtime.Object{tt.existingEgress}
Expand Down Expand Up @@ -1195,6 +1204,15 @@ func TestPodUpdateShouldSyncEgress(t *testing.T) {
{Pod: &cpv1b2.PodReference{Name: "pendingPod", Namespace: "ns1"}},
},
}

egressNodeAvailability := func(egress *crdv1b1.Egress) {

Check failure on line 1208 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

declared and not used: egressNodeAvailability

Check failure on line 1208 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

declared and not used: egressNodeAvailability

Check failure on line 1208 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

declared and not used: egressNodeAvailability

Check failure on line 1208 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

declared and not used: egressNodeAvailability

Check failure on line 1208 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

declared and not used: egressNodeAvailability
return true

Check failure on line 1209 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

too many return values

Check failure on line 1209 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

too many return values

Check failure on line 1209 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

too many return values

Check failure on line 1209 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

too many return values

Check failure on line 1209 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

too many return values
}

defer func() {
egressNodeAvailability = hasEgressNode

Check failure on line 1213 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1213 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1213 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1213 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1213 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment
}()

c := newFakeController(t, []runtime.Object{egress})
stopCh := make(chan struct{})
defer close(stopCh)
Expand Down Expand Up @@ -1327,6 +1345,15 @@ func TestSyncOverlappingEgress(t *testing.T) {
{Pod: &cpv1b2.PodReference{Name: "pod4", Namespace: "ns4"}},
},
}

egressNodeAvailability := func(egress *crdv1b1.Egress) {

Check failure on line 1349 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

declared and not used: egressNodeAvailability

Check failure on line 1349 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

declared and not used: egressNodeAvailability

Check failure on line 1349 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

declared and not used: egressNodeAvailability

Check failure on line 1349 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

declared and not used: egressNodeAvailability

Check failure on line 1349 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

declared and not used: egressNodeAvailability
return true

Check failure on line 1350 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

too many return values

Check failure on line 1350 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

too many return values

Check failure on line 1350 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

too many return values

Check failure on line 1350 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

too many return values

Check failure on line 1350 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

too many return values
}

defer func() {
egressNodeAvailability = hasEgressNode

Check failure on line 1354 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (macos-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment (typecheck)

Check failure on line 1354 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint (ubuntu-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment (typecheck)

Check failure on line 1354 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Go benchmark test

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1354 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (ubuntu-latest)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment

Check failure on line 1354 in pkg/agent/controller/egress/egress_controller_test.go

View workflow job for this annotation

GitHub Actions / Unit test (windows-2022)

cannot use hasEgressNode (value of type func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) bool) as func(egress *"antrea.io/antrea/pkg/apis/crd/v1beta1".Egress) value in assignment
}()

c := newFakeController(t, []runtime.Object{egress1, egress2, egress3})
stopCh := make(chan struct{})
defer close(stopCh)
Expand Down

0 comments on commit 2480ead

Please sign in to comment.