Skip to content

Commit 3a2c2d7

Browse files
tnqnluolanzone
authored andcommitted
Ensure OVS port is valid before setting NO_FLOOD (#4674)
There could be some cases that OVS ports are left invalid. Setting NO_FLOOD for these ports will fail for sure and restarting agents would just meet the same error. Later we should enhance the port cleanup logic, either when they are firstly identified, or when their owners do the initialization. For now, as there could be invalid ports in interface cache, we should ensure a port is valid before setting NO_FLOOD. Signed-off-by: Quan Tian <qtian@vmware.com>
1 parent a1e9dba commit 3a2c2d7

6 files changed

Lines changed: 82 additions & 19 deletions

File tree

cmd/antrea-agent/agent.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ func run(o *Options) error {
232232
k8sClient,
233233
crdClient,
234234
ovsBridgeClient,
235+
ovsctl.NewClient(o.config.OVSBridge),
235236
ofClient,
236237
routeClient,
237238
ifaceStore,

pkg/agent/agent.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ type Initializer struct {
9595
client clientset.Interface
9696
crdClient versioned.Interface
9797
ovsBridgeClient ovsconfig.OVSBridgeClient
98+
ovsCtlClient ovsctl.OVSCtlClient
9899
ofClient openflow.Client
99100
routeClient route.Interface
100101
wireGuardClient wireguard.Interface
@@ -122,6 +123,7 @@ func NewInitializer(
122123
k8sClient clientset.Interface,
123124
crdClient versioned.Interface,
124125
ovsBridgeClient ovsconfig.OVSBridgeClient,
126+
ovsCtlClient ovsctl.OVSCtlClient,
125127
ofClient openflow.Client,
126128
routeClient route.Interface,
127129
ifaceStore interfacestore.InterfaceStore,
@@ -142,6 +144,7 @@ func NewInitializer(
142144
) *Initializer {
143145
return &Initializer{
144146
ovsBridgeClient: ovsBridgeClient,
147+
ovsCtlClient: ovsCtlClient,
145148
client: k8sClient,
146149
crdClient: crdClient,
147150
ifaceStore: ifaceStore,
@@ -371,17 +374,20 @@ func (i *Initializer) initInterfaceStore() error {
371374
}
372375

373376
func (i *Initializer) restorePortConfigs() error {
374-
ovsCtlClient := ovsctl.NewClient(i.ovsBridge)
375377
interfaces := i.ifaceStore.ListInterfaces()
376378
for _, intf := range interfaces {
377379
switch intf.Type {
378380
case interfacestore.IPSecTunnelInterface:
379381
fallthrough
380382
case interfacestore.TrafficControlInterface:
381-
if err := ovsCtlClient.SetPortNoFlood(int(intf.OFPort)); err != nil {
382-
return fmt.Errorf("failed to set port %s with no-flood: %w", intf.InterfaceName, err)
383+
if intf.OFPort < 0 {
384+
klog.InfoS("Skipped setting no-flood for port due to invalid ofPort", "port", intf.InterfaceName, "ofport", intf.OFPort)
385+
continue
386+
}
387+
if err := i.ovsCtlClient.SetPortNoFlood(int(intf.OFPort)); err != nil {
388+
return fmt.Errorf("failed to set no-flood for port %s: %w", intf.InterfaceName, err)
383389
}
384-
klog.InfoS("Set port no-flood successfully", "PortName", intf.InterfaceName)
390+
klog.InfoS("Set no-flood for port", "port", intf.InterfaceName)
385391
}
386392
}
387393
return nil

pkg/agent/agent_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"antrea.io/antrea/pkg/agent/types"
3838
"antrea.io/antrea/pkg/ovs/ovsconfig"
3939
ovsconfigtest "antrea.io/antrea/pkg/ovs/ovsconfig/testing"
40+
ovsctltest "antrea.io/antrea/pkg/ovs/ovsctl/testing"
4041
"antrea.io/antrea/pkg/util/env"
4142
"antrea.io/antrea/pkg/util/ip"
4243
"antrea.io/antrea/pkg/util/runtime"
@@ -647,3 +648,70 @@ func mockConfigureLinkAddress(returnedErr error) func() {
647648
configureLinkAddresses = originalConfigureLinkAddresses
648649
}
649650
}
651+
652+
func TestRestorePortConfigs(t *testing.T) {
653+
tests := []struct {
654+
name string
655+
existingInterfaces []*interfacestore.InterfaceConfig
656+
expectedOVSCtlCalls func(client *ovsctltest.MockOVSCtlClientMockRecorder)
657+
expectedErr string
658+
}{
659+
{
660+
name: "success",
661+
existingInterfaces: []*interfacestore.InterfaceConfig{
662+
interfacestore.NewIPSecTunnelInterface("antrea-ipsec1",
663+
ovsconfig.GeneveTunnel,
664+
"node1",
665+
net.ParseIP("1.1.1.1"),
666+
"abcdefg",
667+
"node1",
668+
&interfacestore.OVSPortConfig{OFPort: 11, PortUUID: "uuid1"}),
669+
interfacestore.NewTunnelInterface(defaultTunInterfaceName,
670+
ovsconfig.GeneveTunnel,
671+
0,
672+
net.ParseIP("1.1.1.10"),
673+
true,
674+
&interfacestore.OVSPortConfig{OFPort: 12}),
675+
interfacestore.NewTrafficControlInterface("antrea-tap1",
676+
&interfacestore.OVSPortConfig{OFPort: 13, PortUUID: "uuid3"}),
677+
interfacestore.NewTrafficControlInterface("antrea-tap2",
678+
&interfacestore.OVSPortConfig{OFPort: -1, PortUUID: "uuid3"}),
679+
},
680+
expectedOVSCtlCalls: func(client *ovsctltest.MockOVSCtlClientMockRecorder) {
681+
client.SetPortNoFlood(11).Return(nil)
682+
client.SetPortNoFlood(13).Return(nil)
683+
},
684+
},
685+
{
686+
name: "fail",
687+
existingInterfaces: []*interfacestore.InterfaceConfig{
688+
interfacestore.NewTrafficControlInterface("antrea-tap1",
689+
&interfacestore.OVSPortConfig{OFPort: 10, PortUUID: "uuid3"}),
690+
},
691+
expectedOVSCtlCalls: func(client *ovsctltest.MockOVSCtlClientMockRecorder) {
692+
client.SetPortNoFlood(10).Return(fmt.Errorf("server unavailable"))
693+
},
694+
expectedErr: "failed to set no-flood for port antrea-tap1: server unavailable",
695+
},
696+
}
697+
for _, tt := range tests {
698+
t.Run(tt.name, func(t *testing.T) {
699+
controller := mock.NewController(t)
700+
defer controller.Finish()
701+
mockOVSCtlClient := ovsctltest.NewMockOVSCtlClient(controller)
702+
ifaceStore := interfacestore.NewInterfaceStore()
703+
initializer := &Initializer{
704+
ifaceStore: ifaceStore,
705+
ovsCtlClient: mockOVSCtlClient,
706+
}
707+
ifaceStore.Initialize(tt.existingInterfaces)
708+
tt.expectedOVSCtlCalls(mockOVSCtlClient.EXPECT())
709+
err := initializer.restorePortConfigs()
710+
if tt.expectedErr == "" {
711+
assert.NoError(t, err)
712+
} else {
713+
assert.ErrorContains(t, err, tt.expectedErr)
714+
}
715+
})
716+
}
717+
}

pkg/agent/controller/trafficcontrol/controller.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -762,8 +762,7 @@ func (c *Controller) getOrCreateTrafficControlPort(port *v1alpha2.TrafficControl
762762
return 0, err
763763
}
764764
}
765-
itf := interfacestore.NewTrafficControlInterface(portName)
766-
itf.OVSPortConfig = &interfacestore.OVSPortConfig{PortUUID: portUUID, OFPort: ofPort}
765+
itf := interfacestore.NewTrafficControlInterface(portName, &interfacestore.OVSPortConfig{PortUUID: portUUID, OFPort: ofPort})
767766
c.interfaceStore.AddInterface(itf)
768767
// Create binding for the newly created port.
769768
c.portToTCBindings[portName] = &portToTCBinding{

pkg/agent/interfacestore/interface_cache_test.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ func TestNewInterfaceStore(t *testing.T) {
4040
t.Run("testGatewayInterface", testGatewayInterface)
4141
t.Run("testTunnelInterface", testTunnelInterface)
4242
t.Run("testUplinkInterface", testUplinkInterface)
43-
t.Run("testTrafficControlInterface", testTrafficControlInterface)
4443
t.Run("testExternalEntityInterface", testEntityInterface)
4544
}
4645

@@ -164,16 +163,6 @@ func testUplinkInterface(t *testing.T) {
164163
testGeneralInterface(t, uplinkInterface, UplinkInterface)
165164
}
166165

167-
func testTrafficControlInterface(t *testing.T) {
168-
tcInterface := NewTrafficControlInterface("tc0")
169-
tcInterface.IPs = []net.IP{hostIP}
170-
tcInterface.OVSPortConfig = &OVSPortConfig{
171-
OFPort: 17,
172-
PortUUID: "1234567890",
173-
}
174-
testGeneralInterface(t, tcInterface, TrafficControlInterface)
175-
}
176-
177166
func testEntityInterface(t *testing.T) {
178167
store := NewInterfaceStore()
179168
portConfig := &OVSPortConfig{OFPort: 18, PortUUID: "123456789"}

pkg/agent/interfacestore/types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ func NewUplinkInterface(uplinkName string) *InterfaceConfig {
175175
return uplinkConfig
176176
}
177177

178-
func NewTrafficControlInterface(interfaceName string) *InterfaceConfig {
179-
trafficControlConfig := &InterfaceConfig{InterfaceName: interfaceName, Type: TrafficControlInterface}
178+
func NewTrafficControlInterface(interfaceName string, ovsPortConfig *OVSPortConfig) *InterfaceConfig {
179+
trafficControlConfig := &InterfaceConfig{InterfaceName: interfaceName, Type: TrafficControlInterface, OVSPortConfig: ovsPortConfig}
180180
return trafficControlConfig
181181
}
182182

0 commit comments

Comments
 (0)