Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure OVS port is valid before setting NO_FLOOD #4674

Merged
merged 1 commit into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,17 +379,20 @@ func (i *Initializer) initInterfaceStore() error {
}

func (i *Initializer) restorePortConfigs() error {
ovsCtlClient := ovsctl.NewClient(i.ovsBridge)
interfaces := i.ifaceStore.ListInterfaces()
for _, intf := range interfaces {
switch intf.Type {
case interfacestore.IPSecTunnelInterface:
fallthrough
case interfacestore.TrafficControlInterface:
if err := ovsCtlClient.SetPortNoFlood(int(intf.OFPort)); err != nil {
return fmt.Errorf("failed to set port %s with no-flood: %w", intf.InterfaceName, err)
if intf.OFPort < 0 {
klog.InfoS("Skipped setting no-flood for port due to invalid ofPort", "port", intf.InterfaceName, "ofport", intf.OFPort)
continue
}
if err := i.ovsCtlClient.SetPortNoFlood(int(intf.OFPort)); err != nil {
return fmt.Errorf("failed to set no-flood for port %s: %w", intf.InterfaceName, err)
}
klog.InfoS("Set port no-flood successfully", "PortName", intf.InterfaceName)
klog.InfoS("Set no-flood for port", "port", intf.InterfaceName)
}
}
return nil
Expand Down
3 changes: 1 addition & 2 deletions pkg/agent/agent_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,7 @@ func (i *Initializer) prepareL7NetworkPolicyInterfaces() error {
return err
}

itf := interfacestore.NewTrafficControlInterface(portName)
itf.OVSPortConfig = &interfacestore.OVSPortConfig{PortUUID: portUUID, OFPort: ofPort}
itf := interfacestore.NewTrafficControlInterface(portName, &interfacestore.OVSPortConfig{PortUUID: portUUID, OFPort: ofPort})
i.ifaceStore.AddInterface(itf)
}

Expand Down
68 changes: 68 additions & 0 deletions pkg/agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"antrea.io/antrea/pkg/agent/types"
"antrea.io/antrea/pkg/ovs/ovsconfig"
ovsconfigtest "antrea.io/antrea/pkg/ovs/ovsconfig/testing"
ovsctltest "antrea.io/antrea/pkg/ovs/ovsctl/testing"
"antrea.io/antrea/pkg/util/env"
"antrea.io/antrea/pkg/util/ip"
"antrea.io/antrea/pkg/util/runtime"
Expand Down Expand Up @@ -647,3 +648,70 @@ func mockConfigureLinkAddress(returnedErr error) func() {
configureLinkAddresses = originalConfigureLinkAddresses
}
}

func TestRestorePortConfigs(t *testing.T) {
tests := []struct {
name string
existingInterfaces []*interfacestore.InterfaceConfig
expectedOVSCtlCalls func(client *ovsctltest.MockOVSCtlClientMockRecorder)
expectedErr string
}{
{
name: "success",
existingInterfaces: []*interfacestore.InterfaceConfig{
interfacestore.NewIPSecTunnelInterface("antrea-ipsec1",
ovsconfig.GeneveTunnel,
"node1",
net.ParseIP("1.1.1.1"),
"abcdefg",
"node1",
&interfacestore.OVSPortConfig{OFPort: 11, PortUUID: "uuid1"}),
interfacestore.NewTunnelInterface(defaultTunInterfaceName,
ovsconfig.GeneveTunnel,
0,
net.ParseIP("1.1.1.10"),
true,
&interfacestore.OVSPortConfig{OFPort: 12}),
interfacestore.NewTrafficControlInterface("antrea-tap1",
&interfacestore.OVSPortConfig{OFPort: 13, PortUUID: "uuid3"}),
interfacestore.NewTrafficControlInterface("antrea-tap2",
&interfacestore.OVSPortConfig{OFPort: -1, PortUUID: "uuid3"}),
},
expectedOVSCtlCalls: func(client *ovsctltest.MockOVSCtlClientMockRecorder) {
client.SetPortNoFlood(11).Return(nil)
client.SetPortNoFlood(13).Return(nil)
},
},
{
name: "fail",
existingInterfaces: []*interfacestore.InterfaceConfig{
interfacestore.NewTrafficControlInterface("antrea-tap1",
&interfacestore.OVSPortConfig{OFPort: 10, PortUUID: "uuid3"}),
},
expectedOVSCtlCalls: func(client *ovsctltest.MockOVSCtlClientMockRecorder) {
client.SetPortNoFlood(10).Return(fmt.Errorf("server unavailable"))
},
expectedErr: "failed to set no-flood for port antrea-tap1: server unavailable",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
controller := mock.NewController(t)
defer controller.Finish()
mockOVSCtlClient := ovsctltest.NewMockOVSCtlClient(controller)
ifaceStore := interfacestore.NewInterfaceStore()
initializer := &Initializer{
ifaceStore: ifaceStore,
ovsCtlClient: mockOVSCtlClient,
}
ifaceStore.Initialize(tt.existingInterfaces)
tt.expectedOVSCtlCalls(mockOVSCtlClient.EXPECT())
err := initializer.restorePortConfigs()
if tt.expectedErr == "" {
assert.NoError(t, err)
} else {
assert.ErrorContains(t, err, tt.expectedErr)
}
})
}
}
3 changes: 1 addition & 2 deletions pkg/agent/controller/trafficcontrol/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -762,8 +762,7 @@ func (c *Controller) getOrCreateTrafficControlPort(port *v1alpha2.TrafficControl
return 0, err
}
}
itf := interfacestore.NewTrafficControlInterface(portName)
itf.OVSPortConfig = &interfacestore.OVSPortConfig{PortUUID: portUUID, OFPort: ofPort}
itf := interfacestore.NewTrafficControlInterface(portName, &interfacestore.OVSPortConfig{PortUUID: portUUID, OFPort: ofPort})
c.interfaceStore.AddInterface(itf)
// Create binding for the newly created port.
c.portToTCBindings[portName] = &portToTCBinding{
Expand Down
11 changes: 0 additions & 11 deletions pkg/agent/interfacestore/interface_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ func TestNewInterfaceStore(t *testing.T) {
t.Run("testGatewayInterface", testGatewayInterface)
t.Run("testTunnelInterface", testTunnelInterface)
t.Run("testUplinkInterface", testUplinkInterface)
t.Run("testTrafficControlInterface", testTrafficControlInterface)
t.Run("testExternalEntityInterface", testEntityInterface)
}

Expand Down Expand Up @@ -164,16 +163,6 @@ func testUplinkInterface(t *testing.T) {
testGeneralInterface(t, uplinkInterface, UplinkInterface)
}

func testTrafficControlInterface(t *testing.T) {
tcInterface := NewTrafficControlInterface("tc0")
tcInterface.IPs = []net.IP{hostIP}
tcInterface.OVSPortConfig = &OVSPortConfig{
OFPort: 17,
PortUUID: "1234567890",
}
testGeneralInterface(t, tcInterface, TrafficControlInterface)
}

func testEntityInterface(t *testing.T) {
store := NewInterfaceStore()
portConfig := &OVSPortConfig{OFPort: 18, PortUUID: "123456789"}
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/interfacestore/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ func NewUplinkInterface(uplinkName string) *InterfaceConfig {
return uplinkConfig
}

func NewTrafficControlInterface(interfaceName string) *InterfaceConfig {
trafficControlConfig := &InterfaceConfig{InterfaceName: interfaceName, Type: TrafficControlInterface}
func NewTrafficControlInterface(interfaceName string, ovsPortConfig *OVSPortConfig) *InterfaceConfig {
trafficControlConfig := &InterfaceConfig{InterfaceName: interfaceName, Type: TrafficControlInterface, OVSPortConfig: ovsPortConfig}
return trafficControlConfig
}

Expand Down