diff --git a/cmd/antrea-agent/options.go b/cmd/antrea-agent/options.go index 732a6abfb6c..faaa1934428 100644 --- a/cmd/antrea-agent/options.go +++ b/cmd/antrea-agent/options.go @@ -734,8 +734,8 @@ func (o *Options) validateSecondaryNetworkConfig() error { if brConfig.BridgeName == "" { return fmt.Errorf("bridge name is not provided for the secondary network OVS bridge") } - if len(brConfig.PhysicalInterfaces) > 1 { - return fmt.Errorf("at most one physical interface can be specified for the secondary network OVS bridge") + if len(brConfig.PhysicalInterfaces) > 8 { + return fmt.Errorf("at most eight physical interfaces can be specified for the secondary network OVS bridge") } return nil diff --git a/cmd/antrea-agent/options_test.go b/cmd/antrea-agent/options_test.go index 22c612d7c5f..4b62f775800 100644 --- a/cmd/antrea-agent/options_test.go +++ b/cmd/antrea-agent/options_test.go @@ -319,8 +319,8 @@ func TestOptionsValidateSecondaryNetworkConfig(t *testing.T) { name: "two interfaces", featureGateValue: true, ovsBridges: []string{"br1"}, - physicalInterfaces: []string{"eth1", "eth2"}, - expectedErr: "at most one physical interface can be specified for the secondary network OVS bridge", + physicalInterfaces: []string{"eth1", "eth2", "eth3", "eth4", "eth5", "eth6", "eth7", "eth8", "eth9"}, + expectedErr: "at most eight physical interfaces can be specified for the secondary network OVS bridge", }, } for _, tc := range tests { diff --git a/docs/secondary-network.md b/docs/secondary-network.md index 8b8d122d198..31f7b24dd92 100644 --- a/docs/secondary-network.md +++ b/docs/secondary-network.md @@ -68,8 +68,8 @@ data: ``` At the moment, Antrea supports only a single OVS bridge for secondary networks, -and supports only a single physical interface on the bridge. The physical -interface cannot be the Node's management interface, otherwise the Node's +and supports upto eight physical interfaces on the bridge. The physical +interfaces cannot be the Node's management interface, otherwise the Node's management network connectivity can be broken after `antrea-agent` creates the OVS bridge and moves the management interface to the bridge. diff --git a/pkg/agent/secondarynetwork/init.go b/pkg/agent/secondarynetwork/init.go index abc3351c001..7333b6e5878 100644 --- a/pkg/agent/secondarynetwork/init.go +++ b/pkg/agent/secondarynetwork/init.go @@ -34,7 +34,7 @@ import ( ) var ( - // Funcs which will be orridden with mock funcs in tests. + // Funcs which will be overridden with mock funcs in tests. interfaceByNameFn = net.InterfaceByName newOVSBridgeFn = ovsconfig.NewOVSBridge ) @@ -82,9 +82,7 @@ func createOVSBridge(bridges []agentconfig.OVSBridgeConfig, ovsdb *ovsdb.OVSDB) // Only one OVS bridge is supported. bridgeConfig := bridges[0] - phyInterface := "" - if len(bridgeConfig.PhysicalInterfaces) > 0 { - phyInterface = bridgeConfig.PhysicalInterfaces[0] + for _, phyInterface := range bridgeConfig.PhysicalInterfaces { if _, err := interfaceByNameFn(phyInterface); err != nil { return nil, fmt.Errorf("failed to get interface %s: %v", phyInterface, err) } @@ -96,21 +94,17 @@ func createOVSBridge(bridges []agentconfig.OVSBridgeConfig, ovsdb *ovsdb.OVSDB) } klog.InfoS("OVS bridge created", "bridge", bridgeConfig.BridgeName) - if phyInterface == "" { - return ovsBridgeClient, nil - } - - if _, err := ovsBridgeClient.GetOFPort(phyInterface, false); err == nil { - klog.V(2).InfoS("Physical interface already connected to OVS bridge, skip the configuration", "device", phyInterface, "bridge", bridgeConfig.BridgeName) - return ovsBridgeClient, nil - } + for i, phyInterface := range bridgeConfig.PhysicalInterfaces { + if _, err := ovsBridgeClient.GetOFPort(phyInterface, false); err == nil { + klog.V(2).InfoS("Physical interface already connected to OVS bridge, skip the configuration", "device", phyInterface, "bridge", bridgeConfig.BridgeName) + continue + } - _, err := ovsBridgeClient.CreateUplinkPort(phyInterface, 0, map[string]interface{}{interfacestore.AntreaInterfaceTypeKey: interfacestore.AntreaUplink}) - if err != nil { - return nil, fmt.Errorf("failed to create OVS uplink port %s: %v", phyInterface, err) + if _, err := ovsBridgeClient.CreateUplinkPort(phyInterface, int32(i), map[string]interface{}{interfacestore.AntreaInterfaceTypeKey: interfacestore.AntreaUplink}); err != nil { + return nil, fmt.Errorf("failed to create OVS uplink port %s: %v", phyInterface, err) + } + klog.InfoS("Physical interface added to OVS bridge", "device", phyInterface, "bridge", bridgeConfig.BridgeName) } - klog.InfoS("Physical interface added to OVS bridge", "device", phyInterface, "bridge", bridgeConfig.BridgeName) - return ovsBridgeClient, nil } diff --git a/pkg/agent/secondarynetwork/init_test.go b/pkg/agent/secondarynetwork/init_test.go index 56845365e94..b9be6fe0fd2 100644 --- a/pkg/agent/secondarynetwork/init_test.go +++ b/pkg/agent/secondarynetwork/init_test.go @@ -82,6 +82,8 @@ func TestCreateOVSBridge(t *testing.T) { m.EXPECT().Create().Return(nil) m.EXPECT().GetOFPort("eth1", false).Return(int32(0), ovsconfig.InvalidArgumentsError("port not found")) m.EXPECT().CreateUplinkPort("eth1", int32(0), map[string]interface{}{"antrea-type": "uplink"}).Return("", nil) + m.EXPECT().GetOFPort("eth2", false).Return(int32(1), ovsconfig.InvalidArgumentsError("port not found")) + m.EXPECT().CreateUplinkPort("eth2", int32(1), map[string]interface{}{"antrea-type": "uplink"}).Return("", nil) }, }, { diff --git a/pkg/config/agent/config.go b/pkg/config/agent/config.go index 21d3ac50cdf..1c59f48b3f9 100644 --- a/pkg/config/agent/config.go +++ b/pkg/config/agent/config.go @@ -398,7 +398,6 @@ type SecondaryNetworkConfig struct { type OVSBridgeConfig struct { BridgeName string `yaml:"bridgeName"` - // Names of physical interfaces to be connected to the bridge. At the moment, - // only a single physical interface is supported. + // Names of physical interfaces to be connected to the bridge. PhysicalInterfaces []string `yaml:"physicalInterfaces,omitempty"` }