Repository: antrea-io/antrea
Pull request #2532 (2021-08-04 01:35:26)

fix lint for if block
fix "if block ends with a `return` statement" issue by go lint

Signed-off-by: Lan Luo <luola@vmware.com>

luolanzone: @antoninbas I think we can enable lint check in go.yml, looks like we only run `make golangci` which doesn't run lint check, and I just run "make lint", it seems there are quite a lot other warning like `exported type `GroupMember` should have comment or be unexported`, not sure if we can skip this kind of warning in `.golangci-golint.yml` or fix them all, any suggestion?
codecov-commenter: # [Codecov](https://codecov.io/gh/antrea-io/antrea/pull/2532?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#2532](https://codecov.io/gh/antrea-io/antrea/pull/2532?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (eabe8a3) into [main](https://codecov.io/gh/antrea-io/antrea/commit/028393d010eb36c6c4568de3078b1e71e44bd815?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (028393d) will **increase** coverage by `0.16%`.
> The diff coverage is `0.00%`.

[![Impacted file tree graph](https://codecov.io/gh/antrea-io/antrea/pull/2532/graphs/tree.svg?width=650&height=150&src=pr&token=TjWaLL2GoC&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)](https://codecov.io/gh/antrea-io/antrea/pull/2532?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

```diff
@@            Coverage Diff             @@
##             main    #2532      +/-   ##
==========================================
+ Coverage   59.78%   59.95%   +0.16%     
==========================================
  Files         284      281       -3     
  Lines       22265    22203      -62     
==========================================
- Hits        13312    13311       -1     
+ Misses       7535     7476      -59     
+ Partials     1418     1416       -2     
```

| Flag | Coverage Δ | |
|---|---|---|
| kind-e2e-tests | `47.10% <0.00%> (+0.22%)` | :arrow_up: |
| unit-tests | `42.22% <0.00%> (-0.01%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/antrea-io/antrea/pull/2532?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [pkg/agent/util/net\_linux.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2FnZW50L3V0aWwvbmV0X2xpbnV4Lmdv) | `34.00% <0.00%> (+0.33%)` | :arrow_up: |
| [pkg/ovs/ovsctl/appctl.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL292cy9vdnNjdGwvYXBwY3RsLmdv) | `29.68% <0.00%> (+1.32%)` | :arrow_up: |
| [...g/controller/networkpolicy/store/appliedtogroup.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2NvbnRyb2xsZXIvbmV0d29ya3BvbGljeS9zdG9yZS9hcHBsaWVkdG9ncm91cC5nbw==) | `86.36% <0.00%> (-3.04%)` | :arrow_down: |
| [pkg/controller/grouping/controller.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2NvbnRyb2xsZXIvZ3JvdXBpbmcvY29udHJvbGxlci5nbw==) | `67.24% <0.00%> (-1.73%)` | :arrow_down: |
| [pkg/apiserver/apiserver.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2FwaXNlcnZlci9hcGlzZXJ2ZXIuZ28=) | `87.50% <0.00%> (-0.50%)` | :arrow_down: |
| [pkg/agent/memberlist/cluster.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2FnZW50L21lbWJlcmxpc3QvY2x1c3Rlci5nbw==) | `72.33% <0.00%> (-0.49%)` | :arrow_down: |
| [pkg/agent/route/route\_linux.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2FnZW50L3JvdXRlL3JvdXRlX2xpbnV4Lmdv) | `44.68% <0.00%> (-0.27%)` | :arrow_down: |
| [pkg/apiserver/certificate/cacert\_controller.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2FwaXNlcnZlci9jZXJ0aWZpY2F0ZS9jYWNlcnRfY29udHJvbGxlci5nbw==) | `56.95% <0.00%> (ø)` | |
| [pkg/legacyapis/controlplane/install/install.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2xlZ2FjeWFwaXMvY29udHJvbHBsYW5lL2luc3RhbGwvaW5zdGFsbC5nbw==) | `100.00% <0.00%> (ø)` | |
| [...egacyclient/clientset/versioned/scheme/register.go](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cGtnL2xlZ2FjeWNsaWVudC9jbGllbnRzZXQvdmVyc2lvbmVkL3NjaGVtZS9yZWdpc3Rlci5nbw==) | `100.00% <0.00%> (ø)` | |
| ... and [10 more](https://codecov.io/gh/antrea-io/antrea/pull/2532/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | |

luolanzone: @antoninbas , it turns out there are quite a lot "if block" issue after disable 'max-per-linter' and run "make lint", I refined all of them here, and will submit a new PR to add go lint check to go.yml and other lint fix.

Patch:
diff --git a/build/yamls/antrea-aks.yml b/build/yamls/antrea-aks.yml
index c2f0194a6..5805b70a1 100644
--- a/build/yamls/antrea-aks.yml
+++ b/build/yamls/antrea-aks.yml
@@ -4180,7 +4180,7 @@ spec:
           name: api
           protocol: TCP
         readinessProbe:
-          failureThreshold: 5
+          failureThreshold: 8
           httpGet:
             host: localhost
             path: /readyz
diff --git a/build/yamls/antrea-eks.yml b/build/yamls/antrea-eks.yml
index 53788c248..2ac92a80b 100644
--- a/build/yamls/antrea-eks.yml
+++ b/build/yamls/antrea-eks.yml
@@ -4182,7 +4182,7 @@ spec:
           name: api
           protocol: TCP
         readinessProbe:
-          failureThreshold: 5
+          failureThreshold: 8
           httpGet:
             host: localhost
             path: /readyz
diff --git a/build/yamls/antrea-gke.yml b/build/yamls/antrea-gke.yml
index eccc11946..30ed457d7 100644
--- a/build/yamls/antrea-gke.yml
+++ b/build/yamls/antrea-gke.yml
@@ -4180,7 +4180,7 @@ spec:
           name: api
           protocol: TCP
         readinessProbe:
-          failureThreshold: 5
+          failureThreshold: 8
           httpGet:
             host: localhost
             path: /readyz
diff --git a/build/yamls/antrea-ipsec.yml b/build/yamls/antrea-ipsec.yml
index 8677b97d2..8edd9ccda 100644
--- a/build/yamls/antrea-ipsec.yml
+++ b/build/yamls/antrea-ipsec.yml
@@ -4229,7 +4229,7 @@ spec:
           name: api
           protocol: TCP
         readinessProbe:
-          failureThreshold: 5
+          failureThreshold: 8
           httpGet:
             host: localhost
             path: /readyz
diff --git a/build/yamls/antrea.yml b/build/yamls/antrea.yml
index 64a1b3db7..03d947c71 100644
--- a/build/yamls/antrea.yml
+++ b/build/yamls/antrea.yml
@@ -4185,7 +4185,7 @@ spec:
           name: api
           protocol: TCP
         readinessProbe:
-          failureThreshold: 5
+          failureThreshold: 8
           httpGet:
             host: localhost
             path: /readyz
diff --git a/build/yamls/base/agent.yml b/build/yamls/base/agent.yml
index e8a8b32f5..a1a0ec5dc 100644
--- a/build/yamls/base/agent.yml
+++ b/build/yamls/base/agent.yml
@@ -110,7 +110,11 @@ spec:
             initialDelaySeconds: 5
             timeoutSeconds: 5
             periodSeconds: 10
-            failureThreshold: 5
+            # In large-scale clusters, it may take up to 40~50 seconds for the antrea-agent to reconnect to the antrea
+            # Service after the antrea-controller restarts. The antrea-agent shouldn't be reported as NotReady in this
+            # scenario, otherwise the DaemonSet controller would restart all agents at once, as opposed to performing a
+            # rolling update. Set failureThreshold to 8 so it can tolerate 70s of disconnection.
+            failureThreshold: 8
           securityContext:
             # antrea-agent needs to perform sysctl configuration.
             privileged: true
diff --git a/cmd/antrea-agent/agent.go b/cmd/antrea-agent/agent.go
index 1007b3398..97499e41b 100644
--- a/cmd/antrea-agent/agent.go
+++ b/cmd/antrea-agent/agent.go
@@ -201,7 +201,8 @@ func run(o *Options) error {
 
 	var denyConnStore *connections.DenyConnectionStore
 	if features.DefaultFeatureGate.Enabled(features.FlowExporter) {
-		denyConnStore = connections.NewDenyConnectionStore(ifaceStore, proxier)
+		denyConnStore = connections.NewDenyConnectionStore(ifaceStore, proxier, o.staleConnectionTimeout)
+		go denyConnStore.RunPeriodicDeletion(stopCh)
 	}
 	networkPolicyController, err := networkpolicy.NewNetworkPolicyController(
 		antreaClientProvider,
@@ -382,7 +383,8 @@ func run(o *Options) error {
 			v6Enabled,
 			proxier,
 			networkPolicyController,
-			o.pollInterval)
+			o.pollInterval,
+			o.staleConnectionTimeout)
 		go conntrackConnStore.Run(stopCh)
 
 		flowExporter, err := exporter.NewFlowExporter(
diff --git a/cmd/antrea-agent/options.go b/cmd/antrea-agent/options.go
index bb8a9ed3c..a194615c1 100644
--- a/cmd/antrea-agent/options.go
+++ b/cmd/antrea-agent/options.go
@@ -44,6 +44,7 @@ const (
 	defaultFlowPollInterval        = 5 * time.Second
 	defaultActiveFlowExportTimeout = 30 * time.Second
 	defaultIdleFlowExportTimeout   = 15 * time.Second
+	defaultStaleConnectionTimeout  = 5 * time.Minute
 	defaultNPLPortRange            = "61000-62000"
 )
 
@@ -62,6 +63,8 @@ type Options struct {
 	activeFlowTimeout time.Duration
 	// Idle flow timeout to export records of inactive flows
 	idleFlowTimeout time.Duration
+	// Stale connection timeout to delete connections if they are not exported.
+	staleConnectionTimeout time.Duration
 }
 
 func newOptions() *Options {
@@ -254,10 +257,19 @@ func (o *Options) validateFlowExporterConfig() error {
 				return fmt.Errorf("IdleFlowExportTimeout is not provided in right format")
 			}
 			if o.idleFlowTimeout < o.pollInterval {
-				o.activeFlowTimeout = o.pollInterval
+				o.idleFlowTimeout = o.pollInterval
 				klog.Warningf("IdleFlowExportTimeout must be greater than or equal to FlowPollInterval")
 			}
 		}
+		if (o.activeFlowTimeout > defaultStaleConnectionTimeout) || (o.idleFlowTimeout > defaultStaleConnectionTimeout) {
+			if o.activeFlowTimeout > o.idleFlowTimeout {
+				o.staleConnectionTimeout = 2 * o.activeFlowTimeout
+			} else {
+				o.staleConnectionTimeout = 2 * o.idleFlowTimeout
+			}
+		} else {
+			o.staleConnectionTimeout = defaultStaleConnectionTimeout
+		}
 	}
 	return nil
 }
diff --git a/cmd/flow-aggregator/flow-aggregator.go b/cmd/flow-aggregator/flow-aggregator.go
index bfc04ea8d..10f47fc3c 100644
--- a/cmd/flow-aggregator/flow-aggregator.go
+++ b/cmd/flow-aggregator/flow-aggregator.go
@@ -52,12 +52,12 @@ func genObservationDomainID(k8sClient kubernetes.Interface) uint32 {
 	)
 	var clusterUUID uuid.UUID
 	if err := wait.PollImmediate(retryInterval, timeout, func() (bool, error) {
-		if clusterIdentity, _, err := clusterIdentityProvider.Get(); err != nil {
+		clusterIdentity, _, err := clusterIdentityProvider.Get()
+		if err != nil {
 			return false, nil
-		} else {
-			clusterUUID = clusterIdentity.UUID
-			return true, nil
 		}
+		clusterUUID = clusterIdentity.UUID
+		return true, nil
 	}); err != nil {
 		klog.Warningf(
 			"Unable to retrieve cluster UUID after %v (does ConfigMap '%s/%s' exist?); will generate a random observation domain ID",
diff --git a/docs/egress.md b/docs/egress.md
index 3ad0ca797..a10d75adc 100644
--- a/docs/egress.md
+++ b/docs/egress.md
@@ -284,7 +284,7 @@ egress-staging       10.10.0.105    1m    node-5
 Now, the packets from the Pods with in the `prod` Namespace to the external
 network will be redirected to the `node-4` Node and SNATed to `10.10.0.104`
 while the packets from the Pods in the `staging` Namespace to the external
-network will be redirected to the `node-5` Node and SNATed to `10.10.0.12`.
+network will be redirected to the `node-5` Node and SNATed to `10.10.0.105`.
 
 In this configuration, if the `node-4` Node powers off, re-configuring
 `10.10.0.104` to another Node or updating the `egressIP` of `egress-prod` to
diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go
index fe5733d65..e6925ee46 100644
--- a/pkg/agent/agent.go
+++ b/pkg/agent/agent.go
@@ -589,9 +589,8 @@ func (i *Initializer) setupDefaultTunnelInterface() error {
 		if err := i.ovsBridgeClient.DeletePort(tunnelIface.PortUUID); err != nil {
 			if i.networkConfig.TrafficEncapMode.SupportsEncap() {
 				return fmt.Errorf("failed to remove tunnel port %s with wrong tunnel type: %s", tunnelPortName, err)
-			} else {
-				klog.Errorf("Failed to remove tunnel port %s in NoEncapMode: %v", tunnelPortName, err)
 			}
+			klog.Errorf("Failed to remove tunnel port %s in NoEncapMode: %v", tunnelPortName, err)
 		} else {
 			klog.Infof("Removed tunnel port %s with tunnel type: %s", tunnelPortName, tunnelIface.TunnelInterfaceConfig.Type)
 			i.ifaceStore.DeleteInterface(tunnelIface)
diff --git a/pkg/agent/cniserver/pod_configuration.go b/pkg/agent/cniserver/pod_configuration.go
index 7f762efa6..3d823ea6e 100644
--- a/pkg/agent/cniserver/pod_configuration.go
+++ b/pkg/agent/cniserver/pod_configuration.go
@@ -107,9 +107,8 @@ func parseContainerIPs(ipcs []*current.IPConfig) ([]net.IP, error) {
 	}
 	if len(ips) > 0 {
 		return ips, nil
-	} else {
-		return nil, fmt.Errorf("failed to find a valid IP address")
 	}
+	return nil, fmt.Errorf("failed to find a valid IP address")
 }
 
 func buildContainerConfig(
@@ -240,9 +239,8 @@ func (pc *podConfigurator) configureInterfaces(
 	var containerConfig *interfacestore.InterfaceConfig
 	if containerConfig, err = pc.connectInterfaceToOVS(podName, podNameSpace, containerID, hostIface, containerIface, result.IPs, containerAccess); err != nil {
 		return fmt.Errorf("failed to connect to ovs for container %s: %v", containerID, err)
-	} else {
-		success = true
 	}
+	success = true
 	defer func() {
 		if !success {
 			_ = pc.disconnectInterfaceFromOVS(containerConfig)
@@ -272,9 +270,8 @@ func (pc *podConfigurator) createOVSPort(ovsPortName string, ovsAttachInfo map[s
 	if err != nil {
 		klog.Errorf("Failed to add OVS port %s, remove from local cache: %v", ovsPortName, err)
 		return "", err
-	} else {
-		return portUUID, nil
 	}
+	return portUUID, nil
 }
 
 func (pc *podConfigurator) removeInterfaces(containerID string) error {
@@ -380,9 +377,8 @@ func (pc *podConfigurator) validateOVSInterfaceConfig(containerID string, contai
 		}
 		return fmt.Errorf("interface IP %s does not match container %s IP",
 			getContainerIPsString(containerConfig.IPs), containerID)
-	} else {
-		return fmt.Errorf("container %s interface not found from local cache", containerID)
 	}
+	return fmt.Errorf("container %s interface not found from local cache", containerID)
 }
 
 func parsePrevResult(conf *NetworkConfig) error {
diff --git a/pkg/agent/controller/egress/egress_controller.go b/pkg/agent/controller/egress/egress_controller.go
index dda8d89c7..3061caeb4 100644
--- a/pkg/agent/controller/egress/egress_controller.go
+++ b/pkg/agent/controller/egress/egress_controller.go
@@ -32,6 +32,7 @@ import (
 	"k8s.io/apimachinery/pkg/watch"
 	coreinformers "k8s.io/client-go/informers/core/v1"
 	"k8s.io/client-go/tools/cache"
+	"k8s.io/client-go/util/retry"
 	"k8s.io/client-go/util/workqueue"
 	"k8s.io/klog/v2"
 
@@ -521,15 +522,34 @@ func (c *EgressController) unbindPodEgress(pod, egress string) (string, bool) {
 	return "", false
 }
 
-func (c *EgressController) updateEgressStatus(egress *crdv1a2.Egress, nodeName string) error {
-	if egress.Status.EgressNode == nodeName {
-		return nil
-	}
-	klog.V(2).InfoS("Updating Egress status", "Egress", egress.Name, "oldNode", egress.Status.EgressNode, "newNode", nodeName)
+func (c *EgressController) updateEgressStatus(egress *crdv1a2.Egress, isLocal bool) error {
 	toUpdate := egress.DeepCopy()
-	toUpdate.Status.EgressNode = nodeName
-	if _, err := c.crdClient.CrdV1alpha2().Egresses().UpdateStatus(context.TODO(), toUpdate, metav1.UpdateOptions{}); err != nil {
-		return fmt.Errorf("updating Egress %s status error: %v", egress.Name, err)
+	var updateErr, getErr error
+	if err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+		if isLocal {
+			// Do nothing if the current EgressNode in status is already this Node.
+			if toUpdate.Status.EgressNode == c.nodeName {
+				return nil
+			}
+			toUpdate.Status.EgressNode = c.nodeName
+		} else {
+			// Do nothing if the current EgressNode in status is not this Node.
+			if toUpdate.Status.EgressNode != c.nodeName {
+				return nil
+			}
+			toUpdate.Status.EgressNode = ""
+		}
+		klog.V(2).InfoS("Updating Egress status", "Egress", egress.Name, "oldNode", egress.Status.EgressNode, "newNode", toUpdate.Status.EgressNode)
+		_, updateErr = c.crdClient.CrdV1alpha2().Egresses().UpdateStatus(context.TODO(), toUpdate, metav1.UpdateOptions{})
+		if updateErr != nil && errors.IsConflict(updateErr) {
+			if toUpdate, getErr = c.crdClient.CrdV1alpha2().Egresses().Get(context.TODO(), egress.Name, metav1.GetOptions{}); getErr != nil {
+				return getErr
+			}
+		}
+		// Return the error from UPDATE.
+		return updateErr
+	}); err != nil {
+		return err
 	}
 	klog.V(2).InfoS("Updated Egress status", "Egress", egress.Name)
 	metrics.AntreaEgressStatusUpdates.Inc()
@@ -584,9 +604,6 @@ func (c *EgressController) syncEgress(egressName string) error {
 		if err := c.ipAssigner.AssignIP(egress.Spec.EgressIP); err != nil {
 			return err
 		}
-		if err := c.updateEgressStatus(egress, c.nodeName); err != nil {
-			return err
-		}
 	} else {
 		// Unassign the Egress IP from the local Node if it was assigned by the agent.
 		if err := c.ipAssigner.UnassignIP(egress.Spec.EgressIP); err != nil {
@@ -610,6 +627,10 @@ func (c *EgressController) syncEgress(egressName string) error {
 		eState.mark = mark
 	}
 
+	if err := c.updateEgressStatus(egress, c.localIPDetector.IsLocalIP(egress.Spec.EgressIP)); err != nil {
+		return fmt.Errorf("update Egress %s status error: %v", egressName, err)
+	}
+
 	// Copy the previous ofPorts and Pods. They will be used to identify stale ofPorts and Pods.
 	staleOFPorts := eState.ofPorts.Union(nil)
 	stalePods := eState.pods.Union(nil)
diff --git a/pkg/agent/controller/networkpolicy/packetin.go b/pkg/agent/controller/networkpolicy/packetin.go
index 8657c633b..5f531e5d5 100644
--- a/pkg/agent/controller/networkpolicy/packetin.go
+++ b/pkg/agent/controller/networkpolicy/packetin.go
@@ -305,34 +305,33 @@ func (c *Controller) rejectRequest(pktIn *ofctrl.PacketIn) error {
 			oriTCPSeqNum+1,
 			TCPAck|TCPRst,
 			true)
-	} else {
-		// Use ICMP host administratively prohibited for ICMP, UDP, SCTP reject.
-		icmpType := ICMPDstUnreachableType
-		icmpCode := ICMPDstHostAdminProhibitedCode
-		ipHdrLen := IPv4HdrLen
-		if isIPv6 {
-			icmpType = ICMPv6DstUnreachableType
-			icmpCode = ICMPv6DstAdminProhibitedCode
-			ipHdrLen = IPv6HdrLen
-		}
-		ipHdr, _ := pktIn.Data.Data.MarshalBinary()
-		icmpData := make([]byte, int(ICMPUnusedHdrLen+ipHdrLen+8))
-		// Put ICMP unused header in Data prop and set it to zero.
-		binary.BigEndian.PutUint32(icmpData[:ICMPUnusedHdrLen], 0)
-		copy(icmpData[ICMPUnusedHdrLen:], ipHdr[:ipHdrLen+8])
-		return c.ofClient.SendICMPPacketOut(
-			srcMAC.String(),
-			dstMAC.String(),
-			srcIP,
-			dstIP,
-			inPort,
-			-1,
-			isIPv6,
-			icmpType,
-			icmpCode,
-			icmpData,
-			true)
 	}
+	// Use ICMP host administratively prohibited for ICMP, UDP, SCTP reject.
+	icmpType := ICMPDstUnreachableType
+	icmpCode := ICMPDstHostAdminProhibitedCode
+	ipHdrLen := IPv4HdrLen
+	if isIPv6 {
+		icmpType = ICMPv6DstUnreachableType
+		icmpCode = ICMPv6DstAdminProhibitedCode
+		ipHdrLen = IPv6HdrLen
+	}
+	ipHdr, _ := pktIn.Data.Data.MarshalBinary()
+	icmpData := make([]byte, int(ICMPUnusedHdrLen+ipHdrLen+8))
+	// Put ICMP unused header in Data prop and set it to zero.
+	binary.BigEndian.PutUint32(icmpData[:ICMPUnusedHdrLen], 0)
+	copy(icmpData[ICMPUnusedHdrLen:], ipHdr[:ipHdrLen+8])
+	return c.ofClient.SendICMPPacketOut(
+		srcMAC.String(),
+		dstMAC.String(),
+		srcIP,
+		dstIP,
+		inPort,
+		-1,
+		isIPv6,
+		icmpType,
+		icmpCode,
+		icmpData,
+		true)
 }
 
 func (c *Controller) storeDenyConnection(pktIn *ofctrl.PacketIn) error {
diff --git a/pkg/agent/controller/networkpolicy/reconciler.go b/pkg/agent/controller/networkpolicy/reconciler.go
index c6b2c0eec..a559fee5a 100644
--- a/pkg/agent/controller/networkpolicy/reconciler.go
+++ b/pkg/agent/controller/networkpolicy/reconciler.go
@@ -268,9 +268,8 @@ func (r *reconciler) getOFRuleTable(rule *CompletedRule) binding.TableIDType {
 	if !rule.isAntreaNetworkPolicyRule() {
 		if rule.Direction == v1beta2.DirectionIn {
 			return openflow.IngressRuleTable
-		} else {
-			return openflow.EgressRuleTable
 		}
+		return openflow.EgressRuleTable
 	}
 	var ruleTables []binding.TableIDType
 	if rule.Direction == v1beta2.DirectionIn {
diff --git a/pkg/agent/controller/traceflow/traceflow_controller.go b/pkg/agent/controller/traceflow/traceflow_controller.go
index 79ad1b9a6..c88a89c07 100644
--- a/pkg/agent/controller/traceflow/traceflow_controller.go
+++ b/pkg/agent/controller/traceflow/traceflow_controller.go
@@ -472,9 +472,8 @@ func (c *Controller) preparePacket(tf *crdv1alpha1.Traceflow, intf *interfacesto
 		if packet.DestinationIP == nil {
 			if packet.IsIPv6 {
 				return nil, errors.New("destination Pod does not have an IPv6 address")
-			} else {
-				return nil, errors.New("destination Pod does not have an IPv4 address")
 			}
+			return nil, errors.New("destination Pod does not have an IPv4 address")
 		}
 	} else if tf.Spec.Destination.Service != "" {
 		dstSvc, err := c.serviceLister.Services(tf.Spec.Destination.Namespace).Get(tf.Spec.Destination.Service)
diff --git a/pkg/agent/flowexporter/connections/connections.go b/pkg/agent/flowexporter/connections/connections.go
index 9fe0ddefa..b6af4ea03 100644
--- a/pkg/agent/flowexporter/connections/connections.go
+++ b/pkg/agent/flowexporter/connections/connections.go
@@ -17,6 +17,7 @@ package connections
 import (
 	"fmt"
 	"sync"
+	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/klog/v2"
@@ -26,21 +27,28 @@ import (
 	"antrea.io/antrea/pkg/agent/proxy"
 )
 
+const (
+	periodicDeleteInterval = time.Minute
+)
+
 type connectionStore struct {
-	connections   map[flowexporter.ConnectionKey]*flowexporter.Connection
-	ifaceStore    interfacestore.InterfaceStore
-	antreaProxier proxy.Proxier
-	mutex         sync.Mutex
+	connections            map[flowexporter.ConnectionKey]*flowexporter.Connection
+	ifaceStore             interfacestore.InterfaceStore
+	antreaProxier          proxy.Proxier
+	staleConnectionTimeout time.Duration
+	mutex                  sync.Mutex
 }
 
 func NewConnectionStore(
 	ifaceStore interfacestore.InterfaceStore,
 	proxier proxy.Proxier,
+	staleConnectionTimeout time.Duration,
 ) connectionStore {
 	return connectionStore{
-		connections:   make(map[flowexporter.ConnectionKey]*flowexporter.Connection),
-		ifaceStore:    ifaceStore,
-		antreaProxier: proxier,
+		connections:            make(map[flowexporter.ConnectionKey]*flowexporter.Connection),
+		ifaceStore:             ifaceStore,
+		antreaProxier:          proxier,
+		staleConnectionTimeout: staleConnectionTimeout,
 	}
 }
 
diff --git a/pkg/agent/flowexporter/connections/conntrack_connections.go b/pkg/agent/flowexporter/connections/conntrack_connections.go
index 61580931e..265486672 100644
--- a/pkg/agent/flowexporter/connections/conntrack_connections.go
+++ b/pkg/agent/flowexporter/connections/conntrack_connections.go
@@ -57,6 +57,7 @@ func NewConntrackConnectionStore(
 	proxier proxy.Proxier,
 	npQuerier querier.AgentNetworkPolicyInfoQuerier,
 	pollInterval time.Duration,
+	staleConnectionTimeout time.Duration,
 ) *ConntrackConnectionStore {
 	return &ConntrackConnectionStore{
 		flowRecords:          flowRecords,
@@ -65,7 +66,7 @@ func NewConntrackConnectionStore(
 		v6Enabled:            v6Enabled,
 		networkPolicyQuerier: npQuerier,
 		pollInterval:         pollInterval,
-		connectionStore:      NewConnectionStore(ifaceStore, proxier),
+		connectionStore:      NewConnectionStore(ifaceStore, proxier, staleConnectionTimeout),
 	}
 }
 
@@ -100,12 +101,28 @@ func (cs *ConntrackConnectionStore) Run(stopCh <-chan struct{}) {
 // TODO: As optimization, only poll invalid/closed connections during every poll, and poll the established connections right before the export.
 func (cs *ConntrackConnectionStore) Poll() ([]int, error) {
 	klog.V(2).Infof("Polling conntrack")
-	// Reset IsPresent flag for all connections in connection map before dumping flows in conntrack module.
-	// if the connection does not exist in conntrack table and has been exported, we will delete it from connection map.
+	// Reset IsPresent flag for all connections in connection map before dumping
+	// flows in conntrack module. If the connection does not exist in conntrack
+	// table and has been exported, then we will delete it from connection map.
+	// In addition, if the connection was not exported for a specific time period,
+	// then we consider it to be stale and delete it.
 	deleteIfStaleOrResetConn := func(key flowexporter.ConnectionKey, conn *flowexporter.Connection) error {
-		if !conn.IsPresent && conn.DyingAndDoneExport {
-			if err := cs.DeleteConnWithoutLock(key); err != nil {
-				return err
+		if !conn.IsPresent {
+			if conn.DyingAndDoneExport {
+				if err := cs.DeleteConnWithoutLock(key); err != nil {
+					return err
+				}
+			} else {
+				record, exists := cs.flowRecords.GetFlowRecordFromMap(&key)
+				if exists {
+					// Delete the connection if it was not exported for the time
+					// period as specified by the stale connection timeout.
+					if time.Since(record.LastExportTime) >= cs.staleConnectionTimeout {
+						// Ignore error if flow record not found.
+						cs.flowRecords.DeleteFlowRecordFromMap(&key)
+						delete(cs.connections, key)
+					}
+				}
 			}
 		} else {
 			conn.IsPresent = false
diff --git a/pkg/agent/flowexporter/connections/conntrack_linux.go b/pkg/agent/flowexporter/connections/conntrack_linux.go
index 0138bbdbc..1725b85fc 100644
--- a/pkg/agent/flowexporter/connections/conntrack_linux.go
+++ b/pkg/agent/flowexporter/connections/conntrack_linux.go
@@ -201,7 +201,6 @@ func stateToString(state uint8) string {
 	}
 	if state > uint8(9) { // invalid state number
 		return ""
-	} else {
-		return stateList[state]
 	}
+	return stateList[state]
 }
diff --git a/pkg/agent/flowexporter/connections/deny_connections.go b/pkg/agent/flowexporter/connections/deny_connections.go
index d7709868b..63a81d2d1 100644
--- a/pkg/agent/flowexporter/connections/deny_connections.go
+++ b/pkg/agent/flowexporter/connections/deny_connections.go
@@ -32,9 +32,31 @@ type DenyConnectionStore struct {
 }
 
 func NewDenyConnectionStore(ifaceStore interfacestore.InterfaceStore,
-	proxier proxy.Proxier) *DenyConnectionStore {
+	proxier proxy.Proxier, staleConnectionTimeout time.Duration) *DenyConnectionStore {
 	return &DenyConnectionStore{
-		connectionStore: NewConnectionStore(ifaceStore, proxier),
+		connectionStore: NewConnectionStore(ifaceStore, proxier, staleConnectionTimeout),
+	}
+}
+
+func (ds *DenyConnectionStore) RunPeriodicDeletion(stopCh <-chan struct{}) {
+	pollTicker := time.NewTicker(periodicDeleteInterval)
+	defer pollTicker.Stop()
+
+	for {
+		select {
+		case <-stopCh:
+			break
+		case <-pollTicker.C:
+			deleteIfStaleConn := func(key flowexporter.ConnectionKey, conn *flowexporter.Connection) error {
+				// Delete the connection if it was not exported in last five minutes.
+				if time.Since(conn.LastExportTime) >= ds.staleConnectionTimeout {
+					delete(ds.connections, key)
+				}
+				return nil
+			}
+			ds.ForAllConnectionsDo(deleteIfStaleConn)
+			klog.V(2).Infof("Stale connections in the Deny Connection Store are successfully deleted.")
+		}
 	}
 }
 
@@ -52,21 +74,20 @@ func (ds *DenyConnectionStore) AddOrUpdateConn(conn *flowexporter.Connection, ti
 		conn.StopTime = timeSeen
 		klog.V(2).Infof("Deny connection with flowKey %v has been updated.", connKey)
 		return
-	} else {
-		conn.StartTime = timeSeen
-		conn.StopTime = timeSeen
-		conn.LastExportTime = timeSeen
-		conn.DeltaBytes = bytes
-		conn.OriginalBytes = bytes
-		conn.DeltaPackets = uint64(1)
-		conn.OriginalPackets = uint64(1)
-		ds.fillPodInfo(conn)
-		protocolStr := ip.IPProtocolNumberToString(conn.FlowKey.Protocol, "UnknownProtocol")
-		serviceStr := fmt.Sprintf("%s:%d/%s", conn.DestinationServiceAddress, conn.DestinationServicePort, protocolStr)
-		ds.fillServiceInfo(conn, serviceStr)
-		metrics.TotalDenyConnections.Inc()
-		ds.connections[connKey] = conn
 	}
+	conn.StartTime = timeSeen
+	conn.StopTime = timeSeen
+	conn.LastExportTime = timeSeen
+	conn.DeltaBytes = bytes
+	conn.OriginalBytes = bytes
+	conn.DeltaPackets = uint64(1)
+	conn.OriginalPackets = uint64(1)
+	ds.fillPodInfo(conn)
+	protocolStr := ip.IPProtocolNumberToString(conn.FlowKey.Protocol, "UnknownProtocol")
+	serviceStr := fmt.Sprintf("%s:%d/%s", conn.DestinationServiceAddress, conn.DestinationServicePort, protocolStr)
+	ds.fillServiceInfo(conn, serviceStr)
+	metrics.TotalDenyConnections.Inc()
+	ds.connections[connKey] = conn
 }
 
 // ResetConnStatsWithoutLock resets DeltaBytes and DeltaPackets of connection
diff --git a/pkg/agent/flowexporter/exporter/exporter.go b/pkg/agent/flowexporter/exporter/exporter.go
index 332f5bfd5..42cffc167 100644
--- a/pkg/agent/flowexporter/exporter/exporter.go
+++ b/pkg/agent/flowexporter/exporter/exporter.go
@@ -710,12 +710,10 @@ func (exp *flowExporter) findFlowType(conn flowexporter.Connection) uint8 {
 				return ipfixregistry.FlowTypeInterNode
 			}
 			return ipfixregistry.FlowTypeIntraNode
-		} else {
-			return ipfixregistry.FlowTypeToExternal
 		}
-	} else {
-		// We do not support External-To-Pod flows for now.
-		klog.Warningf("Source IP: %s doesn't exist in PodCIDRs", conn.FlowKey.SourceAddress.String())
-		return 0
+		return ipfixregistry.FlowTypeToExternal
 	}
+	// We do not support External-To-Pod flows for now.
+	klog.Warningf("Source IP: %s doesn't exist in PodCIDRs", conn.FlowKey.SourceAddress.String())
+	return 0
 }
diff --git a/pkg/agent/flowexporter/flowrecords/flow_records.go b/pkg/agent/flowexporter/flowrecords/flow_records.go
index 1c8a61e99..1e76444c8 100644
--- a/pkg/agent/flowexporter/flowrecords/flow_records.go
+++ b/pkg/agent/flowexporter/flowrecords/flow_records.go
@@ -15,6 +15,7 @@
 package flowrecords
 
 import (
+	"fmt"
 	"sync"
 	"time"
 
@@ -100,8 +101,7 @@ func (fr *FlowRecords) AddFlowRecordWithoutLock(connKey *flowexporter.Connection
 	fr.recordsMap[*connKey] = *record
 }
 
-// GetFlowRecordFromMap gets the flow record from record map given connection key.
-// This is used only for unit tests.
+// GetFlowRecordFromMap gets the flow record from record map given the connection key.
 func (fr *FlowRecords) GetFlowRecordFromMap(connKey *flowexporter.ConnectionKey) (*flowexporter.FlowRecord, bool) {
 	fr.mutex.Lock()
 	defer fr.mutex.Unlock()
@@ -109,6 +109,18 @@ func (fr *FlowRecords) GetFlowRecordFromMap(connKey *flowexporter.ConnectionKey)
 	return &record, exists
 }
 
+// DeleteFlowRecordFromMap deletes the flow record from record map given the connection key.
+func (fr *FlowRecords) DeleteFlowRecordFromMap(connKey *flowexporter.ConnectionKey) error {
+	fr.mutex.Lock()
+	defer fr.mutex.Unlock()
+	_, exists := fr.recordsMap[*connKey]
+	if !exists {
+		return fmt.Errorf("record with key %v doesn't exist in map", connKey)
+	}
+	delete(fr.recordsMap, *connKey)
+	return nil
+}
+
 // ValidateAndUpdateStats validates and updates the flow record given the connection
 // key. Caller is expected to grab lock.
 func (fr *FlowRecords) ValidateAndUpdateStats(connKey flowexporter.ConnectionKey, record flowexporter.FlowRecord) {
@@ -136,3 +148,16 @@ func (fr *FlowRecords) ForAllFlowRecordsDo(callback flowexporter.FlowRecordCallB
 	}
 	return nil
 }
+
+// ForAllFlowRecordsDoWithoutLock executes the callback for all records in the flow
+// record map. This is used in the perf testing.
+func (fr *FlowRecords) ForAllFlowRecordsDoWithoutLock(callback flowexporter.FlowRecordCallBack) error {
+	for k, v := range fr.recordsMap {
+		err := callback(k, v)
+		if err != nil {
+			klog.Errorf("Error when executing callback for flow record: %v", err)
+			return err
+		}
+	}
+	return nil
+}
diff --git a/pkg/agent/nodeportlocal/portcache/port_table.go b/pkg/agent/nodeportlocal/portcache/port_table.go
index 644af03ce..19a776913 100644
--- a/pkg/agent/nodeportlocal/portcache/port_table.go
+++ b/pkg/agent/nodeportlocal/portcache/port_table.go
@@ -119,7 +119,7 @@ func (pt *PortTable) AddRule(podIP string, podPort int) (int, error) {
 	if err != nil {
 		return 0, err
 	}
-	if err := pt.PodPortRules.AddRule(nodePort, fmt.Sprintf("%s:%d", podIP, podPort)); err != nil {
+	if err := pt.PodPortRules.AddRule(nodePort, podIP, podPort); err != nil {
 		if err := socket.Close(); err != nil {
 			klog.ErrorS(err, "Unexpected error when closing socket")
 		}
@@ -138,7 +138,7 @@ func (pt *PortTable) DeleteRule(podIP string, podPort int) error {
 	pt.tableLock.Lock()
 	defer pt.tableLock.Unlock()
 	data := pt.getEntryByPodIPPort(podIP, podPort)
-	if err := pt.PodPortRules.DeleteRule(data.NodePort, fmt.Sprintf("%s:%d", podIP, podPort)); err != nil {
+	if err := pt.PodPortRules.DeleteRule(data.NodePort, podIP, podPort); err != nil {
 		return err
 	}
 	if err := data.socket.Close(); err != nil {
diff --git a/pkg/agent/nodeportlocal/rules/iptable_rule.go b/pkg/agent/nodeportlocal/rules/iptable_rule.go
index 7cdb0cf9e..af4bb91e9 100644
--- a/pkg/agent/nodeportlocal/rules/iptable_rule.go
+++ b/pkg/agent/nodeportlocal/rules/iptable_rule.go
@@ -56,16 +56,16 @@ func (ipt *iptablesRules) Init() error {
 // traffic) and OUTPUT chain (for locally-generated traffic). All NPL DNAT rules
 // will be added to this chain.
 func (ipt *iptablesRules) initRules() error {
-	if err := ipt.table.EnsureChain(iptables.NATTable, NodePortLocalChain); err != nil {
+	if err := ipt.table.EnsureChain(iptables.ProtocolIPv4, iptables.NATTable, NodePortLocalChain); err != nil {
 		return err
 	}
 	ruleSpec := []string{
 		"-p", "tcp", "-m", "addrtype", "--dst-type", "LOCAL", "-j", NodePortLocalChain,
 	}
-	if err := ipt.table.EnsureRule(iptables.NATTable, iptables.PreRoutingChain, ruleSpec); err != nil {
+	if err := ipt.table.AppendRule(iptables.ProtocolIPv4, iptables.NATTable, iptables.PreRoutingChain, ruleSpec); err != nil {
 		return err
 	}
-	if err := ipt.table.EnsureRule(iptables.NATTable, iptables.OutputChain, ruleSpec); err != nil {
+	if err := ipt.table.AppendRule(iptables.ProtocolIPv4, iptables.NATTable, iptables.OutputChain, ruleSpec); err != nil {
 		return err
 	}
 	return nil
@@ -78,13 +78,14 @@ func buildRuleForPod(port int, podIP string) []string {
 	}
 }
 
-// AddRule appends a DNAT rule in NodePortLocalChain chain of NAT table
-func (ipt *iptablesRules) AddRule(port int, podIP string) error {
-	rule := buildRuleForPod(port, podIP)
-	if err := ipt.table.EnsureRule(iptables.NATTable, NodePortLocalChain, rule); err != nil {
+// AddRule appends a DNAT rule in NodePortLocalChain chain of NAT table.
+func (ipt *iptablesRules) AddRule(nodePort int, podIP string, podPort int) error {
+	podAddr := fmt.Sprintf("%s:%d", podIP, podPort)
+	rule := buildRuleForPod(nodePort, podAddr)
+	if err := ipt.table.AppendRule(iptables.ProtocolIPv4, iptables.NATTable, NodePortLocalChain, rule); err != nil {
 		return err
 	}
-	klog.Infof("Successfully added DNAT rule for Pod IP %s, port %d", podIP, port)
+	klog.InfoS("Successfully added DNAT rule", "podAddr", podAddr, "nodePort", nodePort)
 	return nil
 }
 
@@ -107,18 +108,19 @@ func (ipt *iptablesRules) AddAllRules(nplList []PodNodePort) error {
 }
 
 // DeleteRule deletes a specific NPL rule from NodePortLocalChain chain
-func (ipt *iptablesRules) DeleteRule(port int, podIP string) error {
-	klog.Infof("Deleting DNAT rule for Pod IP %s, port %d", podIP, port)
-	rule := buildRuleForPod(port, podIP)
-	if err := ipt.table.DeleteRule(iptables.NATTable, NodePortLocalChain, rule); err != nil {
+func (ipt *iptablesRules) DeleteRule(nodePort int, podIP string, podPort int) error {
+	podAddr := fmt.Sprintf("%s:%d", podIP, podPort)
+	rule := buildRuleForPod(nodePort, podAddr)
+	if err := ipt.table.DeleteRule(iptables.ProtocolIPv4, iptables.NATTable, NodePortLocalChain, rule); err != nil {
 		return err
 	}
+	klog.InfoS("Successfully deleted DNAT rule", "podAddr", podAddr, "nodePort", nodePort)
 	return nil
 }
 
 // DeleteAllRules deletes all NPL rules programmed in the node
 func (ipt *iptablesRules) DeleteAllRules() error {
-	exists, err := ipt.table.ChainExists(iptables.NATTable, NodePortLocalChain)
+	exists, err := ipt.table.ChainExists(iptables.ProtocolIPv4, iptables.NATTable, NodePortLocalChain)
 	if err != nil {
 		return fmt.Errorf("failed to check if NodePortLocal chain exists in NAT table: %v", err)
 	}
@@ -128,13 +130,13 @@ func (ipt *iptablesRules) DeleteAllRules() error {
 	ruleSpec := []string{
 		"-p", "tcp", "-m", "addrtype", "--dst-type", "LOCAL", "-j", NodePortLocalChain,
 	}
-	if err := ipt.table.DeleteRule(iptables.NATTable, iptables.PreRoutingChain, ruleSpec); err != nil {
+	if err := ipt.table.DeleteRule(iptables.ProtocolIPv4, iptables.NATTable, iptables.PreRoutingChain, ruleSpec); err != nil {
 		return err
 	}
-	if err := ipt.table.DeleteRule(iptables.NATTable, iptables.OutputChain, ruleSpec); err != nil {
+	if err := ipt.table.DeleteRule(iptables.ProtocolIPv4, iptables.NATTable, iptables.OutputChain, ruleSpec); err != nil {
 		return err
 	}
-	if err := ipt.table.DeleteChain(iptables.NATTable, NodePortLocalChain); err != nil {
+	if err := ipt.table.DeleteChain(iptables.ProtocolIPv4, iptables.NATTable, NodePortLocalChain); err != nil {
 		return err
 	}
 	return nil
diff --git a/pkg/agent/nodeportlocal/rules/rules.go b/pkg/agent/nodeportlocal/rules/rules.go
index a4a70b6d8..7c9bca1ab 100644
--- a/pkg/agent/nodeportlocal/rules/rules.go
+++ b/pkg/agent/nodeportlocal/rules/rules.go
@@ -19,8 +19,8 @@ package rules
 // PodPortRules is an interface to abstract operations on rules for Pods
 type PodPortRules interface {
 	Init() error
-	AddRule(port int, podip string) error
-	DeleteRule(port int, podip string) error
+	AddRule(nodePort int, podIP string, podPort int) error
+	DeleteRule(nodePort int, podIP string, podPort int) error
 	DeleteAllRules() error
 	AddAllRules(nplList []PodNodePort) error
 }
diff --git a/pkg/agent/openflow/network_policy.go b/pkg/agent/openflow/network_policy.go
index 416bfd772..26b3dd4cb 100644
--- a/pkg/agent/openflow/network_policy.go
+++ b/pkg/agent/openflow/network_policy.go
@@ -63,15 +63,13 @@ func (a *IPAddress) GetMatchKey(addrType types.AddressType) *types.MatchKey {
 	case types.SrcAddress:
 		if ipArr.To4() != nil {
 			return MatchSrcIP
-		} else {
-			return MatchSrcIPv6
 		}
+		return MatchSrcIPv6
 	case types.DstAddress:
 		if ipArr.To4() != nil {
 			return MatchDstIP
-		} else {
-			return MatchDstIPv6
 		}
+		return MatchDstIPv6
 	default:
 		klog.Errorf("Unknown AddressType %d in IPAddress", addrType)
 		return Unsupported
@@ -101,15 +99,13 @@ func (a *IPNetAddress) GetMatchKey(addrType types.AddressType) *types.MatchKey {
 	case types.SrcAddress:
 		if ipAddr.IP.To4() != nil {
 			return MatchSrcIPNet
-		} else {
-			return MatchSrcIPNetv6
 		}
+		return MatchSrcIPNetv6
 	case types.DstAddress:
 		if ipAddr.IP.To4() != nil {
 			return MatchDstIPNet
-		} else {
-			return MatchDstIPNetv6
 		}
+		return MatchDstIPNetv6
 	default:
 		klog.Errorf("Unknown AddressType %d in IPNetAddress", addrType)
 		return Unsupported
@@ -335,16 +331,15 @@ func (ctx *conjMatchFlowContext) deleteAction(conjID uint32) *flowChange {
 			flow:       ctx.flow,
 			changeType: deletion,
 		}
-	} else {
-		// Modify the Openflow entry and reset the other conjunctive actions.
-		var actions []*conjunctiveAction
-		for _, act := range ctx.actions {
-			if act.conjID != conjID {
-				actions = append(actions, act)
-			}
+	}
+	// Modify the Openflow entry and reset the other conjunctive actions.
+	var actions []*conjunctiveAction
+	for _, act := range ctx.actions {
+		if act.conjID != conjID {
+			actions = append(actions, act)
 		}
-		return ctx.createOrUpdateConjunctiveMatchFlow(actions)
 	}
+	return ctx.createOrUpdateConjunctiveMatchFlow(actions)
 }
 
 // addAction adds the specified policyRuleConjunction into conjunctiveMatchFlow's actions, and then returns the flowChange.
@@ -1572,9 +1567,8 @@ func parseMetricFlow(flow string) (uint32, types.RuleMetric) {
 	// table=101, n_packets=9, n_bytes=666, priority=200,reg0=0x100000/0x100000,reg3=0x5 actions=drop
 	if _, ok := flowMap[dropIdentifier]; ok {
 		return parseDropFlow(flowMap)
-	} else {
-		return parseAllowFlow(flowMap)
 	}
+	return parseAllowFlow(flowMap)
 }
 
 func (c *client) NetworkPolicyMetrics() map[uint32]*types.RuleMetric {
diff --git a/pkg/agent/openflow/pipeline.go b/pkg/agent/openflow/pipeline.go
index 9028f263a..be90f0861 100644
--- a/pkg/agent/openflow/pipeline.go
+++ b/pkg/agent/openflow/pipeline.go
@@ -1533,16 +1533,15 @@ func (c *client) conjunctionActionFlow(conjunctionID uint32, tableID binding.Tab
 				CTDone().
 				Cookie(c.cookieAllocator.Request(cookie.Policy).Raw()).
 				Done()
-		} else {
-			return c.pipeline[tableID].BuildFlow(ofPriority).MatchProtocol(proto).
-				MatchConjID(conjunctionID).
-				Action().LoadRegRange(int(conjReg), conjunctionID, binding.Range{0, 31}). // Traceflow.
-				Action().CT(true, nextTable, ctZone).                                     // CT action requires commit flag if actions other than NAT without arguments are specified.
-				LoadToLabelRange(uint64(conjunctionID), &labelRange).
-				CTDone().
-				Cookie(c.cookieAllocator.Request(cookie.Policy).Raw()).
-				Done()
 		}
+		return c.pipeline[tableID].BuildFlow(ofPriority).MatchProtocol(proto).
+			MatchConjID(conjunctionID).
+			Action().LoadRegRange(int(conjReg), conjunctionID, binding.Range{0, 31}). // Traceflow.
+			Action().CT(true, nextTable, ctZone).                                     // CT action requires commit flag if actions other than NAT without arguments are specified.
+			LoadToLabelRange(uint64(conjunctionID), &labelRange).
+			CTDone().
+			Cookie(c.cookieAllocator.Request(cookie.Policy).Raw()).
+			Done()
 	}
 	var flows []binding.Flow
 	for _, proto := range c.ipProtocols {
@@ -1875,19 +1874,18 @@ func (c *client) snatRuleFlow(ofPort uint32, snatIP net.IP, snatMark uint32, loc
 			Action().GotoTable(snatTable.GetNext()).
 			Cookie(c.cookieAllocator.Request(cookie.SNAT).Raw()).
 			Done()
-	} else {
-		// SNAT IP should be on a remote Node.
-		return snatTable.BuildFlow(priorityNormal).
-			MatchProtocol(ipProto).
-			MatchInPort(ofPort).
-			Action().SetSrcMAC(localGatewayMAC).
-			Action().SetDstMAC(globalVirtualMAC).
-			// Set tunnel destination to the SNAT IP.
-			Action().SetTunnelDst(snatIP).
-			Action().GotoTable(l3DecTTLTable).
-			Cookie(c.cookieAllocator.Request(cookie.SNAT).Raw()).
-			Done()
 	}
+	// SNAT IP should be on a remote Node.
+	return snatTable.BuildFlow(priorityNormal).
+		MatchProtocol(ipProto).
+		MatchInPort(ofPort).
+		Action().SetSrcMAC(localGatewayMAC).
+		Action().SetDstMAC(globalVirtualMAC).
+		// Set tunnel destination to the SNAT IP.
+		Action().SetTunnelDst(snatIP).
+		Action().GotoTable(l3DecTTLTable).
+		Cookie(c.cookieAllocator.Request(cookie.SNAT).Raw()).
+		Done()
 }
 
 // loadBalancerServiceFromOutsideFlow generates the flow to forward LoadBalancer service traffic from outside node
diff --git a/pkg/agent/proxy/proxier.go b/pkg/agent/proxy/proxier.go
index 71fe7c1f3..ebee1993c 100644
--- a/pkg/agent/proxy/proxier.go
+++ b/pkg/agent/proxy/proxier.go
@@ -686,9 +686,8 @@ func (p *metaProxierWrapper) GetServiceByIP(serviceStr string) (k8sproxy.Service
 	lastColonIndex := strings.LastIndex(serviceStr, ":")
 	if utilnet.IsIPv6String(serviceStr[:lastColonIndex]) {
 		return p.ipv6Proxier.GetServiceByIP(serviceStr)
-	} else {
-		return p.ipv4Proxier.GetServiceByIP(serviceStr)
 	}
+	return p.ipv4Proxier.GetServiceByIP(serviceStr)
 }
 
 func NewDualStackProxier(
diff --git a/pkg/agent/route/route_linux.go b/pkg/agent/route/route_linux.go
index 06cfca5b3..68aae961d 100644
--- a/pkg/agent/route/route_linux.go
+++ b/pkg/agent/route/route_linux.go
@@ -258,6 +258,7 @@ func (c *Client) syncIPTables() error {
 	var err error
 	v4Enabled := config.IsIPv4Enabled(c.nodeConfig, c.networkConfig.TrafficEncapMode)
 	v6Enabled := config.IsIPv6Enabled(c.nodeConfig, c.networkConfig.TrafficEncapMode)
+
 	c.ipt, err = iptables.New(v4Enabled, v6Enabled)
 	if err != nil {
 		return fmt.Errorf("error creating IPTables instance: %v", err)
@@ -274,11 +275,11 @@ func (c *Client) syncIPTables() error {
 		{iptables.MangleTable, iptables.OutputChain, antreaOutputChain, "Antrea: jump to Antrea output rules"},
 	}
 	for _, rule := range jumpRules {
-		if err := c.ipt.EnsureChain(rule.table, rule.dstChain); err != nil {
+		if err := c.ipt.EnsureChain(iptables.ProtocolDual, rule.table, rule.dstChain); err != nil {
 			return err
 		}
 		ruleSpec := []string{"-j", rule.dstChain, "-m", "comment", "--comment", rule.comment}
-		if err := c.ipt.EnsureRule(rule.table, rule.srcChain, ruleSpec); err != nil {
+		if err := c.ipt.AppendRule(iptables.ProtocolDual, rule.table, rule.srcChain, ruleSpec); err != nil {
 			return err
 		}
 	}
@@ -771,5 +772,5 @@ func (c *Client) DeleteSNATRule(mark uint32) error {
 	}
 	c.markToSNATIP.Delete(mark)
 	snatIP := value.(net.IP)
-	return c.ipt.DeleteRule(iptables.NATTable, antreaPostRoutingChain, c.snatRuleSpec(snatIP, mark))
+	return c.ipt.DeleteRule(iptables.ProtocolDual, iptables.NATTable, antreaPostRoutingChain, c.snatRuleSpec(snatIP, mark))
 }
diff --git a/pkg/agent/util/iptables/iptables.go b/pkg/agent/util/iptables/iptables.go
index 2c6a3fb74..dfc14a090 100644
--- a/pkg/agent/util/iptables/iptables.go
+++ b/pkg/agent/util/iptables/iptables.go
@@ -52,6 +52,15 @@ const (
 
 type Protocol byte
 
+var protocolStrMap = map[Protocol]string{
+	ProtocolIPv4: "IPv4",
+	ProtocolIPv6: "IPv6",
+}
+
+func (p Protocol) String() string {
+	return protocolStrMap[p]
+}
+
 const (
 	ProtocolDual Protocol = iota
 	ProtocolIPv4
@@ -63,20 +72,20 @@ const (
 var restoreWaitSupportedMinVersion = semver.Version{Major: 1, Minor: 6, Patch: 2}
 
 type Client struct {
-	ipts []*iptables.IPTables
+	ipts map[Protocol]*iptables.IPTables
 	// restoreWaitSupported indicates whether iptables-restore (or ip6tables-restore) supports --wait flag.
 	restoreWaitSupported bool
 }
 
 func New(enableIPV4, enableIPV6 bool) (*Client, error) {
-	var ipts []*iptables.IPTables
+	ipts := make(map[Protocol]*iptables.IPTables)
 	var restoreWaitSupported bool
 	if enableIPV4 {
 		ipt, err := iptables.New()
 		if err != nil {
 			return nil, fmt.Errorf("error creating IPTables instance: %v", err)
 		}
-		ipts = append(ipts, ipt)
+		ipts[ProtocolIPv4] = ipt
 		restoreWaitSupported = isRestoreWaitSupported(ipt)
 	}
 	if enableIPV6 {
@@ -84,7 +93,7 @@ func New(enableIPV4, enableIPV6 bool) (*Client, error) {
 		if err != nil {
 			return nil, fmt.Errorf("error creating IPTables instance for IPv6: %v", err)
 		}
-		ipts = append(ipts, ip6t)
+		ipts[ProtocolIPv6] = ip6t
 		if !restoreWaitSupported {
 			restoreWaitSupported = isRestoreWaitSupported(ip6t)
 		}
@@ -99,9 +108,12 @@ func isRestoreWaitSupported(ipt *iptables.IPTables) bool {
 }
 
 // EnsureChain checks if target chain already exists, creates it if not.
-func (c *Client) EnsureChain(table string, chain string) error {
-	for idx := range c.ipts {
-		ipt := c.ipts[idx]
+func (c *Client) EnsureChain(protocol Protocol, table string, chain string) error {
+	for p := range c.ipts {
+		ipt := c.ipts[p]
+		if !matchProtocol(ipt, protocol) {
+			continue
+		}
 		exists, err := ipt.ChainExists(table, chain)
 		if err != nil {
 			return fmt.Errorf("error checking if chain %s exists in table %s: %v", chain, table, err)
@@ -112,48 +124,56 @@ func (c *Client) EnsureChain(table string, chain string) error {
 		if err := ipt.NewChain(table, chain); err != nil {
 			return fmt.Errorf("error creating chain %s in table %s: %v", chain, table, err)
 		}
-		klog.V(2).Infof("Created chain %s in table %s", chain, table)
+		klog.V(2).InfoS("Created a chain", "chain", chain, "table", table, "protocol", p)
 	}
 	return nil
 }
 
-// ChainExists checks if a chain already exists in a table
-func (c *Client) ChainExists(table string, chain string) (bool, error) {
-	for idx := range c.ipts {
-		exists, err := c.ipts[idx].ChainExists(table, chain)
+// ChainExists checks if target chain already exists in a table
+func (c *Client) ChainExists(protocol Protocol, table string, chain string) (bool, error) {
+	for p := range c.ipts {
+		ipt := c.ipts[p]
+		if !matchProtocol(ipt, protocol) {
+			continue
+		}
+		exists, err := ipt.ChainExists(table, chain)
 		if err != nil {
 			return false, fmt.Errorf("error checking if chain %s exists in table %s: %v", chain, table, err)
 		}
-		if exists {
-			return true, nil
+		if !exists {
+			return false, nil
 		}
+		klog.V(2).InfoS("A chain exists", "chain", chain, "table", table, "protocol", p)
 	}
-	return false, nil
+	return true, nil
 }
 
-// EnsureRule checks if target rule already exists, appends it if not.
-func (c *Client) EnsureRule(table string, chain string, ruleSpec []string) error {
-	for idx := range c.ipts {
-		ipt := c.ipts[idx]
+// AppendRule checks if target rule already exists with the protocol, appends it if not.
+func (c *Client) AppendRule(protocol Protocol, table string, chain string, ruleSpec []string) error {
+	for p := range c.ipts {
+		ipt := c.ipts[p]
+		if !matchProtocol(ipt, protocol) {
+			continue
+		}
 		exist, err := ipt.Exists(table, chain, ruleSpec...)
 		if err != nil {
 			return fmt.Errorf("error checking if rule %v exists in table %s chain %s: %v", ruleSpec, table, chain, err)
 		}
 		if exist {
-			return nil
+			continue
 		}
 		if err := ipt.Append(table, chain, ruleSpec...); err != nil {
 			return fmt.Errorf("error appending rule %v to table %s chain %s: %v", ruleSpec, table, chain, err)
 		}
+		klog.V(2).InfoS("Appended a rule", "rule", ruleSpec, "table", table, "chain", chain, "protocol", p)
 	}
-	klog.V(2).Infof("Appended rule %v to table %s chain %s", ruleSpec, table, chain)
 	return nil
 }
 
 // InsertRule checks if target rule already exists, inserts it if not.
 func (c *Client) InsertRule(protocol Protocol, table string, chain string, ruleSpec []string) error {
-	for idx := range c.ipts {
-		ipt := c.ipts[idx]
+	for p := range c.ipts {
+		ipt := c.ipts[p]
 		if !matchProtocol(ipt, protocol) {
 			continue
 		}
@@ -162,13 +182,13 @@ func (c *Client) InsertRule(protocol Protocol, table string, chain string, ruleS
 			return fmt.Errorf("error checking if rule %v exists in table %s chain %s: %v", ruleSpec, table, chain, err)
 		}
 		if exist {
-			return nil
+			continue
 		}
 		if err := ipt.Insert(table, chain, 1, ruleSpec...); err != nil {
 			return fmt.Errorf("error inserting rule %v to table %s chain %s: %v", ruleSpec, table, chain, err)
 		}
+		klog.V(2).InfoS("Inserted a rule", "rule", ruleSpec, "table", table, "chain", chain)
 	}
-	klog.V(2).Infof("Inserted rule %v to table %s chain %s", ruleSpec, table, chain)
 	return nil
 }
 
@@ -185,46 +205,59 @@ func matchProtocol(ipt *iptables.IPTables, protocol Protocol) bool {
 }
 
 // DeleteRule checks if target rule already exists, deletes the rule if found.
-func (c *Client) DeleteRule(table string, chain string, ruleSpec []string) error {
-	for idx := range c.ipts {
-		exist, err := c.ipts[idx].Exists(table, chain, ruleSpec...)
+func (c *Client) DeleteRule(protocol Protocol, table string, chain string, ruleSpec []string) error {
+	for p := range c.ipts {
+		ipt := c.ipts[p]
+		if !matchProtocol(ipt, protocol) {
+			continue
+		}
+		exist, err := ipt.Exists(table, chain, ruleSpec...)
 		if err != nil {
 			return fmt.Errorf("error checking if rule %v exists in table %s chain %s: %v", ruleSpec, table, chain, err)
 		}
 		if !exist {
-			return nil
+			continue
 		}
-		if err := c.ipts[idx].Delete(table, chain, ruleSpec...); err != nil {
+		if err := ipt.Delete(table, chain, ruleSpec...); err != nil {
 			return fmt.Errorf("error deleting rule %v from table %s chain %s: %v", ruleSpec, table, chain, err)
 		}
-		klog.V(2).Infof("Deleted rule %v from table %s chain %s", ruleSpec, table, chain)
+		klog.V(2).InfoS("Deleted a rule", "rule", ruleSpec, "table", table, "chain", chain, "protocol", p)
 	}
 	return nil
 }
 
-// DeleteChain deletes all rules from a chain in a table and then delete the chain
-func (c *Client) DeleteChain(table string, chain string) error {
-	for idx := range c.ipts {
-		err := c.ipts[idx].ClearChain(table, chain)
+// DeleteChain deletes all rules from a chain in a table and then delete the chain.
+func (c *Client) DeleteChain(protocol Protocol, table string, chain string) error {
+	for p := range c.ipts {
+		ipt := c.ipts[p]
+		if !matchProtocol(ipt, protocol) {
+			continue
+		}
+		exists, err := ipt.ChainExists(table, chain)
 		if err != nil {
+			return fmt.Errorf("error checking if chain %s exists in table %s: %v", chain, table, err)
+		}
+		if !exists {
+			continue
+		}
+		if err = ipt.ClearChain(table, chain); err != nil {
 			return fmt.Errorf("error clearing rules from table %s chain %s: %v", table, chain, err)
 		}
-		err = c.ipts[idx].DeleteChain(table, chain)
-		if err != nil {
+		if err = ipt.DeleteChain(table, chain); err != nil {
 			return fmt.Errorf("error deleting chain %s from table %s: %v", chain, table, err)
 		}
-		klog.V(2).Infof("Deleted chain %s from table %s", chain, table)
+		klog.V(2).InfoS("Deleted a chain", "chain", chain, "table", table, "protocol", p)
 	}
 	return nil
 }
 
-// ListRules lists all rules from a chain in a table
+// ListRules lists all rules from a chain in a table.
 func (c *Client) ListRules(table string, chain string) ([]string, error) {
 	var allRules []string
-	for idx := range c.ipts {
-		rules, err := c.ipts[idx].List(table, chain)
+	for p := range c.ipts {
+		rules, err := c.ipts[p].List(table, chain)
 		if err != nil {
-			return rules, fmt.Errorf("error getting rules from table %s chain %s: %v", table, chain, err)
+			return rules, fmt.Errorf("error getting rules from table %s chain %s protocol %s: %v", table, chain, p, err)
 		}
 		allRules = append(allRules, rules...)
 	}
@@ -265,7 +298,7 @@ func (c *Client) Restore(data []byte, flush bool, useIPv6 bool) error {
 		defer unlockFunc()
 	}
 	if err := cmd.Run(); err != nil {
-		klog.Errorf("Failed to execute %s: %v\nstdin:\n%s\nstderr:\n%s", iptablesCmd, err, data, stderr)
+		klog.ErrorS(err, "Failed to execute iptables command", "iptablesCmd", iptablesCmd, "stdin", data, "stderr", stderr)
 		return fmt.Errorf("error executing %s: %v", iptablesCmd, err)
 	}
 	return nil
@@ -274,9 +307,9 @@ func (c *Client) Restore(data []byte, flush bool, useIPv6 bool) error {
 // Save calls iptables-saves to dump chains and tables in iptables.
 func (c *Client) Save() ([]byte, error) {
 	var output []byte
-	for idx := range c.ipts {
+	for p := range c.ipts {
 		var cmd string
-		ipt := c.ipts[idx]
+		ipt := c.ipts[p]
 		switch ipt.Proto() {
 		case iptables.ProtocolIPv6:
 			cmd = "ip6tables-save"
diff --git a/pkg/agent/util/net.go b/pkg/agent/util/net.go
index 9fcd7fabc..1609e1d0f 100644
--- a/pkg/agent/util/net.go
+++ b/pkg/agent/util/net.go
@@ -160,12 +160,11 @@ func GetIPWithFamily(ips []net.IP, addrFamily uint8) (net.IP, error) {
 			}
 		}
 		return nil, errors.New("no IP found with IPv6 AddressFamily")
-	} else {
-		for _, ip := range ips {
-			if ip.To4() != nil {
-				return ip, nil
-			}
+	}
+	for _, ip := range ips {
+		if ip.To4() != nil {
+			return ip, nil
 		}
-		return nil, errors.New("no IP found with IPv4 AddressFamily")
 	}
+	return nil, errors.New("no IP found with IPv4 AddressFamily")
 }
diff --git a/pkg/agent/util/net_linux.go b/pkg/agent/util/net_linux.go
index 54f5d7361..7b6782383 100644
--- a/pkg/agent/util/net_linux.go
+++ b/pkg/agent/util/net_linux.go
@@ -116,9 +116,8 @@ func SetLinkUp(name string) (net.HardwareAddr, int, error) {
 	if err != nil {
 		if _, ok := err.(netlink.LinkNotFoundError); ok {
 			return nil, 0, newLinkNotFoundError(name)
-		} else {
-			return nil, 0, err
 		}
+		return nil, 0, err
 	}
 	// Set host gateway interface up.
 	if err := netlink.LinkSetUp(link); err != nil {
diff --git a/pkg/antctl/raw/supportbundle/command.go b/pkg/antctl/raw/supportbundle/command.go
index 5a9ade8fb..8bf2b007d 100644
--- a/pkg/antctl/raw/supportbundle/command.go
+++ b/pkg/antctl/raw/supportbundle/command.go
@@ -513,16 +513,16 @@ func controllerRemoteRunE(cmd *cobra.Command, args []string) error {
 	bar := barTmpl.Start(amount)
 	defer bar.Finish()
 	defer bar.Set("prefix", "Finish ")
-	if reader, err := getClusterInfo(k8sClientset); err != nil {
+	reader, err := getClusterInfo(k8sClientset)
+	if err != nil {
+		return err
+	}
+	f, err := os.Create(filepath.Join(option.dir, "clusterinfo"))
+	if err != nil {
 		return err
-	} else {
-		f, err := os.Create(filepath.Join(option.dir, "clusterinfo"))
-		if err != nil {
-			return err
-		}
-		defer f.Close()
-		io.Copy(f, reader)
 	}
+	defer f.Close()
+	io.Copy(f, reader)
 	if err := requestAll(agentClients, controllerClient, bar); err != nil {
 		return err
 	}
diff --git a/pkg/antctl/runtime/runtime.go b/pkg/antctl/runtime/runtime.go
index 7c4f88c7a..9531f9191 100644
--- a/pkg/antctl/runtime/runtime.go
+++ b/pkg/antctl/runtime/runtime.go
@@ -44,9 +44,8 @@ func ResolveKubeconfig(path string) (*rest.Config, error) {
 	}
 	if _, err = os.Stat(path); path == clientcmd.RecommendedHomeFile && os.IsNotExist(err) {
 		return rest.InClusterConfig()
-	} else {
-		return clientcmd.BuildConfigFromFlags("", path)
 	}
+	return clientcmd.BuildConfigFromFlags("", path)
 }
 
 func init() {
diff --git a/pkg/apis/controlplane/helper.go b/pkg/apis/controlplane/helper.go
index 7f73cbd05..d229dbe4e 100644
--- a/pkg/apis/controlplane/helper.go
+++ b/pkg/apis/controlplane/helper.go
@@ -19,7 +19,6 @@ import "fmt"
 func (r *NetworkPolicyReference) ToString() string {
 	if r.Type == AntreaClusterNetworkPolicy {
 		return fmt.Sprintf("%s:%s", r.Type, r.Name)
-	} else {
-		return fmt.Sprintf("%s:%s/%s", r.Type, r.Namespace, r.Name)
 	}
+	return fmt.Sprintf("%s:%s/%s", r.Type, r.Namespace, r.Name)
 }
diff --git a/pkg/apis/controlplane/v1beta1/helper.go b/pkg/apis/controlplane/v1beta1/helper.go
index 7d7b18fb6..3f3f0b536 100644
--- a/pkg/apis/controlplane/v1beta1/helper.go
+++ b/pkg/apis/controlplane/v1beta1/helper.go
@@ -37,7 +37,6 @@ func (p *GroupMemberPod) ToGroupMember() *GroupMember {
 func (r *NetworkPolicyReference) ToString() string {
 	if r.Type == AntreaClusterNetworkPolicy {
 		return fmt.Sprintf("%s:%s", r.Type, r.Name)
-	} else {
-		return fmt.Sprintf("%s:%s/%s", r.Type, r.Namespace, r.Name)
 	}
+	return fmt.Sprintf("%s:%s/%s", r.Type, r.Namespace, r.Name)
 }
diff --git a/pkg/apis/controlplane/v1beta2/helper.go b/pkg/apis/controlplane/v1beta2/helper.go
index f6a88933e..2fd9bd157 100644
--- a/pkg/apis/controlplane/v1beta2/helper.go
+++ b/pkg/apis/controlplane/v1beta2/helper.go
@@ -19,7 +19,6 @@ import "fmt"
 func (r *NetworkPolicyReference) ToString() string {
 	if r.Type == AntreaClusterNetworkPolicy {
 		return fmt.Sprintf("%s:%s", r.Type, r.Name)
-	} else {
-		return fmt.Sprintf("%s:%s/%s", r.Type, r.Namespace, r.Name)
 	}
+	return fmt.Sprintf("%s:%s/%s", r.Type, r.Namespace, r.Name)
 }
diff --git a/pkg/apiserver/handlers/featuregates/handler.go b/pkg/apiserver/handlers/featuregates/handler.go
index 34b3335cb..4f491d01b 100644
--- a/pkg/apiserver/handlers/featuregates/handler.go
+++ b/pkg/apiserver/handlers/featuregates/handler.go
@@ -123,7 +123,6 @@ func getControllerGatesResponse() []Response {
 func getStatus(status bool) string {
 	if status {
 		return "Enabled"
-	} else {
-		return "Disabled"
 	}
+	return "Disabled"
 }
diff --git a/pkg/controller/crdmirroring/crdmirroring_controller.go b/pkg/controller/crdmirroring/crdmirroring_controller.go
index 3109fafd2..64fa0f1cc 100644
--- a/pkg/controller/crdmirroring/crdmirroring_controller.go
+++ b/pkg/controller/crdmirroring/crdmirroring_controller.go
@@ -138,9 +138,8 @@ func (c *Controller) syncMirroring(key string) error {
 	if err != nil {
 		if !apierrors.IsNotFound(err) {
 			return fmt.Errorf("failed to get legacy %s %s/%s: %v", c.crdName, namespace, name, err)
-		} else {
-			legacyExist = false
 		}
+		legacyExist = false
 	}
 
 	// Get the new object, and if got an error that is not "IsNotFound", return the error
@@ -149,9 +148,8 @@ func (c *Controller) syncMirroring(key string) error {
 	if err != nil {
 		if !apierrors.IsNotFound(err) {
 			return fmt.Errorf("failed to get new %s %s/%s: %v", c.crdName, namespace, name, err)
-		} else {
-			newExist = false
 		}
+		newExist = false
 	}
 
 	// If neither the old object nor the new object exists, return
diff --git a/pkg/controller/networkpolicy/status_controller.go b/pkg/controller/networkpolicy/status_controller.go
index 4df998fd0..380e220f2 100644
--- a/pkg/controller/networkpolicy/status_controller.go
+++ b/pkg/controller/networkpolicy/status_controller.go
@@ -275,9 +275,8 @@ func (c *StatusController) syncHandler(key string) error {
 		}
 		if internalNP.SourceRef.Type == controlplane.AntreaNetworkPolicy {
 			return c.npControlInterface.UpdateAntreaNetworkPolicyStatus(internalNP.SourceRef.Namespace, internalNP.SourceRef.Name, status)
-		} else {
-			return c.npControlInterface.UpdateAntreaClusterNetworkPolicyStatus(internalNP.SourceRef.Name, status)
 		}
+		return c.npControlInterface.UpdateAntreaClusterNetworkPolicyStatus(internalNP.SourceRef.Name, status)
 	}
 	desiredNodes := len(internalNP.SpanMeta.NodeNames)
 	currentNodes := 0
@@ -307,9 +306,8 @@ func (c *StatusController) syncHandler(key string) error {
 	klog.V(2).Infof("Updating NetworkPolicy %s status: %v", internalNP.SourceRef.ToString(), status)
 	if internalNP.SourceRef.Type == controlplane.AntreaNetworkPolicy {
 		return c.npControlInterface.UpdateAntreaNetworkPolicyStatus(internalNP.SourceRef.Namespace, internalNP.SourceRef.Name, status)
-	} else {
-		return c.npControlInterface.UpdateAntreaClusterNetworkPolicyStatus(internalNP.SourceRef.Name, status)
 	}
+	return c.npControlInterface.UpdateAntreaClusterNetworkPolicyStatus(internalNP.SourceRef.Name, status)
 }
 
 // networkPolicyControlInterface is an interface that knows how to update Antrea NetworkPolicy status.
diff --git a/pkg/controller/traceflow/controller.go b/pkg/controller/traceflow/controller.go
index e949021e5..dc66a9928 100644
--- a/pkg/controller/traceflow/controller.go
+++ b/pkg/controller/traceflow/controller.go
@@ -219,21 +219,21 @@ func (c *Controller) processTraceflowItem() bool {
 	defer c.queue.Done(obj)
 
 	// We expect strings (Traceflow name) to come off the workqueue.
-	if key, ok := obj.(string); !ok {
+	key, ok := obj.(string)
+	if !ok {
 		// As the item in the workqueue is actually invalid, we call Forget here else we'd
 		// go into a loop of attempting to process a work item that is invalid.
 		// This should not happen: enqueueTraceflow only enqueues strings.
 		c.queue.Forget(obj)
 		klog.Errorf("Expected string in work queue but got %#v", obj)
 		return true
+	}
+	err := c.syncTraceflow(key)
+	if err != nil {
+		klog.Errorf("Error syncing Traceflow %s, exiting. Error: %v", key, err)
+		c.queue.AddRateLimited(key)
 	} else {
-		err := c.syncTraceflow(key)
-		if err != nil {
-			klog.Errorf("Error syncing Traceflow %s, exiting. Error: %v", key, err)
-			c.queue.AddRateLimited(key)
-		} else {
-			c.queue.Forget(key)
-		}
+		c.queue.Forget(key)
 	}
 	return true
 }
@@ -364,9 +364,8 @@ func (c *Controller) occupyTag(tf *crdv1alpha1.Traceflow) error {
 	if existingTraceflowName, ok := c.runningTraceflows[tag]; ok {
 		if tf.Name == existingTraceflowName {
 			return nil
-		} else {
-			return errors.New("this Traceflow's CRD data plane tag is already taken")
 		}
+		return errors.New("this Traceflow's CRD data plane tag is already taken")
 	}
 
 	c.runningTraceflows[tag] = tf.Name
diff --git a/pkg/flowaggregator/flowaggregator.go b/pkg/flowaggregator/flowaggregator.go
index 0e0cd5f51..e169776a1 100644
--- a/pkg/flowaggregator/flowaggregator.go
+++ b/pkg/flowaggregator/flowaggregator.go
@@ -298,21 +298,26 @@ func (fa *flowAggregator) InitAggregationProcess() error {
 	return err
 }
 
-func (fa *flowAggregator) createAndSendTemplate(isRecordIPv6 bool) (uint16, error) {
+func (fa *flowAggregator) createAndSendTemplate(isRecordIPv6 bool) error {
 	templateID := fa.exportingProcess.NewTemplateID()
 	recordIPFamily := "IPv4"
 	if isRecordIPv6 {
 		recordIPFamily = "IPv6"
 	}
+	if isRecordIPv6 {
+		fa.templateIDv6 = templateID
+	} else {
+		fa.templateIDv4 = templateID
+	}
 	bytesSent, err := fa.sendTemplateSet(isRecordIPv6)
 	if err != nil {
 		fa.exportingProcess.CloseConnToCollector()
 		fa.exportingProcess = nil
 		fa.set.ResetSet()
-		return 0, fmt.Errorf("sending %s template set failed, err: %v", recordIPFamily, err)
+		return fmt.Errorf("sending %s template set failed, err: %v", recordIPFamily, err)
 	}
 	klog.V(2).InfoS("Exporting process initialized", "bytesSent", bytesSent, "templateSetIPFamily", recordIPFamily)
-	return templateID, nil
+	return nil
 }
 
 func (fa *flowAggregator) initExportingProcess() error {
@@ -346,10 +351,10 @@ func (fa *flowAggregator) initExportingProcess() error {
 	}
 	fa.exportingProcess = ep
 	// Currently, we send two templates for IPv4 and IPv6 regardless of the IP families supported by cluster
-	if fa.templateIDv4, err = fa.createAndSendTemplate(false); err != nil {
+	if err = fa.createAndSendTemplate(false); err != nil {
 		return err
 	}
-	if fa.templateIDv6, err = fa.createAndSendTemplate(true); err != nil {
+	if err = fa.createAndSendTemplate(true); err != nil {
 		return err
 	}
 	return nil
diff --git a/pkg/graphviz/traceflow.go b/pkg/graphviz/traceflow.go
index 8bfb6373c..9136d165e 100644
--- a/pkg/graphviz/traceflow.go
+++ b/pkg/graphviz/traceflow.go
@@ -153,9 +153,8 @@ func getSrcNodeName(tf *crdv1alpha1.Traceflow) string {
 	if tf.Spec.LiveTraffic {
 		if len(tf.Spec.Source.IP) > 0 {
 			return getWrappedStr(tf.Spec.Source.IP)
-		} else {
-			return getWrappedStr(tf.Status.CapturedPacket.SrcIP)
 		}
+		return getWrappedStr(tf.Status.CapturedPacket.SrcIP)
 	}
 	return ""
 }
diff --git a/pkg/ovs/ovsconfig/ovs_client.go b/pkg/ovs/ovsconfig/ovs_client.go
index 479fcc16a..8659cd807 100644
--- a/pkg/ovs/ovsconfig/ovs_client.go
+++ b/pkg/ovs/ovsconfig/ovs_client.go
@@ -625,9 +625,9 @@ func buildMapFromOVSDBMap(data []interface{}) map[string]string {
 			ret[pair.([]interface{})[0].(string)] = pair.([]interface{})[1].(string)
 		}
 		return ret
-	} else { // Should not be possible
-		return map[string]string{}
 	}
+	// Should not be possible
+	return map[string]string{}
 }
 
 func buildPortDataCommon(port, intf map[string]interface{}, portData *OVSPortData) {
@@ -768,9 +768,8 @@ func (br *OVSBridge) GetOVSVersion() (string, Error) {
 	if len(res[0].Rows) == 0 {
 		klog.Warning("Could not find ovs_version in the OVS query result")
 		return "", NewTransactionError(fmt.Errorf("no results from OVS query"), false)
-	} else {
-		return parseOvsVersion(res[0].Rows[0])
 	}
+	return parseOvsVersion(res[0].Rows[0])
 }
 
 // parseOvsVersion parses the version from an interface type, which can be a map of string[interface] or string[string], and returns it as a string, we have special logic here so that a panic doesn't happen.
diff --git a/pkg/ovs/ovsctl/appctl.go b/pkg/ovs/ovsctl/appctl.go
index 36014bc2b..024e6c47f 100644
--- a/pkg/ovs/ovsctl/appctl.go
+++ b/pkg/ovs/ovsctl/appctl.go
@@ -80,9 +80,8 @@ func (c *ovsCtlClient) Trace(req *TracingRequest) (string, error) {
 		ipKey, nwSrcKey = getNwSrcKey(req.SrcIP)
 		if strings.Contains(req.Flow, fmt.Sprintf("%s=", nwSrcKey)) {
 			return "", newBadRequestError(fmt.Sprintf("duplicated '%s' in flow", nwSrcKey))
-		} else {
-			nwSrc = fmt.Sprintf("%s=%s,", nwSrcKey, req.SrcIP.String())
 		}
+		nwSrc = fmt.Sprintf("%s=%s,", nwSrcKey, req.SrcIP.String())
 	}
 	if req.DstIP != nil {
 		var nwDstKey string
@@ -90,9 +89,8 @@ func (c *ovsCtlClient) Trace(req *TracingRequest) (string, error) {
 		// Do not allow overriding destination IP.
 		if strings.Contains(req.Flow, fmt.Sprintf("%s=", nwDstKey)) {
 			return "", newBadRequestError(fmt.Sprintf("duplicated '%s' in flow", nwDstKey))
-		} else {
-			nwDst = fmt.Sprintf("%s=%s,", nwDstKey, req.DstIP.String())
 		}
+		nwDst = fmt.Sprintf("%s=%s,", nwDstKey, req.DstIP.String())
 	}
 
 	// Always allow overriding source and destination MACs.
@@ -128,17 +126,15 @@ func (c *ovsCtlClient) Trace(req *TracingRequest) (string, error) {
 func getNwSrcKey(ip net.IP) (string, string) {
 	if ip.To4() != nil {
 		return "ip", "nw_src"
-	} else {
-		return "ipv6", "ipv6_src"
 	}
+	return "ipv6", "ipv6_src"
 }
 
 func getNwDstKey(ip net.IP) (string, string) {
 	if ip.To4() != nil {
 		return "ip", "nw_dst"
-	} else {
-		return "ipv6", "ipv6_dst"
 	}
+	return "ipv6", "ipv6_dst"
 }
 
 func (c *ovsCtlClient) runTracing(flow string) (string, error) {


Test patch:
diff --git a/pkg/agent/controller/egress/egress_controller_test.go b/pkg/agent/controller/egress/egress_controller_test.go
index 95502c359..31e54b7cf 100644
--- a/pkg/agent/controller/egress/egress_controller_test.go
+++ b/pkg/agent/controller/egress/egress_controller_test.go
@@ -16,6 +16,7 @@ package egress
 
 import (
 	"context"
+	"fmt"
 	"net"
 	"reflect"
 	"testing"
@@ -24,10 +25,12 @@ import (
 	"github.com/golang/mock/gomock"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/apimachinery/pkg/util/wait"
+	k8stesting "k8s.io/client-go/testing"
 	"k8s.io/client-go/util/workqueue"
 
 	ipassignertest "antrea.io/antrea/pkg/agent/controller/egress/ipassigner/testing"
@@ -38,7 +41,6 @@ import (
 	cpv1b2 "antrea.io/antrea/pkg/apis/controlplane/v1beta2"
 	crdv1a2 "antrea.io/antrea/pkg/apis/crd/v1alpha2"
 	"antrea.io/antrea/pkg/client/clientset/versioned"
-	"antrea.io/antrea/pkg/client/clientset/versioned/fake"
 	fakeversioned "antrea.io/antrea/pkg/client/clientset/versioned/fake"
 	crdinformers "antrea.io/antrea/pkg/client/informers/externalversions"
 	"antrea.io/antrea/pkg/util/k8s"
@@ -98,7 +100,7 @@ func newFakeController(t *testing.T, initObjects []runtime.Object) *fakeControll
 	mockRouteClient := routetest.NewMockInterface(controller)
 	mockIPAssigner := ipassignertest.NewMockIPAssigner(controller)
 
-	clientset := &fake.Clientset{}
+	clientset := &fakeversioned.Clientset{}
 	crdClient := fakeversioned.NewSimpleClientset(initObjects...)
 	crdInformerFactory := crdinformers.NewSharedInformerFactory(crdClient, 0)
 	egressInformer := crdInformerFactory.Crd().V1alpha2().Egresses()
@@ -114,6 +116,7 @@ func newFakeController(t *testing.T, initObjects []runtime.Object) *fakeControll
 	egressController := &EgressController{
 		ofClient:             mockOFClient,
 		routeClient:          mockRouteClient,
+		crdClient:            crdClient,
 		antreaClientProvider: &antreaClientGetter{clientset},
 		egressInformer:       egressInformer.Informer(),
 		egressLister:         egressInformer.Lister(),
@@ -148,6 +151,7 @@ func TestSyncEgress(t *testing.T) {
 		existingEgressGroup *cpv1b2.EgressGroup
 		newEgressGroup      *cpv1b2.EgressGroup
 		newLocalIPs         sets.String
+		expectedEgresses    []*crdv1a2.Egress
 		expectedCalls       func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner)
 	}{
 		{
@@ -175,6 +179,12 @@ func TestSyncEgress(t *testing.T) {
 				},
 			},
 			newLocalIPs: sets.NewString(),
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP1},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallSNATMarkFlows(net.ParseIP(fakeLocalEgressIP1), uint32(1))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeLocalEgressIP1), uint32(1))
@@ -218,6 +228,13 @@ func TestSyncEgress(t *testing.T) {
 				},
 			},
 			newLocalIPs: sets.NewString(fakeRemoteEgressIP1),
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeRemoteEgressIP1},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeRemoteEgressIP1), uint32(0))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(2), net.ParseIP(fakeRemoteEgressIP1), uint32(0))
@@ -258,6 +275,13 @@ func TestSyncEgress(t *testing.T) {
 					{Pod: &cpv1b2.PodReference{Name: "pod3", Namespace: "ns3"}},
 				},
 			},
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP2},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallSNATMarkFlows(net.ParseIP(fakeLocalEgressIP1), uint32(1))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeLocalEgressIP1), uint32(1))
@@ -303,6 +327,12 @@ func TestSyncEgress(t *testing.T) {
 					{Pod: &cpv1b2.PodReference{Name: "pod3", Namespace: "ns3"}},
 				},
 			},
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeRemoteEgressIP1},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallSNATMarkFlows(net.ParseIP(fakeLocalEgressIP1), uint32(1))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeLocalEgressIP1), uint32(1))
@@ -346,6 +376,13 @@ func TestSyncEgress(t *testing.T) {
 					{Pod: &cpv1b2.PodReference{Name: "pod3", Namespace: "ns3"}},
 				},
 			},
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP1},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeRemoteEgressIP1), uint32(0))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(2), net.ParseIP(fakeRemoteEgressIP1), uint32(0))
@@ -387,6 +424,18 @@ func TestSyncEgress(t *testing.T) {
 					{Pod: &cpv1b2.PodReference{Name: "pod3", Namespace: "ns3"}},
 				},
 			},
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP1},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressB", UID: "uidB"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP2},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallSNATMarkFlows(net.ParseIP(fakeLocalEgressIP1), uint32(1))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeLocalEgressIP1), uint32(1))
@@ -426,6 +475,18 @@ func TestSyncEgress(t *testing.T) {
 					{Pod: &cpv1b2.PodReference{Name: "pod3", Namespace: "ns3"}},
 				},
 			},
+			expectedEgresses: []*crdv1a2.Egress{
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP1},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+				{
+					ObjectMeta: metav1.ObjectMeta{Name: "egressB", UID: "uidB"},
+					Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP1},
+					Status:     crdv1a2.EgressStatus{EgressNode: fakeNode},
+				},
+			},
 			expectedCalls: func(mockOFClient *openflowtest.MockClient, mockRouteClient *routetest.MockInterface, mockIPAssigner *ipassignertest.MockIPAssigner) {
 				mockOFClient.EXPECT().InstallSNATMarkFlows(net.ParseIP(fakeLocalEgressIP1), uint32(1))
 				mockOFClient.EXPECT().InstallPodSNATFlows(uint32(1), net.ParseIP(fakeLocalEgressIP1), uint32(1))
@@ -470,6 +531,11 @@ func TestSyncEgress(t *testing.T) {
 			// Call it one more time to ensure it's idempotent, no extra datapath calls are supposed to be made.
 			err = c.syncEgress(tt.newEgress.Name)
 			assert.NoError(t, err)
+			for _, expectedEgress := range tt.expectedEgresses {
+				gotEgress, err := c.crdClient.CrdV1alpha2().Egresses().Get(context.TODO(), expectedEgress.Name, metav1.GetOptions{})
+				require.NoError(t, err)
+				assert.Equal(t, expectedEgress, gotEgress)
+			}
 		})
 	}
 }
@@ -624,3 +690,90 @@ func addPodInterface(ifaceStore interfacestore.InterfaceStore, podNamespace, pod
 		OVSPortConfig:            &interfacestore.OVSPortConfig{OFPort: ofPort},
 	})
 }
+
+func TestUpdateEgressStatus(t *testing.T) {
+	getError := fmt.Errorf("fake get Egress error")
+	updateConflictError := &errors.StatusError{ErrStatus: metav1.Status{Reason: metav1.StatusReasonConflict, Message: "update Egress conflict"}}
+	updateError := fmt.Errorf("update Egress error")
+	tests := []struct {
+		name                 string
+		updateErrorNum       int
+		updateError          error
+		getErrorNum          int
+		expectedUpdateCalled int
+		expectedGetCalled    int
+		expectedError        error
+	}{
+		{
+			name:                 "succeed immediately",
+			updateErrorNum:       0,
+			updateError:          nil,
+			getErrorNum:          0,
+			expectedUpdateCalled: 1,
+			expectedGetCalled:    0,
+			expectedError:        nil,
+		},
+		{
+			name:                 "succeed after one update conflict failure",
+			updateErrorNum:       1,
+			updateError:          updateConflictError,
+			getErrorNum:          0,
+			expectedUpdateCalled: 2,
+			expectedGetCalled:    1,
+			expectedError:        nil,
+		},
+		{
+			name:                 "fail after one update failure",
+			updateErrorNum:       1,
+			updateError:          updateError,
+			getErrorNum:          0,
+			expectedUpdateCalled: 1,
+			expectedGetCalled:    0,
+			expectedError:        updateError,
+		},
+		{
+			name:                 "fail after one update conflict failure and one get failure",
+			updateErrorNum:       1,
+			updateError:          updateConflictError,
+			getErrorNum:          1,
+			expectedUpdateCalled: 1,
+			expectedGetCalled:    1,
+			expectedError:        getError,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			egress := crdv1a2.Egress{
+				ObjectMeta: metav1.ObjectMeta{Name: "egressA", UID: "uidA", ResourceVersion: "fake-ResourceVersion"},
+				Spec:       crdv1a2.EgressSpec{EgressIP: fakeLocalEgressIP1},
+			}
+			fakeClient := &fakeversioned.Clientset{}
+			getCalled := 0
+			fakeClient.AddReactor("get", "egresses", func(action k8stesting.Action) (bool, runtime.Object, error) {
+				getCalled += 1
+				if getCalled <= tt.getErrorNum {
+					return true, nil, getError
+				}
+				return true, &egress, nil
+			})
+			updateCalled := 0
+			fakeClient.AddReactor("update", "*", func(action k8stesting.Action) (bool, runtime.Object, error) {
+				updateCalled += 1
+				if updateCalled <= tt.updateErrorNum {
+					return true, nil, tt.updateError
+				}
+				return true, &egress, nil
+			})
+
+			c := &EgressController{crdClient: fakeClient, nodeName: fakeNode}
+			_, err := c.crdClient.CrdV1alpha2().Egresses().Create(context.TODO(), &egress, metav1.CreateOptions{})
+			assert.NoError(t, err)
+			err = c.updateEgressStatus(&egress, true)
+			if err != tt.expectedError {
+				t.Errorf("Update Egress error not match, got: %v, expected: %v", err, tt.expectedError)
+			}
+			assert.Equal(t, tt.expectedGetCalled, getCalled, "Get called num not match")
+			assert.Equal(t, tt.expectedUpdateCalled, updateCalled, "Update called num not match")
+		})
+	}
+}
diff --git a/pkg/agent/flowexporter/connections/connections_test.go b/pkg/agent/flowexporter/connections/connections_test.go
index 0c9417f9e..de21af157 100644
--- a/pkg/agent/flowexporter/connections/connections_test.go
+++ b/pkg/agent/flowexporter/connections/connections_test.go
@@ -26,7 +26,10 @@ import (
 	interfacestoretest "antrea.io/antrea/pkg/agent/interfacestore/testing"
 )
 
-const testPollInterval = 0 // Not used in these tests, hence 0.
+const (
+	testPollInterval           = 0 // Not used in these tests, hence 0.
+	testStaleConnectionTimeout = 5 * time.Minute
+)
 
 func TestConnectionStore_ForAllConnectionsDo(t *testing.T) {
 	ctrl := gomock.NewController(t)
@@ -65,7 +68,7 @@ func TestConnectionStore_ForAllConnectionsDo(t *testing.T) {
 	}
 	// Create connectionStore
 	mockIfaceStore := interfacestoretest.NewMockInterfaceStore(ctrl)
-	connStore := NewConnectionStore(mockIfaceStore, nil)
+	connStore := NewConnectionStore(mockIfaceStore, nil, testStaleConnectionTimeout)
 	// Add flows to the Connection store
 	for i, flow := range testFlows {
 		connStore.connections[*testFlowKeys[i]] = flow
diff --git a/pkg/agent/flowexporter/connections/conntrack_connections_perf_test.go b/pkg/agent/flowexporter/connections/conntrack_connections_perf_test.go
index 0dc44c4ca..21b8c490a 100644
--- a/pkg/agent/flowexporter/connections/conntrack_connections_perf_test.go
+++ b/pkg/agent/flowexporter/connections/conntrack_connections_perf_test.go
@@ -105,7 +105,7 @@ func setupConntrackConnStore(b *testing.B) (*ConntrackConnectionStore, *connecti
 
 	npQuerier := queriertest.NewMockAgentNetworkPolicyInfoQuerier(ctrl)
 
-	return NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, mockProxier, npQuerier, testPollInterval), mockConnDumper
+	return NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, mockProxier, npQuerier, testPollInterval, testStaleConnectionTimeout), mockConnDumper
 }
 
 func generateConns() []*flowexporter.Connection {
diff --git a/pkg/agent/flowexporter/connections/conntrack_connections_test.go b/pkg/agent/flowexporter/connections/conntrack_connections_test.go
index d33998d82..5310e08fc 100644
--- a/pkg/agent/flowexporter/connections/conntrack_connections_test.go
+++ b/pkg/agent/flowexporter/connections/conntrack_connections_test.go
@@ -200,7 +200,7 @@ func TestConntrackConnectionStore_AddOrUpdateConn(t *testing.T) {
 	mockProxier := proxytest.NewMockProxier(ctrl)
 	mockConnDumper := connectionstest.NewMockConnTrackDumper(ctrl)
 	npQuerier := queriertest.NewMockAgentNetworkPolicyInfoQuerier(ctrl)
-	conntrackConnStore := NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, mockProxier, npQuerier, testPollInterval)
+	conntrackConnStore := NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, mockProxier, npQuerier, testPollInterval, testStaleConnectionTimeout)
 
 	// Add flow1conn and flow3conn to the Connection map
 	testFlow1Tuple := flowexporter.NewConnectionKey(&testFlow1)
@@ -320,7 +320,7 @@ func TestConnectionStore_DeleteConnectionByKey(t *testing.T) {
 	metrics.TotalAntreaConnectionsInConnTrackTable.Set(float64(len(testFlows)))
 	// Create connectionStore
 	mockIfaceStore := interfacestoretest.NewMockInterfaceStore(ctrl)
-	connStore := NewConntrackConnectionStore(nil, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, nil, nil, testPollInterval)
+	connStore := NewConntrackConnectionStore(nil, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, nil, nil, testPollInterval, testStaleConnectionTimeout)
 	// Add flows to the connection store.
 	for i, flow := range testFlows {
 		connStore.connections[*testFlowKeys[i]] = flow
@@ -344,7 +344,7 @@ func TestConnectionStore_MetricSettingInPoll(t *testing.T) {
 	// Create connectionStore
 	mockIfaceStore := interfacestoretest.NewMockInterfaceStore(ctrl)
 	mockConnDumper := connectionstest.NewMockConnTrackDumper(ctrl)
-	conntrackConnStore := NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, nil, nil, testPollInterval)
+	conntrackConnStore := NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), mockIfaceStore, true, false, nil, nil, testPollInterval, testStaleConnectionTimeout)
 	// Hard-coded conntrack occupancy metrics for test
 	TotalConnections := 0
 	MaxConnections := 300000
diff --git a/pkg/agent/flowexporter/connections/deny_connections_test.go b/pkg/agent/flowexporter/connections/deny_connections_test.go
index 8ab76f187..4492b5dca 100644
--- a/pkg/agent/flowexporter/connections/deny_connections_test.go
+++ b/pkg/agent/flowexporter/connections/deny_connections_test.go
@@ -71,7 +71,7 @@ func TestDenyConnectionStore_AddOrUpdateConn(t *testing.T) {
 	mockIfaceStore.EXPECT().GetInterfaceByIP(tuple.SourceAddress.String()).Return(nil, false)
 	mockIfaceStore.EXPECT().GetInterfaceByIP(tuple.DestinationAddress.String()).Return(nil, false)
 
-	denyConnStore := NewDenyConnectionStore(mockIfaceStore, mockProxier)
+	denyConnStore := NewDenyConnectionStore(mockIfaceStore, mockProxier, testStaleConnectionTimeout)
 
 	denyConnStore.AddOrUpdateConn(&testFlow, refTime.Add(-(time.Second * 20)), uint64(60))
 	expConn := testFlow
@@ -99,7 +99,7 @@ func TestDenyConnectionStore_DeleteConnWithoutLock(t *testing.T) {
 	metrics.InitializeConnectionMetrics()
 	// Create denyConnectionStore
 	mockIfaceStore := interfacestoretest.NewMockInterfaceStore(ctrl)
-	connStore := NewDenyConnectionStore(mockIfaceStore, nil)
+	connStore := NewDenyConnectionStore(mockIfaceStore, nil, testStaleConnectionTimeout)
 	refTime := time.Now()
 	tuple1 := flowexporter.Tuple{SourceAddress: net.IP{1, 2, 3, 4}, DestinationAddress: net.IP{4, 3, 2, 1}, Protocol: 6, SourcePort: 65280, DestinationPort: 255}
 	tuple2 := flowexporter.Tuple{SourceAddress: net.IP{1, 2, 3, 4}, DestinationAddress: net.IP{8, 7, 6, 5}, Protocol: 6, SourcePort: 65280, DestinationPort: 255}
diff --git a/pkg/agent/flowexporter/exporter/exporter_perf_test.go b/pkg/agent/flowexporter/exporter/exporter_perf_test.go
index db967c703..f6b0b70d1 100644
--- a/pkg/agent/flowexporter/exporter/exporter_perf_test.go
+++ b/pkg/agent/flowexporter/exporter/exporter_perf_test.go
@@ -128,6 +128,44 @@ func BenchmarkExportDenyConns(b *testing.B) {
 
 }
 
+/*
+go test -test.v -run=None -test.benchmem -bench=BenchmarkGetRecordAndDeleteFromMap -memprofile memprofile.out -cpuprofile profile.out
+goos: linux
+goarch: amd64
+pkg: antrea.io/antrea/pkg/agent/flowexporter/exporter
+cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
+BenchmarkGetRecordAndDeleteFromMap
+    exporter_perf_test.go:150:
+        Summary:
+        Number of conntrack connections: 100000
+         Number of dying conntrack connections: 5000
+BenchmarkGetRecordAndDeleteFromMap-2   	168049232	         6.737 ns/op	       0 B/op	       0 allocs/op
+PASS
+ok  	antrea.io/antrea/pkg/agent/flowexporter/exporter	8.707s
+Reference value:
+	#conns
+	20000   168049232	 6.737 ns/op	  0 B/op   0 allocs/op
+*/
+func BenchmarkGetRecordAndDeleteFromMap(b *testing.B) {
+	disableLogToStderr()
+	ctrl := gomock.NewController(b)
+	defer ctrl.Finish()
+
+	conntrackConnStore := connections.NewConntrackConnectionStore(nil, flowrecords.NewFlowRecords(), nil, true, false, nil, nil, 1, 1)
+	records := addConnsAndGetRecords(conntrackConnStore)
+	b.ResetTimer()
+	for n := 0; n < b.N; n++ {
+		getFlowRecordAndDelete := func(key flowexporter.ConnectionKey, record flowexporter.FlowRecord) error {
+			if _, exists := records.GetFlowRecordFromMap(&key); exists {
+				return records.DeleteFlowRecordFromMap(&key)
+			}
+			return nil
+		}
+		records.ForAllFlowRecordsDoWithoutLock(getFlowRecordAndDelete)
+	}
+	b.Logf("\nSummary:\nNumber of conntrack connections: %d\n Number of dying conntrack connections: %d\n", testNumOfConns, testNumOfDyingConns)
+}
+
 func setupExporter(isConntrackConn bool) (*flowExporter, error) {
 	var err error
 	collectorAddr, err := startLocalServer()
@@ -137,8 +175,8 @@ func setupExporter(isConntrackConn bool) (*flowExporter, error) {
 
 	// create connection store and generate connections
 	records := flowrecords.NewFlowRecords()
-	denyConnStore := connections.NewDenyConnectionStore(nil, nil)
-	conntrackConnStore := connections.NewConntrackConnectionStore(nil, flowrecords.NewFlowRecords(), nil, true, false, nil, nil, 1)
+	denyConnStore := connections.NewDenyConnectionStore(nil, nil, 0)
+	conntrackConnStore := connections.NewConntrackConnectionStore(nil, flowrecords.NewFlowRecords(), nil, true, false, nil, nil, 1, 1)
 	if isConntrackConn {
 		records = addConnsAndGetRecords(conntrackConnStore)
 	} else {
diff --git a/pkg/agent/flowexporter/exporter/exporter_test.go b/pkg/agent/flowexporter/exporter/exporter_test.go
index d5e795d21..174a4f170 100644
--- a/pkg/agent/flowexporter/exporter/exporter_test.go
+++ b/pkg/agent/flowexporter/exporter/exporter_test.go
@@ -377,7 +377,7 @@ func runSendFlowRecordTests(t *testing.T, flowExp *flowExporter, isIPv6 bool) {
 	flowExp.process = mockIPFIXExpProc
 	flowExp.ipfixSet = mockDataSet
 	mockConnDumper := connectionstest.NewMockConnTrackDumper(ctrl)
-	flowExp.conntrackConnStore = connections.NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), nil, !isIPv6, isIPv6, nil, nil, 1)
+	flowExp.conntrackConnStore = connections.NewConntrackConnectionStore(mockConnDumper, flowrecords.NewFlowRecords(), nil, !isIPv6, isIPv6, nil, nil, 1, 1)
 
 	tests := []struct {
 		name               string
@@ -457,7 +457,7 @@ func runSendFlowRecordTests(t *testing.T, flowExp *flowExporter, isIPv6 bool) {
 			flowExp.numDataSetsSent = 0
 
 			denyConn := getDenyConnection(isIPv6, tt.isDenyConnActive, tt.protoID)
-			flowExp.denyConnStore = connections.NewDenyConnectionStore(nil, nil)
+			flowExp.denyConnStore = connections.NewDenyConnectionStore(nil, nil, 0)
 			flowExp.denyConnStore.AddOrUpdateConn(denyConn, denyConn.LastExportTime, denyConn.DeltaBytes)
 			assert.Equal(t, getNumOfConnections(flowExp.denyConnStore), 1)
 
diff --git a/pkg/agent/nodeportlocal/npl_agent_test.go b/pkg/agent/nodeportlocal/npl_agent_test.go
index ea9aae035..2a77df15c 100644
--- a/pkg/agent/nodeportlocal/npl_agent_test.go
+++ b/pkg/agent/nodeportlocal/npl_agent_test.go
@@ -191,8 +191,8 @@ func setUp(t *testing.T, tc *testConfig, objects ...runtime.Object) *testData {
 	mockCtrl := gomock.NewController(t)
 
 	mockIPTables := rulestesting.NewMockPodPortRules(mockCtrl)
-	mockIPTables.EXPECT().AddRule(gomock.Any(), gomock.Any()).AnyTimes()
-	mockIPTables.EXPECT().DeleteRule(gomock.Any(), gomock.Any()).AnyTimes()
+	mockIPTables.EXPECT().AddRule(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
+	mockIPTables.EXPECT().DeleteRule(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
 	mockIPTables.EXPECT().AddAllRules(gomock.Any()).AnyTimes()
 
 	mockPortOpener := portcachetesting.NewMockLocalPortOpener(mockCtrl)
@@ -267,9 +267,8 @@ func (t *testData) pollForPodAnnotation(podName string, found bool) (string, err
 		data, exists = ann[nplk8s.NPLAnnotationKey]
 		if found {
 			return exists, nil
-		} else {
-			return !exists, nil
 		}
+		return !exists, nil
 	})
 
 	return data, err
diff --git a/pkg/agent/nodeportlocal/rules/testing/mock_rules.go b/pkg/agent/nodeportlocal/rules/testing/mock_rules.go
index b0ce5f010..da1d7a03e 100644
--- a/pkg/agent/nodeportlocal/rules/testing/mock_rules.go
+++ b/pkg/agent/nodeportlocal/rules/testing/mock_rules.go
@@ -63,17 +63,17 @@ func (mr *MockPodPortRulesMockRecorder) AddAllRules(arg0 interface{}) *gomock.Ca
 }
 
 // AddRule mocks base method
-func (m *MockPodPortRules) AddRule(arg0 int, arg1 string) error {
+func (m *MockPodPortRules) AddRule(arg0 int, arg1 string, arg2 int) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "AddRule", arg0, arg1)
+	ret := m.ctrl.Call(m, "AddRule", arg0, arg1, arg2)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // AddRule indicates an expected call of AddRule
-func (mr *MockPodPortRulesMockRecorder) AddRule(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockPodPortRulesMockRecorder) AddRule(arg0, arg1, arg2 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRule", reflect.TypeOf((*MockPodPortRules)(nil).AddRule), arg0, arg1)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRule", reflect.TypeOf((*MockPodPortRules)(nil).AddRule), arg0, arg1, arg2)
 }
 
 // DeleteAllRules mocks base method
@@ -91,17 +91,17 @@ func (mr *MockPodPortRulesMockRecorder) DeleteAllRules() *gomock.Call {
 }
 
 // DeleteRule mocks base method
-func (m *MockPodPortRules) DeleteRule(arg0 int, arg1 string) error {
+func (m *MockPodPortRules) DeleteRule(arg0 int, arg1 string, arg2 int) error {
 	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteRule", arg0, arg1)
+	ret := m.ctrl.Call(m, "DeleteRule", arg0, arg1, arg2)
 	ret0, _ := ret[0].(error)
 	return ret0
 }
 
 // DeleteRule indicates an expected call of DeleteRule
-func (mr *MockPodPortRulesMockRecorder) DeleteRule(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockPodPortRulesMockRecorder) DeleteRule(arg0, arg1, arg2 interface{}) *gomock.Call {
 	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRule", reflect.TypeOf((*MockPodPortRules)(nil).DeleteRule), arg0, arg1)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteRule", reflect.TypeOf((*MockPodPortRules)(nil).DeleteRule), arg0, arg1, arg2)
 }
 
 // Init mocks base method
diff --git a/pkg/agent/openflow/client_test.go b/pkg/agent/openflow/client_test.go
index 7f3af062e..d2e4f3edd 100644
--- a/pkg/agent/openflow/client_test.go
+++ b/pkg/agent/openflow/client_test.go
@@ -62,9 +62,8 @@ func installNodeFlows(ofClient Client, cacheKey string) (int, error) {
 	fCacheI, ok := client.nodeFlowCache.Load(hostName)
 	if ok {
 		return len(fCacheI.(flowCache)), err
-	} else {
-		return 0, err
 	}
+	return 0, err
 }
 
 func installPodFlows(ofClient Client, cacheKey string) (int, error) {
@@ -77,9 +76,8 @@ func installPodFlows(ofClient Client, cacheKey string) (int, error) {
 	fCacheI, ok := client.podFlowCache.Load(containerID)
 	if ok {
 		return len(fCacheI.(flowCache)), err
-	} else {
-		return 0, err
 	}
+	return 0, err
 }
 
 // TestIdempotentFlowInstallation checks that InstallNodeFlows and InstallPodFlows are idempotent.
diff --git a/pkg/controller/networkpolicy/status_controller_test.go b/pkg/controller/networkpolicy/status_controller_test.go
index 614e85080..6155a272b 100644
--- a/pkg/controller/networkpolicy/status_controller_test.go
+++ b/pkg/controller/networkpolicy/status_controller_test.go
@@ -120,13 +120,12 @@ func toAntreaNetworkPolicy(inp *types.NetworkPolicy) runtime.Object {
 				Generation: inp.Generation,
 			},
 		}
-	} else {
-		return &crdv1alpha1.ClusterNetworkPolicy{
-			ObjectMeta: v1.ObjectMeta{
-				Name:       inp.SourceRef.Name,
-				Generation: inp.Generation,
-			},
-		}
+	}
+	return &crdv1alpha1.ClusterNetworkPolicy{
+		ObjectMeta: v1.ObjectMeta{
+			Name:       inp.SourceRef.Name,
+			Generation: inp.Generation,
+		},
 	}
 }
 
diff --git a/test/e2e/basic_test.go b/test/e2e/basic_test.go
index 57497ec6b..b4a26f3af 100644
--- a/test/e2e/basic_test.go
+++ b/test/e2e/basic_test.go
@@ -283,11 +283,11 @@ func testIPAMRestart(t *testing.T, data *TestData) {
 			return nil, err
 		}
 		pods = append(pods, podName)
-		if podIP, err := data.podWaitForIPs(defaultTimeout, podName, testNamespace); err != nil {
+		podIP, err := data.podWaitForIPs(defaultTimeout, podName, testNamespace)
+		if err != nil {
 			return nil, err
-		} else {
-			return podIP, nil
 		}
+		return podIP, nil
 	}
 
 	if podIP1, err = createPodAndGetIP(podName1); err != nil {
@@ -577,11 +577,11 @@ func getRoundNumber(data *TestData, podName string) (uint64, error) {
 		key := externalIDArray[0].(string)
 		value := externalIDArray[1].(string)
 		if key == "roundNum" {
-			if roundNum, err := strconv.ParseUint(value, 10, 64); err != nil {
+			roundNum, err := strconv.ParseUint(value, 10, 64)
+			if err != nil {
 				return 0, fmt.Errorf("cannot convert roundNum to uint64: %v", err)
-			} else {
-				return roundNum, nil
 			}
+			return roundNum, nil
 		}
 	}
 
@@ -768,13 +768,13 @@ func testClusterIdentity(t *testing.T, data *TestData) {
 	const timeout = 10 * time.Second
 	var clusterUUID uuid.UUID
 	err := wait.PollImmediate(retryInterval, timeout, func() (bool, error) {
-		if clusterIdentity, _, err := clusterIdentityProvider.Get(); err != nil {
+		clusterIdentity, _, err := clusterIdentityProvider.Get()
+		if err != nil {
 			return false, nil
-		} else {
-			clusterUUID = clusterIdentity.UUID
-			t.Logf("Cluster UUID: %v", clusterUUID)
-			return true, nil
 		}
+		clusterUUID = clusterIdentity.UUID
+		t.Logf("Cluster UUID: %v", clusterUUID)
+		return true, nil
 	})
 
 	assert.NoError(t, err, "Failed to retrieve cluster identity information within %v", timeout)
diff --git a/test/e2e/egress_test.go b/test/e2e/egress_test.go
index 29c2928fc..5394beb8f 100644
--- a/test/e2e/egress_test.go
+++ b/test/e2e/egress_test.go
@@ -169,13 +169,23 @@ ip netns exec %[1]s /agnhost netexec
 	assertClientIP(localPod, egressNodeIP)
 	assertClientIP(remotePod, egressNodeIP)
 
+	var err error
+	err = wait.Poll(time.Millisecond*100, time.Second, func() (bool, error) {
+		egress, err = data.crdClient.CrdV1alpha2().Egresses().Get(context.TODO(), egress.Name, metav1.GetOptions{})
+		if err != nil {
+			return false, err
+		}
+		return egress.Status.EgressNode == egressNode, nil
+	})
+	assert.NoError(t, err, "Egress failed to reach expected status")
+
 	t.Log("Updating the Egress's AppliedTo to remotePod only")
 	egress.Spec.AppliedTo = v1alpha2.AppliedTo{
 		PodSelector: &metav1.LabelSelector{
 			MatchLabels: map[string]string{"antrea-e2e": remotePod},
 		},
 	}
-	egress, err := data.crdClient.CrdV1alpha2().Egresses().Update(context.TODO(), egress, metav1.UpdateOptions{})
+	egress, err = data.crdClient.CrdV1alpha2().Egresses().Update(context.TODO(), egress, metav1.UpdateOptions{})
 	if err != nil {
 		t.Fatalf("Failed to update Egress %v: %v", egress, err)
 	}
@@ -342,7 +352,7 @@ func testEgressUpdateEgressIP(t *testing.T, data *TestData) {
 			toUpdate.Spec.ExternalIPPool = newPool.Name
 			toUpdate.Spec.EgressIP = newIP
 			egress, err = data.crdClient.CrdV1alpha2().Egresses().Update(context.TODO(), toUpdate, metav1.UpdateOptions{})
-			require.NoError(t, err, "Failed to delete Egress")
+			require.NoError(t, err, "Failed to update Egress")
 
 			_, err = data.checkEgressState(egress.Name, newIP, tt.newNode, "", time.Second)
 			require.NoError(t, err)
diff --git a/test/e2e/fixtures.go b/test/e2e/fixtures.go
index e912f24b2..cc183ba9e 100644
--- a/test/e2e/fixtures.go
+++ b/test/e2e/fixtures.go
@@ -119,14 +119,14 @@ func skipIfNoWindowsNodes(tb testing.TB) {
 
 func skipIfFeatureDisabled(tb testing.TB, feature featuregate.Feature, checkAgent bool, checkController bool) {
 	if checkAgent {
-		if featureGate, err := GetAgentFeatures(antreaNamespace); err != nil {
+		if featureGate, err := GetAgentFeatures(); err != nil {
 			tb.Fatalf("Cannot determine if %s is enabled in the Agent: %v", feature, err)
 		} else if !featureGate.Enabled(feature) {
 			tb.Skipf("Skipping test because %s is not enabled in the Agent", feature)
 		}
 	}
 	if checkController {
-		if featureGate, err := GetControllerFeatures(antreaNamespace); err != nil {
+		if featureGate, err := GetControllerFeatures(); err != nil {
 			tb.Fatalf("Cannot determine if %s is enabled in the Controller: %v", feature, err)
 		} else if !featureGate.Enabled(feature) {
 			tb.Skipf("Skipping test because %s is not enabled in the Controller", feature)
@@ -429,13 +429,12 @@ func createTestBusyboxPods(tb testing.TB, data *TestData, num int, ns string, no
 			tb.Errorf("Error when creating busybox test Pod '%s': %v", podName, err)
 			return "", nil, err
 		}
-
-		if podIP, err := data.podWaitForIPs(defaultTimeout, podName, ns); err != nil {
+		podIP, err := data.podWaitForIPs(defaultTimeout, podName, ns)
+		if err != nil {
 			tb.Errorf("Error when waiting for IP for Pod '%s': %v", podName, err)
 			return podName, nil, err
-		} else {
-			return podName, podIP, nil
 		}
+		return podName, podIP, nil
 	}
 
 	podsCh := make(chan podData, num)
diff --git a/test/e2e/flowaggregator_test.go b/test/e2e/flowaggregator_test.go
index 094bfea7a..54fa74468 100644
--- a/test/e2e/flowaggregator_test.go
+++ b/test/e2e/flowaggregator_test.go
@@ -514,6 +514,7 @@ func checkRecordsForFlows(t *testing.T, data *TestData, srcIP string, dstIP stri
 		t.Errorf("Error when running iperf3 client: %v", err)
 	}
 	bwSlice, srcPort := getBandwidthAndSourcePort(stdout)
+	require.Equal(t, 2, len(bwSlice), "bandwidth value and / or bandwidth unit are not available")
 	// bandwidth from iperf output
 	bandwidthInFloat, err := strconv.ParseFloat(bwSlice[0], 64)
 	require.NoErrorf(t, err, "Error when converting iperf bandwidth %s to float64 type", bwSlice[0])
@@ -774,9 +775,8 @@ func getCollectorOutput(t *testing.T, srcIP, dstIP, srcPort string, timeStart ti
 				}
 			}
 			return false, nil
-		} else {
-			return strings.Contains(collectorOutput, srcIP) && strings.Contains(collectorOutput, dstIP) && strings.Contains(collectorOutput, srcPort), nil
 		}
+		return strings.Contains(collectorOutput, srcIP) && strings.Contains(collectorOutput, dstIP) && strings.Contains(collectorOutput, srcPort), nil
 	})
 	require.NoErrorf(t, err, "IPFIX collector did not receive the expected records in collector output: %v time start: %s iperf source port: %s", collectorOutput, timeStart.String(), srcPort)
 	return collectorOutput, recordSlices
diff --git a/test/e2e/framework.go b/test/e2e/framework.go
index cf7d43d75..8b7e6d98b 100644
--- a/test/e2e/framework.go
+++ b/test/e2e/framework.go
@@ -55,6 +55,8 @@ import (
 	"antrea.io/antrea/test/e2e/providers"
 )
 
+var AntreaConfigMap *corev1.ConfigMap
+
 const (
 	defaultTimeout  = 90 * time.Second
 	defaultInterval = 1 * time.Second
@@ -217,11 +219,11 @@ func workerNodeName(idx int) string {
 	if idx == 0 { // control-plane Node
 		return ""
 	}
-	if node, ok := clusterInfo.nodes[idx]; !ok {
+	node, ok := clusterInfo.nodes[idx]
+	if !ok {
 		return ""
-	} else {
-		return node.name
 	}
+	return node.name
 }
 
 // workerNodeIP returns an empty string if there is no worker Node with the provided idx
@@ -230,21 +232,21 @@ func workerNodeIP(idx int) string {
 	if idx == 0 { // control-plane Node
 		return ""
 	}
-	if node, ok := clusterInfo.nodes[idx]; !ok {
+	node, ok := clusterInfo.nodes[idx]
+	if !ok {
 		return ""
-	} else {
-		return node.ip
 	}
+	return node.ip
 }
 
 // nodeGatewayIPs returns the Antrea gateway's IPv4 address and IPv6 address for the provided Node
 // (if applicable), in that order.
 func nodeGatewayIPs(idx int) (string, string) {
-	if node, ok := clusterInfo.nodes[idx]; !ok {
+	node, ok := clusterInfo.nodes[idx]
+	if !ok {
 		return "", ""
-	} else {
-		return node.gwV4Addr, node.gwV6Addr
 	}
+	return node.gwV4Addr, node.gwV6Addr
 }
 
 func controlPlaneNodeName() string {
@@ -258,21 +260,21 @@ func controlPlaneNodeIP() string {
 // nodeName returns an empty string if there is no Node with the provided idx. If idx is 0, the name
 // of the control-plane Node will be returned.
 func nodeName(idx int) string {
-	if node, ok := clusterInfo.nodes[idx]; !ok {
+	node, ok := clusterInfo.nodes[idx]
+	if !ok {
 		return ""
-	} else {
-		return node.name
 	}
+	return node.name
 }
 
 // nodeIP returns an empty string if there is no Node with the provided idx. If idx is 0, the IP
 // of the control-plane Node will be returned.
 func nodeIP(idx int) string {
-	if node, ok := clusterInfo.nodes[idx]; !ok {
+	node, ok := clusterInfo.nodes[idx]
+	if !ok {
 		return ""
-	} else {
-		return node.ip
 	}
+	return node.ip
 }
 
 func labelNodeRoleControlPlane() string {
@@ -303,11 +305,11 @@ func initProvider() error {
 		"remote":  providers.NewRemoteProvider,
 	}
 	if fn, ok := providerFactory[testOptions.providerName]; ok {
-		if newProvider, err := fn(testOptions.providerConfigPath); err != nil {
+		newProvider, err := fn(testOptions.providerConfigPath)
+		if err != nil {
 			return err
-		} else {
-			provider = newProvider
 		}
+		provider = newProvider
 	} else {
 		return fmt.Errorf("unknown provider '%s'", testOptions.providerName)
 	}
@@ -408,35 +410,35 @@ func collectClusterInfo() error {
 			return res, fmt.Errorf("error when running the following command `%s` on control-plane Node: %v, %s", cmd, err, stdout)
 		}
 		re := regexp.MustCompile(reg)
-		if matches := re.FindStringSubmatch(stdout); len(matches) == 0 {
+		matches := re.FindStringSubmatch(stdout)
+		if len(matches) == 0 {
 			return res, fmt.Errorf("cannot retrieve CIDR, unexpected kubectl output: %s", stdout)
-		} else {
-			cidrs := strings.Split(matches[1], ",")
-			if len(cidrs) == 1 {
-				_, cidr, err := net.ParseCIDR(cidrs[0])
-				if err != nil {
-					return res, fmt.Errorf("CIDR cannot be parsed: %s", cidrs[0])
-				}
-				if cidr.IP.To4() != nil {
-					res[0] = cidrs[0]
-				} else {
-					res[1] = cidrs[0]
-				}
-			} else if len(cidrs) == 2 {
-				_, cidr, err := net.ParseCIDR(cidrs[0])
-				if err != nil {
-					return res, fmt.Errorf("CIDR cannot be parsed: %s", cidrs[0])
-				}
-				if cidr.IP.To4() != nil {
-					res[0] = cidrs[0]
-					res[1] = cidrs[1]
-				} else {
-					res[0] = cidrs[1]
-					res[1] = cidrs[0]
-				}
+		}
+		cidrs := strings.Split(matches[1], ",")
+		if len(cidrs) == 1 {
+			_, cidr, err := net.ParseCIDR(cidrs[0])
+			if err != nil {
+				return res, fmt.Errorf("CIDR cannot be parsed: %s", cidrs[0])
+			}
+			if cidr.IP.To4() != nil {
+				res[0] = cidrs[0]
 			} else {
-				return res, fmt.Errorf("unexpected cluster CIDR: %s", matches[1])
+				res[1] = cidrs[0]
 			}
+		} else if len(cidrs) == 2 {
+			_, cidr, err := net.ParseCIDR(cidrs[0])
+			if err != nil {
+				return res, fmt.Errorf("CIDR cannot be parsed: %s", cidrs[0])
+			}
+			if cidr.IP.To4() != nil {
+				res[0] = cidrs[0]
+				res[1] = cidrs[1]
+			} else {
+				res[0] = cidrs[1]
+				res[1] = cidrs[0]
+			}
+		} else {
+			return res, fmt.Errorf("unexpected cluster CIDR: %s", matches[1])
 		}
 		return res, nil
 	}
@@ -1025,8 +1027,7 @@ func (data *TestData) deletePodAndWait(timeout time.Duration, name string, ns st
 	if err := data.deletePod(ns, name); err != nil {
 		return err
 	}
-
-	if err := wait.Poll(defaultInterval, timeout, func() (bool, error) {
+	err := wait.Poll(defaultInterval, timeout, func() (bool, error) {
 		if _, err := data.clientset.CoreV1().Pods(ns).Get(context.TODO(), name, metav1.GetOptions{}); err != nil {
 			if errors.IsNotFound(err) {
 				return true, nil
@@ -1035,11 +1036,11 @@ func (data *TestData) deletePodAndWait(timeout time.Duration, name string, ns st
 		}
 		// Keep trying
 		return false, nil
-	}); err == wait.ErrWaitTimeout {
+	})
+	if err == wait.ErrWaitTimeout {
 		return fmt.Errorf("Pod '%s' still visible to client after %v", name, timeout)
-	} else {
-		return err
 	}
+	return err
 }
 
 type PodCondition func(*corev1.Pod) (bool, error)
@@ -1048,14 +1049,14 @@ type PodCondition func(*corev1.Pod) (bool, error)
 // the condition predicate is met (or until the provided timeout expires).
 func (data *TestData) podWaitFor(timeout time.Duration, name, namespace string, condition PodCondition) (*corev1.Pod, error) {
 	err := wait.Poll(defaultInterval, timeout, func() (bool, error) {
-		if pod, err := data.clientset.CoreV1().Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{}); err != nil {
+		pod, err := data.clientset.CoreV1().Pods(namespace).Get(context.TODO(), name, metav1.GetOptions{})
+		if err != nil {
 			if errors.IsNotFound(err) {
 				return false, nil
 			}
 			return false, fmt.Errorf("error when getting Pod '%s': %v", name, err)
-		} else {
-			return condition(pod)
 		}
+		return condition(pod)
 	})
 	if err != nil {
 		return nil, err
@@ -1410,7 +1411,7 @@ func (data *TestData) deleteServiceAndWait(timeout time.Duration, name string) e
 		return err
 	}
 
-	if err := wait.Poll(defaultInterval, timeout, func() (bool, error) {
+	err := wait.Poll(defaultInterval, timeout, func() (bool, error) {
 		if _, err := data.clientset.CoreV1().Services(testNamespace).Get(context.TODO(), name, metav1.GetOptions{}); err != nil {
 			if errors.IsNotFound(err) {
 				return true, nil
@@ -1419,11 +1420,11 @@ func (data *TestData) deleteServiceAndWait(timeout time.Duration, name string) e
 		}
 		// Keep trying
 		return false, nil
-	}); err == wait.ErrWaitTimeout {
+	})
+	if err == wait.ErrWaitTimeout {
 		return fmt.Errorf("Service '%s' still visible to client after %v", name, timeout)
-	} else {
-		return err
 	}
+	return err
 }
 
 // createNetworkPolicy creates a network policy with spec.
@@ -1537,16 +1538,17 @@ func parseArpingStdout(out string) (sent uint32, received uint32, loss float32,
 	if len(matches) == 0 {
 		return 0, 0, 0.0, fmt.Errorf("Unexpected arping output")
 	}
-	if v, err := strconv.ParseUint(matches[1], 10, 32); err != nil {
+	v, err := strconv.ParseUint(matches[1], 10, 32)
+	if err != nil {
 		return 0, 0, 0.0, fmt.Errorf("Error when retrieving 'sent probes' from arpping output: %v", err)
-	} else {
-		sent = uint32(v)
 	}
-	if v, err := strconv.ParseUint(matches[2], 10, 32); err != nil {
+	sent = uint32(v)
+
+	v, err = strconv.ParseUint(matches[2], 10, 32)
+	if err != nil {
 		return 0, 0, 0.0, fmt.Errorf("Error when retrieving 'received responses' from arpping output: %v", err)
-	} else {
-		received = uint32(v)
 	}
+	received = uint32(v)
 	loss = 100. * float32(sent-received) / float32(sent)
 	return sent, received, loss, nil
 }
@@ -1631,7 +1633,7 @@ func (data *TestData) GetEncapMode() (config.TrafficEncapModeType, error) {
 	return config.TrafficEncapModeEncap, nil
 }
 
-func getFeatures(confName string, antreaNamespace string) (featuregate.FeatureGate, error) {
+func getFeatures(confName string) (featuregate.FeatureGate, error) {
 	featureGate := features.DefaultMutableFeatureGate.DeepCopy()
 	var cfg interface{}
 	if err := yaml.Unmarshal([]byte(AntreaConfigMap.Data[confName]), &cfg); err != nil {
@@ -1651,12 +1653,12 @@ func getFeatures(confName string, antreaNamespace string) (featuregate.FeatureGa
 	return featureGate, nil
 }
 
-func GetAgentFeatures(antreaNamespace string) (featuregate.FeatureGate, error) {
-	return getFeatures(antreaAgentConfName, antreaNamespace)
+func GetAgentFeatures() (featuregate.FeatureGate, error) {
+	return getFeatures(antreaAgentConfName)
 }
 
-func GetControllerFeatures(antreaNamespace string) (featuregate.FeatureGate, error) {
-	return getFeatures(antreaControllerConfName, antreaNamespace)
+func GetControllerFeatures() (featuregate.FeatureGate, error) {
+	return getFeatures(antreaControllerConfName)
 }
 
 func (data *TestData) GetAntreaConfigMap(antreaNamespace string) (*corev1.ConfigMap, error) {
@@ -2035,14 +2037,14 @@ func (data *TestData) createDaemonSet(name string, ns string, ctrName string, im
 
 func (data *TestData) waitForDaemonSetPods(timeout time.Duration, dsName string, namespace string) error {
 	err := wait.Poll(defaultInterval, timeout, func() (bool, error) {
-		if ds, err := data.clientset.AppsV1().DaemonSets(namespace).Get(context.TODO(), dsName, metav1.GetOptions{}); err != nil {
+		ds, err := data.clientset.AppsV1().DaemonSets(namespace).Get(context.TODO(), dsName, metav1.GetOptions{})
+		if err != nil {
 			return false, err
-		} else {
-			if ds.Status.NumberReady != int32(clusterInfo.numNodes) {
-				return false, nil
-			}
-			return true, nil
 		}
+		if ds.Status.NumberReady != int32(clusterInfo.numNodes) {
+			return false, nil
+		}
+		return true, nil
 	})
 	if err != nil {
 		return err
diff --git a/test/e2e/infra/vagrant/playbook/roles/common/tasks/docker.yml b/test/e2e/infra/vagrant/playbook/roles/common/tasks/docker.yml
index 62cc47da8..5784acb90 100644
--- a/test/e2e/infra/vagrant/playbook/roles/common/tasks/docker.yml
+++ b/test/e2e/infra/vagrant/playbook/roles/common/tasks/docker.yml
@@ -46,3 +46,16 @@
 # Install docker-py so that docker images can be pulled
 - pip:
     name: docker-py
+
+- name: Create Docker daemon configuration from template
+  template:
+    src: templates/docker.json.j2
+    dest: /etc/docker/daemon.json
+  register: docker_config
+
+- name: Restart Docker
+  service:
+    name: docker
+    daemon_reload: yes
+    state: restarted
+  when: docker_config.changed
diff --git a/test/e2e/infra/vagrant/playbook/roles/common/templates/docker.json.j2 b/test/e2e/infra/vagrant/playbook/roles/common/templates/docker.json.j2
new file mode 100644
index 000000000..5d18abccd
--- /dev/null
+++ b/test/e2e/infra/vagrant/playbook/roles/common/templates/docker.json.j2
@@ -0,0 +1,8 @@
+{
+  "exec-opts": ["native.cgroupdriver=systemd"],
+  "log-driver": "json-file",
+  "log-opts": {
+    "max-size": "100m"
+  },
+  "storage-driver": "overlay2"
+}
diff --git a/test/e2e/ipsec_test.go b/test/e2e/ipsec_test.go
index 610ed43e2..cb2c1b3d4 100644
--- a/test/e2e/ipsec_test.go
+++ b/test/e2e/ipsec_test.go
@@ -58,16 +58,16 @@ func (data *TestData) readSecurityAssociationsStatus(nodeName string) (up int, c
 	if len(matches) == 0 {
 		return 0, 0, fmt.Errorf("unexpected 'ipsec status' output: %s", stdout)
 	}
-	if v, err := strconv.ParseUint(matches[1], 10, 32); err != nil {
+	v, err := strconv.ParseUint(matches[1], 10, 32)
+	if err != nil {
 		return 0, 0, fmt.Errorf("error when retrieving 'up' SAs from 'ipsec status' output: %v", err)
-	} else {
-		up = int(v)
 	}
-	if v, err := strconv.ParseUint(matches[2], 10, 32); err != nil {
+	up = int(v)
+	v, err = strconv.ParseUint(matches[2], 10, 32)
+	if err != nil {
 		return 0, 0, fmt.Errorf("error when retrieving 'connecting' SAs from 'ipsec status' output: %v", err)
-	} else {
-		connecting = int(v)
 	}
+	connecting = int(v)
 	return up, connecting, nil
 }
 
diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go
index 32aaefc14..ab011f519 100644
--- a/test/e2e/main_test.go
+++ b/test/e2e/main_test.go
@@ -22,12 +22,8 @@ import (
 	"os"
 	"testing"
 	"time"
-
-	corev1 "k8s.io/api/core/v1"
 )
 
-var AntreaConfigMap *corev1.ConfigMap
-
 // setupLogging creates a temporary directory to export the test logs if necessary. If a directory
 // was provided by the user, it checks that the directory exists.
 func (tOptions *TestOptions) setupLogging() func() {
@@ -47,14 +43,13 @@ func (tOptions *TestOptions) setupLogging() func() {
 				log.Printf("Logs exported under '%s', it is your responsibility to delete the directory when you no longer need it", name)
 			}
 		}
-	} else {
-		fInfo, err := os.Stat(tOptions.logsExportDir)
-		if err != nil {
-			log.Fatalf("Cannot stat provided directory '%s': %v", tOptions.logsExportDir, err)
-		}
-		if !fInfo.Mode().IsDir() {
-			log.Fatalf("'%s' is not a valid directory", tOptions.logsExportDir)
-		}
+	}
+	fInfo, err := os.Stat(tOptions.logsExportDir)
+	if err != nil {
+		log.Fatalf("Cannot stat provided directory '%s': %v", tOptions.logsExportDir, err)
+	}
+	if !fInfo.Mode().IsDir() {
+		log.Fatalf("'%s' is not a valid directory", tOptions.logsExportDir)
 	}
 	// no-op cleanup function
 	return func() {}
diff --git a/test/e2e/networkpolicy_test.go b/test/e2e/networkpolicy_test.go
index 5db351f2b..c465d8b33 100644
--- a/test/e2e/networkpolicy_test.go
+++ b/test/e2e/networkpolicy_test.go
@@ -356,11 +356,11 @@ func testDefaultDenyIngressPolicy(t *testing.T, data *TestData) {
 	defer data.deleteService(service.Name)
 
 	// client1 is a host network Pod and is on the same node as the server Pod, simulating kubelet probe traffic.
-	client1Name, _, cleanupFunc := createAndWaitForPod(t, data, data.createHostNetworkBusyboxPodOnNode, "test-hostnetwork-client-", serverNode, testNamespace)
+	client1Name, _, cleanupFunc := createAndWaitForPod(t, data, data.createHostNetworkBusyboxPodOnNode, "test-hostnetwork-client-can-connect-", serverNode, testNamespace)
 	defer cleanupFunc()
 
 	// client2 is a host network Pod and is on a different node from the server Pod, accessing the server Pod via the NodePort service.
-	client2Name, _, cleanupFunc := createAndWaitForPod(t, data, data.createHostNetworkBusyboxPodOnNode, "test-hostnetwork-client-", controlPlaneNodeName(), testNamespace)
+	client2Name, _, cleanupFunc := createAndWaitForPod(t, data, data.createHostNetworkBusyboxPodOnNode, "test-hostnetwork-client-cannot-connect-", controlPlaneNodeName(), testNamespace)
 	defer cleanupFunc()
 
 	spec := &networkingv1.NetworkPolicySpec{
diff --git a/test/e2e/providers/vagrant.go b/test/e2e/providers/vagrant.go
index b68644c45..1ce53a26d 100644
--- a/test/e2e/providers/vagrant.go
+++ b/test/e2e/providers/vagrant.go
@@ -73,11 +73,11 @@ func convertConfig(inConfig *ssh_config.Config, name string) (string, *ssh.Clien
 	values := make(map[string]string)
 
 	for _, key := range keyList {
-		if value, err := getFromKeyStrict(key); err != nil {
+		value, err := getFromKeyStrict(key)
+		if err != nil {
 			return "", nil, err
-		} else {
-			values[key] = value
 		}
+		values[key] = value
 	}
 
 	identityFile := values["IdentityFile"]
diff --git a/test/integration/agent/cniserver_test.go b/test/integration/agent/cniserver_test.go
index c814e4be1..34fb02f29 100644
--- a/test/integration/agent/cniserver_test.go
+++ b/test/integration/agent/cniserver_test.go
@@ -282,9 +282,8 @@ func (tc testCase) createCheckCmdArgs(targetNS ns.NetNS, config *Net, dataDir st
 func ipVersion(ip net.IP) string {
 	if ip.To4() != nil {
 		return "4"
-	} else {
-		return "6"
 	}
+	return "6"
 }
 
 type cmdAddDelTester struct {
diff --git a/test/integration/agent/flowexporter_test.go b/test/integration/agent/flowexporter_test.go
index df96d842f..8543735ed 100644
--- a/test/integration/agent/flowexporter_test.go
+++ b/test/integration/agent/flowexporter_test.go
@@ -37,7 +37,10 @@ import (
 	queriertest "antrea.io/antrea/pkg/querier/testing"
 )
 
-const testPollInterval = 0 // Not used in the test, hence 0.
+const (
+	testPollInterval           = 0 // Not used in the test, hence 0.
+	testStaleConnectionTimeout = 5 * time.Minute
+)
 
 func createConnsForTest() ([]*flowexporter.Connection, []*flowexporter.ConnectionKey) {
 	// Reference for flow timestamp
@@ -108,7 +111,7 @@ func TestConnectionStoreAndFlowRecords(t *testing.T) {
 	ifStoreMock := interfacestoretest.NewMockInterfaceStore(ctrl)
 	npQuerier := queriertest.NewMockAgentNetworkPolicyInfoQuerier(ctrl)
 	// TODO: Enhance the integration test by testing service.
-	conntrackConnStore := connections.NewConntrackConnectionStore(connDumperMock, flowrecords.NewFlowRecords(), ifStoreMock, true, false, nil, npQuerier, testPollInterval)
+	conntrackConnStore := connections.NewConntrackConnectionStore(connDumperMock, flowrecords.NewFlowRecords(), ifStoreMock, true, false, nil, npQuerier, testPollInterval, testStaleConnectionTimeout)
 	// Expect calls for connStore.poll and other callees
 	connDumperMock.EXPECT().DumpFlows(uint16(openflow.CtZone)).Return(testConns, 0, nil)
 	connDumperMock.EXPECT().GetMaxConnections().Return(0, nil)
diff --git a/test/integration/agent/openflow_test.go b/test/integration/agent/openflow_test.go
index 8adc762d2..e343658d7 100644
--- a/test/integration/agent/openflow_test.go
+++ b/test/integration/agent/openflow_test.go
@@ -799,9 +799,8 @@ func getIPProtoStr(addr types.Address) (bool, string) {
 	}
 	if addrIP.To4() != nil {
 		return false, "ip"
-	} else {
-		return true, "ipv6"
 	}
+	return true, "ipv6"
 }
 
 func checkOVSFlowMetrics(t *testing.T, client ofClient.Client) {