Skip to content

Commit

Permalink
Use OVS Interface external_ids to save Antrea Interface type
Browse files Browse the repository at this point in the history
Introduce Antrea Interface Type to map the OVS port to Antrea created
interfaces, and use OVS Interface external_ids field to save the
configuration. This type is helpful for Antrea to define more inteface
types.

Signed-off-by: wenyingd <[email protected]>
  • Loading branch information
wenyingd committed Nov 15, 2021
1 parent 07b8168 commit 5e69e3c
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 54 deletions.
20 changes: 8 additions & 12 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,14 @@ func (i *Initializer) initInterfaceStore() error {
}

ifaceList := make([]*interfacestore.InterfaceConfig, 0, len(ovsPorts))
uplinkIfName := i.nodeConfig.UplinkNetConfig.Name
for index := range ovsPorts {
port := &ovsPorts[index]
ovsPort := &interfacestore.OVSPortConfig{
PortUUID: port.UUID,
OFPort: port.OFPort}
var intf *interfacestore.InterfaceConfig
switch {
case port.OFPort == config.HostGatewayOFPort:
switch port.AntreaIFType {
case ovsconfig.AntreaGateway:
intf = &interfacestore.InterfaceConfig{
Type: interfacestore.GatewayInterface,
InterfaceName: port.Name,
Expand All @@ -246,19 +245,13 @@ func (i *Initializer) initInterfaceStore() error {
// Set the gateway interface name to the discovered name.
i.hostGateway = intf.InterfaceName
}
case port.Name == uplinkIfName:
case ovsconfig.AntreaUplink:
intf = &interfacestore.InterfaceConfig{
Type: interfacestore.UplinkInterface,
InterfaceName: port.Name,
OVSPortConfig: ovsPort,
}
case port.IFType == ovsconfig.GeneveTunnel:
fallthrough
case port.IFType == ovsconfig.VXLANTunnel:
fallthrough
case port.IFType == ovsconfig.GRETunnel:
fallthrough
case port.IFType == ovsconfig.STTTunnel:
case ovsconfig.AntreaTunnel:
intf = noderoute.ParseTunnelInterfaceConfig(port, ovsPort)
if intf != nil && port.OFPort == config.DefaultTunOFPort &&
intf.InterfaceName != i.nodeConfig.DefaultTunName {
Expand All @@ -267,6 +260,9 @@ func (i *Initializer) initInterfaceStore() error {
// Set the default tunnel interface name to the discovered name.
i.nodeConfig.DefaultTunName = intf.InterfaceName
}
case ovsconfig.AntreaHostIF:
// Not load the host interface.
continue
default:
// The port should be for a container interface.
intf = cniserver.ParseOVSPortInterfaceConfig(port, ovsPort, true)
Expand Down Expand Up @@ -556,7 +552,7 @@ func (i *Initializer) setupGatewayInterface() error {
gatewayIface, portExists := i.ifaceStore.GetInterface(i.hostGateway)
if !portExists {
klog.V(2).Infof("Creating gateway port %s on OVS bridge", i.hostGateway)
gwPortUUID, err := i.ovsBridgeClient.CreateInternalPort(i.hostGateway, config.HostGatewayOFPort, nil)
gwPortUUID, err := i.ovsBridgeClient.CreateInternalPort(i.hostGateway, config.HostGatewayOFPort, ovsconfig.AntreaGateway, nil)
if err != nil {
klog.Errorf("Failed to create gateway port %s on OVS bridge: %v", i.hostGateway, err)
return err
Expand Down
2 changes: 1 addition & 1 deletion pkg/agent/agent_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (i *Initializer) prepareOVSBridge() error {
} else {
// OVS does not receive "ofport_request" param when creating local port, so here use config.AutoAssignedOFPort=0
// to ignore this param.
if _, err = i.ovsBridgeClient.CreateInternalPort(brName, config.AutoAssignedOFPort, nil); err != nil {
if _, err = i.ovsBridgeClient.CreateInternalPort(brName, config.AutoAssignedOFPort, ovsconfig.AntreaHostIF, nil); err != nil {
return err
}
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/agent/agent_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"antrea.io/antrea/pkg/agent/config"
"antrea.io/antrea/pkg/agent/interfacestore"
"antrea.io/antrea/pkg/agent/util"
"antrea.io/antrea/pkg/ovs/ovsconfig"
"antrea.io/antrea/pkg/ovs/ovsctl"
"antrea.io/antrea/pkg/util/ip"
)
Expand Down Expand Up @@ -144,7 +145,7 @@ func (i *Initializer) prepareOVSBridge() error {
} else {
// OVS does not receive "ofport_request" param when creating local port, so here use config.AutoAssignedOFPort=0
// to ignore this param.
if _, err = i.ovsBridgeClient.CreateInternalPort(brName, config.AutoAssignedOFPort, nil); err != nil {
if _, err = i.ovsBridgeClient.CreateInternalPort(brName, config.AutoAssignedOFPort, ovsconfig.AntreaHostIF, nil); err != nil {
return err
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/cniserver/pod_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ func (pc *podConfigurator) createOVSPort(ovsPortName string, ovsAttachInfo map[s
var err error
switch pc.ifConfigurator.getOVSInterfaceType() {
case internalOVSInterfaceType:
portUUID, err = pc.ovsBridgeClient.CreateInternalPort(ovsPortName, 0, ovsAttachInfo)
portUUID, err = pc.ovsBridgeClient.CreateInternalPort(ovsPortName, 0, ovsconfig.AntreaContainer, ovsAttachInfo)
default:
portUUID, err = pc.ovsBridgeClient.CreatePort(ovsPortName, ovsPortName, ovsAttachInfo)
portUUID, err = pc.ovsBridgeClient.CreatePort(ovsPortName, ovsPortName, ovsconfig.AntreaContainer, ovsAttachInfo)
}
if err != nil {
klog.Errorf("Failed to add OVS port %s, remove from local cache: %v", ovsPortName, err)
Expand Down
4 changes: 2 additions & 2 deletions pkg/ovs/ovsconfig/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ type OVSBridgeClient interface {
SetDatapathID(datapathID string) Error
GetInterfaceOptions(name string) (map[string]string, Error)
SetInterfaceOptions(name string, options map[string]interface{}) Error
CreatePort(name, ifDev string, externalIDs map[string]interface{}) (string, Error)
CreateInternalPort(name string, ofPortRequest int32, externalIDs map[string]interface{}) (string, Error)
CreatePort(name, ifDev string, antreaType string, externalIDs map[string]interface{}) (string, Error)
CreateInternalPort(name string, ofPortRequest int32, antreaType string, externalIDs map[string]interface{}) (string, Error)
CreateTunnelPort(name string, tunnelType TunnelType, ofPortRequest int32) (string, Error)
CreateTunnelPortExt(name string, tunnelType TunnelType, ofPortRequest int32, csum bool, localIP string, remoteIP string, psk string, externalIDs map[string]interface{}) (string, Error)
CreateUplinkPort(name string, ofPortRequest int32, externalIDs map[string]interface{}) (string, Error)
Expand Down
39 changes: 25 additions & 14 deletions pkg/ovs/ovsconfig/ovs_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ type OVSPortData struct {
UUID string
Name string
// Interface type.
IFType string
IFName string
OFPort int32
ExternalIDs map[string]string
Options map[string]string
IFType string
// The interface type defined by Antrea, which is saved in Interface external_ids.
AntreaIFType string
IFName string
OFPort int32
ExternalIDs map[string]string
Options map[string]string
}

const (
Expand All @@ -56,6 +58,13 @@ const (
// Maximum allowed value of ofPortRequest.
ofPortRequestMax = 65279
hardwareOffload = "hw-offload"

AntreaIFTypeKey = "antrea-type"
AntreaGateway = "gateway"
AntreaContainer = "container"
AntreaTunnel = "tunnel"
AntreaUplink = "uplink"
AntreaHostIF = "hostLink"
)

// NewOVSDBConnectionUDS connects to the OVSDB server on the UNIX domain socket
Expand Down Expand Up @@ -361,11 +370,11 @@ func (br *OVSBridge) DeletePort(portUUID string) Error {
// If externalIDs is not empty, the map key/value pairs will be set to the
// port's external_ids.
// If ofPortRequest is not zero, it will be passed to the OVS port creation.
func (br *OVSBridge) CreateInternalPort(name string, ofPortRequest int32, externalIDs map[string]interface{}) (string, Error) {
func (br *OVSBridge) CreateInternalPort(name string, ofPortRequest int32, antreaType string, externalIDs map[string]interface{}) (string, Error) {
if ofPortRequest < 0 || ofPortRequest > ofPortRequestMax {
return "", newInvalidArgumentsError(fmt.Sprint("invalid ofPortRequest value: ", ofPortRequest))
}
return br.createPort(name, name, "internal", ofPortRequest, externalIDs, nil)
return br.createPort(name, name, "internal", antreaType, ofPortRequest, externalIDs, nil)
}

// CreateTunnelPort creates a tunnel port with the specified name and type on
Expand Down Expand Up @@ -436,7 +445,7 @@ func (br *OVSBridge) createTunnelPort(
options["csum"] = "true"
}

return br.createPort(name, name, string(tunnelType), ofPortRequest, externalIDs, options)
return br.createPort(name, name, string(tunnelType), AntreaTunnel, ofPortRequest, externalIDs, options)
}

// GetInterfaceOptions returns the options of the provided interface.
Expand Down Expand Up @@ -508,18 +517,18 @@ func ParseTunnelInterfaceOptions(portData *OVSPortData) (net.IP, net.IP, string,

// CreateUplinkPort creates uplink port.
func (br *OVSBridge) CreateUplinkPort(name string, ofPortRequest int32, externalIDs map[string]interface{}) (string, Error) {
return br.createPort(name, name, "", ofPortRequest, externalIDs, nil)
return br.createPort(name, name, "", AntreaUplink, ofPortRequest, externalIDs, nil)
}

// CreatePort creates a port with the specified name on the bridge, and connects
// the interface specified by ifDev to the port.
// If externalIDs is not empty, the map key/value pairs will be set to the
// port's external_ids.
func (br *OVSBridge) CreatePort(name, ifDev string, externalIDs map[string]interface{}) (string, Error) {
return br.createPort(name, ifDev, "", 0, externalIDs, nil)
func (br *OVSBridge) CreatePort(name, ifDev string, antreaType string, externalIDs map[string]interface{}) (string, Error) {
return br.createPort(name, ifDev, "", antreaType, 0, externalIDs, nil)
}

func (br *OVSBridge) createPort(name, ifName, ifType string, ofPortRequest int32, externalIDs, options map[string]interface{}) (string, Error) {
func (br *OVSBridge) createPort(name, ifName, ifType string, antreaType string, ofPortRequest int32, externalIDs, options map[string]interface{}) (string, Error) {
var externalIDMap []interface{}
var optionMap []interface{}

Expand All @@ -537,6 +546,7 @@ func (br *OVSBridge) createPort(name, ifName, ifType string, ofPortRequest int32
Type: ifType,
OFPortRequest: ofPortRequest,
Options: optionMap,
ExternalIDs: helpers.MakeOVSDBMap(map[string]interface{}{AntreaIFTypeKey: antreaType}),
}
ifNamedUUID := tx.Insert(dbtransaction.Insert{
Table: "Interface",
Expand Down Expand Up @@ -640,6 +650,7 @@ func buildPortDataCommon(port, intf map[string]interface{}, portData *OVSPortDat
} else { // ofport not assigned by OVS yet
portData.OFPort = 0
}
portData.AntreaIFType = buildMapFromOVSDBMap(intf["external_ids"].([]interface{}))[AntreaIFTypeKey]
}

// GetPortData retrieves port data given the OVS port UUID and interface name.
Expand All @@ -655,7 +666,7 @@ func (br *OVSBridge) GetPortData(portUUID, ifName string) (*OVSPortData, Error)
})
tx.Select(dbtransaction.Select{
Table: "Interface",
Columns: []string{"_uuid", "type", "ofport", "options"},
Columns: []string{"_uuid", "type", "ofport", "options", "external_ids"},
Where: [][]interface{}{{"name", "==", ifName}},
})

Expand Down Expand Up @@ -708,7 +719,7 @@ func (br *OVSBridge) GetPortList() ([]OVSPortData, Error) {
})
tx.Select(dbtransaction.Select{
Table: "Interface",
Columns: []string{"_uuid", "type", "name", "ofport", "options"},
Columns: []string{"_uuid", "type", "name", "ofport", "options", "external_ids"},
})

res, err, temporary := tx.Commit()
Expand Down
1 change: 1 addition & 0 deletions pkg/ovs/ovsconfig/ovs_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ type Interface struct {
Type string `json:"type,omitempty"`
OFPortRequest int32 `json:"ofport_request,omitempty"`
Options []interface{} `json:"options,omitempty"`
ExternalIDs []interface{} `json:"external_ids,omitempty"`
}
16 changes: 8 additions & 8 deletions pkg/ovs/ovsconfig/testing/mock_ovsconfig.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions test/integration/agent/cniserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ func cmdAddDelCheckTest(testNS ns.NetNS, tc testCase, dataDir string) {
// Mock ovs output while get ovs port external configuration
ovsPortname := util.GenerateContainerInterfaceName(testPod, testPodNamespace, ContainerID)
ovsPortUUID := uuid.New().String()
ovsServiceMock.EXPECT().CreatePort(ovsPortname, ovsPortname, mock.Any()).Return(ovsPortUUID, nil).AnyTimes()
ovsServiceMock.EXPECT().CreatePort(ovsPortname, ovsPortname, mock.Any(), mock.Any()).Return(ovsPortUUID, nil).AnyTimes()
ovsServiceMock.EXPECT().GetOFPort(ovsPortname).Return(int32(10), nil).AnyTimes()
ofServiceMock.EXPECT().InstallPodFlows(ovsPortname, mock.Any(), mock.Any(), mock.Any()).Return(nil)

Expand Down Expand Up @@ -826,7 +826,7 @@ func TestCNIServerChaining(t *testing.T) {
// Pod port expectations
orderedCalls = append(orderedCalls,
routeMock.EXPECT().MigrateRoutesToGw(hostVeth.Name),
ovsServiceMock.EXPECT().CreatePort(ovsPortname, ovsPortname, mock.Any()).Return(ovsPortUUID, nil),
ovsServiceMock.EXPECT().CreatePort(ovsPortname, ovsPortname, mock.Any(), mock.Any()).Return(ovsPortUUID, nil),
ovsServiceMock.EXPECT().GetOFPort(ovsPortname).Return(testContainerOFPort, nil),
ofServiceMock.EXPECT().InstallPodFlows(ovsPortname, []net.IP{podIP}, containerIntf.HardwareAddr, mock.Any()),
)
Expand Down
28 changes: 16 additions & 12 deletions test/integration/ovs/ovs_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ func TestOVSBridge(t *testing.T) {
deleteAllPorts(t, data.br)
checkPorts(0)

uuid1 := testCreatePort(t, data.br, "p1", "internal")
uuid2 := testCreatePort(t, data.br, "p2", "")
uuid3 := testCreatePort(t, data.br, "p3", "vxlan")
uuid4 := testCreatePort(t, data.br, "p4", "geneve")
uuid1 := testCreatePort(t, data.br, "p1", "internal", ovsconfig.AntreaContainer)
uuid2 := testCreatePort(t, data.br, "p2", "", ovsconfig.AntreaGateway)
uuid3 := testCreatePort(t, data.br, "p3", "vxlan", "")
uuid4 := testCreatePort(t, data.br, "p4", "geneve", "")

checkPorts(4)

Expand All @@ -127,10 +127,10 @@ func TestOVSBridge(t *testing.T) {

checkPorts(0)

testCreatePort(t, data.br, "p1", "internal")
testCreatePort(t, data.br, "p2", "")
testCreatePort(t, data.br, "p3", "vxlan")
testCreatePort(t, data.br, "p4", "geneve")
testCreatePort(t, data.br, "p1", "internal", ovsconfig.AntreaContainer)
testCreatePort(t, data.br, "p2", "", ovsconfig.AntreaGateway)
testCreatePort(t, data.br, "p3", "vxlan", "")
testCreatePort(t, data.br, "p4", "geneve", "")

checkPorts(4)

Expand All @@ -148,7 +148,7 @@ func TestOVSDeletePortIdempotent(t *testing.T) {

deleteAllPorts(t, data.br)

uuid := testCreatePort(t, data.br, "p1", "internal")
uuid := testCreatePort(t, data.br, "p1", "internal", ovsconfig.AntreaContainer)
testDeletePort(t, data.br, uuid)
testDeletePort(t, data.br, uuid)
}
Expand Down Expand Up @@ -269,7 +269,7 @@ func deleteAllPorts(t *testing.T, br *ovsconfig.OVSBridge) {

var ofPortRequest int32 = 1

func testCreatePort(t *testing.T, br *ovsconfig.OVSBridge, name string, ifType string) string {
func testCreatePort(t *testing.T, br *ovsconfig.OVSBridge, name string, ifType string, antreaIFType string) string {
var err error
var uuid string
var externalIDs map[string]interface{}
Expand All @@ -278,10 +278,10 @@ func testCreatePort(t *testing.T, br *ovsconfig.OVSBridge, name string, ifType s
switch ifType {
case "":
externalIDs = map[string]interface{}{"k1": "v1", "k2": "v2"}
uuid, err = br.CreatePort(name, name, externalIDs)
uuid, err = br.CreatePort(name, name, antreaIFType, externalIDs)
case "internal":
externalIDs = map[string]interface{}{"k1": "v1", "k2": "v2"}
uuid, err = br.CreateInternalPort(name, ofPortRequest, externalIDs)
uuid, err = br.CreateInternalPort(name, ofPortRequest, antreaIFType, externalIDs)
case "vxlan":
externalIDs = map[string]interface{}{}
uuid, err = br.CreateTunnelPort(name, ovsconfig.VXLANTunnel, ofPortRequest)
Expand Down Expand Up @@ -310,6 +310,10 @@ func testCreatePort(t *testing.T, br *ovsconfig.OVSBridge, name string, ifType s
if ifType != "" {
assert.Equal(t, ofPort, port.OFPort)
}
if antreaIFType == "" {
antreaIFType = ovsconfig.AntreaTunnel
}
assert.Equal(t, antreaIFType, port.AntreaIFType)

for k, v := range externalIDs {
rv, ok := port.ExternalIDs[k]
Expand Down

0 comments on commit 5e69e3c

Please sign in to comment.