Skip to content

Commit 8f29ecb

Browse files
committed
Restore NO_FLOOD to OVS ports after reconnecting the OVS bridge
The NO_FLOOD configuration is lost when the OVS daemon is restarted. Currently, the only way to recover this configuration is by restarting the agent. This pull request adds logic to recover the configuration when receiving OVS reconnection events. Signed-off-by: Xu Liu <xliu2@vmware.com>
1 parent d5dd02e commit 8f29ecb

3 files changed

Lines changed: 46 additions & 6 deletions

File tree

pkg/agent/agent.go

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,6 @@ func (i *Initializer) initInterfaceStore() error {
287287
return intf
288288
}
289289
ifaceList := make([]*interfacestore.InterfaceConfig, 0, len(ovsPorts))
290-
ovsCtlClient := ovsctl.NewClient(i.ovsBridge)
291290
for index := range ovsPorts {
292291
port := &ovsPorts[index]
293292
ovsPort := &interfacestore.OVSPortConfig{
@@ -322,9 +321,8 @@ func (i *Initializer) initInterfaceStore() error {
322321
intf = cniserver.ParseOVSPortInterfaceConfig(port, ovsPort)
323322
case interfacestore.AntreaTrafficControl:
324323
intf = trafficcontrol.ParseTrafficControlInterfaceConfig(port, ovsPort)
325-
if err := ovsCtlClient.SetPortNoFlood(int(ovsPort.OFPort)); err != nil {
326-
klog.ErrorS(err, "Failed to set port with no-flood config", "PortName", port.Name)
327-
}
324+
case interfacestore.AntreaIPsec:
325+
intf = noderoute.ParseTunnelInterfaceConfig(port, ovsPort)
328326
default:
329327
klog.InfoS("Unknown Antrea interface type", "type", interfaceType)
330328
}
@@ -376,6 +374,30 @@ func (i *Initializer) initInterfaceStore() error {
376374
return nil
377375
}
378376

377+
func (i *Initializer) restorePortConfigs() error {
378+
ovsCtlClient := ovsctl.NewClient(i.ovsBridge)
379+
ovsPorts, err := i.ovsBridgeClient.GetPortList()
380+
if err != nil {
381+
return fmt.Errorf("failed to list OVS ports: %w", err)
382+
}
383+
for _, port := range ovsPorts {
384+
interfaceType, ok := port.ExternalIDs[interfacestore.AntreaInterfaceTypeKey]
385+
if !ok {
386+
continue
387+
}
388+
switch interfaceType {
389+
case interfacestore.AntreaIPsec:
390+
fallthrough
391+
case interfacestore.AntreaTrafficControl:
392+
if err := ovsCtlClient.SetPortNoFlood(int(port.OFPort)); err != nil {
393+
return fmt.Errorf("failed to set port %s with no-flood: %w", port.Name, err)
394+
}
395+
klog.InfoS("Set port no-flood successfully", "PortName", port.Name)
396+
}
397+
}
398+
return nil
399+
}
400+
379401
// Initialize sets up agent initial configurations.
380402
func (i *Initializer) Initialize() error {
381403
klog.Info("Setting up node network")
@@ -394,6 +416,10 @@ func (i *Initializer) Initialize() error {
394416
return err
395417
}
396418

419+
if err := i.restorePortConfigs(); err != nil {
420+
return err
421+
}
422+
397423
if i.enableL7NetworkPolicy {
398424
// prepareL7NetworkPolicyInterfaces must be executed after setupOVSBridge since it requires interfaceStore.
399425
if err := i.prepareL7NetworkPolicyInterfaces(); err != nil {
@@ -568,11 +594,17 @@ func (i *Initializer) initOpenFlowPipeline() error {
568594
i.ofClient.ReplayFlows()
569595
klog.Info("Flow replay completed")
570596

597+
klog.InfoS("Restoring OF port configs to OVS bridge")
598+
if err := i.restorePortConfigs(); err != nil {
599+
klog.ErrorS(err, "Failed to restore OF port configs")
600+
} else {
601+
klog.InfoS("Port configs restoration completed")
602+
}
571603
// ofClient and ovsBridgeClient have their own mechanisms to restore connections with OVS, and it could
572604
// happen that ovsBridgeClient's connection is not ready when ofClient completes flow replay. We retry it
573605
// with a timeout that is longer time than ovsBridgeClient's maximum connecting retry interval (8 seconds)
574606
// to ensure the flag can be removed successfully.
575-
err := wait.PollImmediate(200*time.Millisecond, 10*time.Second, func() (done bool, err error) {
607+
err = wait.PollImmediate(200*time.Millisecond, 10*time.Second, func() (done bool, err error) {
576608
if err := i.FlowRestoreComplete(); err != nil {
577609
return false, nil
578610
}

pkg/agent/controller/noderoute/node_route_controller.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,11 @@ func (c *Controller) createIPSecTunnelPort(nodeName string, nodeIP net.IP) (int3
677677
exists = false
678678
}
679679
}
680+
ovsExternalIDs := map[string]interface{}{
681+
ovsExternalIDNodeName: nodeName,
682+
interfacestore.AntreaInterfaceTypeKey: interfacestore.AntreaIPsec,
683+
}
680684
if !exists {
681-
ovsExternalIDs := map[string]interface{}{ovsExternalIDNodeName: nodeName}
682685
portUUID, err := c.ovsBridgeClient.CreateTunnelPortExt(
683686
portName,
684687
c.networkConfig.TunnelType,
@@ -714,6 +717,10 @@ func (c *Controller) createIPSecTunnelPort(nodeName string, nodeIP net.IP) (int3
714717
// Let NodeRouteController retry at errors.
715718
return 0, fmt.Errorf("failed to get of_port of IPsec tunnel port for Node %s", nodeName)
716719
}
720+
// Set external_ids to the port for upgrade case.
721+
if err := c.ovsBridgeClient.SetPortExternalIDs(portName, ovsExternalIDs); err != nil {
722+
return 0, fmt.Errorf("failed to set external IDs for port %s: %w", nodeName, err)
723+
}
717724
// Set the port with no-flood to reject ARP flood packets.
718725
if err := c.ovsCtlClient.SetPortNoFlood(int(ofPort)); err != nil {
719726
return 0, fmt.Errorf("failed to set port %s with no-flood config: %w", portName, err)

pkg/agent/interfacestore/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const (
4343
AntreaUplink = "uplink"
4444
AntreaHost = "host"
4545
AntreaTrafficControl = "traffic-control"
46+
AntreaIPsec = "ipsec"
4647
AntreaUnset = ""
4748
)
4849

0 commit comments

Comments
 (0)