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 648c4bc
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 78 deletions.
109 changes: 73 additions & 36 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,50 +226,87 @@ func (i *Initializer) initInterfaceStore() error {
return err
}

parseGatewayIFFunc := func(port *ovsconfig.OVSPortData, ovsPort *interfacestore.OVSPortConfig) *interfacestore.InterfaceConfig {
intf := &interfacestore.InterfaceConfig{
Type: interfacestore.GatewayInterface,
InterfaceName: port.Name,
OVSPortConfig: ovsPort}
if intf.InterfaceName != i.hostGateway {
klog.Warningf("The discovered gateway interface name %s is different from the configured value: %s",
intf.InterfaceName, i.hostGateway)
// Set the gateway interface name to the discovered name.
i.hostGateway = intf.InterfaceName
}
return intf
}
parseUplinkIFFunc := func(port *ovsconfig.OVSPortData, ovsPort *interfacestore.OVSPortConfig) *interfacestore.InterfaceConfig {
return &interfacestore.InterfaceConfig{
Type: interfacestore.UplinkInterface,
InterfaceName: port.Name,
OVSPortConfig: ovsPort,
}
}
parseTunnelIFFunc := func(port *ovsconfig.OVSPortData, ovsPort *interfacestore.OVSPortConfig) *interfacestore.InterfaceConfig {
intf := noderoute.ParseTunnelInterfaceConfig(port, ovsPort)
if intf != nil && port.OFPort == config.DefaultTunOFPort &&
intf.InterfaceName != i.nodeConfig.DefaultTunName {
klog.Infof("The discovered default tunnel interface name %s is different from the default value: %s",
intf.InterfaceName, i.nodeConfig.DefaultTunName)
// Set the default tunnel interface name to the discovered name.
i.nodeConfig.DefaultTunName = intf.InterfaceName
}
return intf
}
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:
intf = &interfacestore.InterfaceConfig{
Type: interfacestore.GatewayInterface,
InterfaceName: port.Name,
OVSPortConfig: ovsPort}
if intf.InterfaceName != i.hostGateway {
klog.Warningf("The discovered gateway interface name %s is different from the configured value: %s",
intf.InterfaceName, i.hostGateway)
// Set the gateway interface name to the discovered name.
i.hostGateway = intf.InterfaceName
if port.AntreaIFType != ovsconfig.AntreaUnSet {
switch port.AntreaIFType {
case ovsconfig.AntreaGateway:
intf = parseGatewayIFFunc(port, ovsPort)
case ovsconfig.AntreaUplink:
intf = parseUplinkIFFunc(port, ovsPort)
case ovsconfig.AntreaTunnel:
intf = parseTunnelIFFunc(port, ovsPort)
case ovsconfig.AntreaHostIF:
// Not load the host interface.
intf = nil
default:
// The port should be for a container interface.
intf = cniserver.ParseOVSPortInterfaceConfig(port, ovsPort, true)
}
case port.Name == uplinkIfName:
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:
intf = noderoute.ParseTunnelInterfaceConfig(port, ovsPort)
if intf != nil && port.OFPort == config.DefaultTunOFPort &&
intf.InterfaceName != i.nodeConfig.DefaultTunName {
klog.Infof("The discovered default tunnel interface name %s is different from the default value: %s",
intf.InterfaceName, i.nodeConfig.DefaultTunName)
// Set the default tunnel interface name to the discovered name.
i.nodeConfig.DefaultTunName = intf.InterfaceName
} else {
// Compatible with the original workflow to init the interfaceStore. It is used for the upgrade case.
uplinkIfName := i.nodeConfig.UplinkNetConfig.Name
var antreaIFType string
switch {
case port.OFPort == config.HostGatewayOFPort:
intf = parseGatewayIFFunc(port, ovsPort)
antreaIFType = ovsconfig.AntreaGateway
case port.Name == uplinkIfName:
intf = parseUplinkIFFunc(port, ovsPort)
antreaIFType = ovsconfig.AntreaUplink
case port.IFType == ovsconfig.GeneveTunnel:
fallthrough
case port.IFType == ovsconfig.VXLANTunnel:
fallthrough
case port.IFType == ovsconfig.GRETunnel:
fallthrough
case port.IFType == ovsconfig.STTTunnel:
intf = parseTunnelIFFunc(port, ovsPort)
antreaIFType = ovsconfig.AntreaTunnel
case port.Name == i.ovsBridge:
intf = nil
default:
// The port should be for a container interface.
intf = cniserver.ParseOVSPortInterfaceConfig(port, ovsPort, true)
antreaIFType = ovsconfig.AntreaContainer
}
default:
// The port should be for a container interface.
intf = cniserver.ParseOVSPortInterfaceConfig(port, ovsPort, true)
i.ovsBridgeClient.SetAntreaInterfaceType(port.Name, antreaIFType)
}
if intf != nil {
ifaceList = append(ifaceList, intf)
Expand Down Expand Up @@ -556,7 +593,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
2 changes: 2 additions & 0 deletions pkg/agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ func TestInitstore(t *testing.T) {
}

mockOVSBridgeClient.EXPECT().GetPortList().Return(initOVSPorts, nil)
mockOVSBridgeClient.EXPECT().SetAntreaInterfaceType(ovsPort1.Name, ovsconfig.AntreaContainer).Return(nil)
mockOVSBridgeClient.EXPECT().SetAntreaInterfaceType(ovsPort2.Name, ovsconfig.AntreaContainer).Return(nil)
initializer.initInterfaceStore()
if store.Len() != 2 {
t.Errorf("Failed to load OVS port in store")
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
5 changes: 3 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 All @@ -54,4 +54,5 @@ type OVSBridgeClient interface {
GetBridgeName() string
IsHardwareOffloadEnabled() bool
GetOVSDatapathType() OVSDatapathType
SetAntreaInterfaceType(ifName, antreaIFType string) Error
}
62 changes: 48 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,14 @@ const (
// Maximum allowed value of ofPortRequest.
ofPortRequestMax = 65279
hardwareOffload = "hw-offload"

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

// NewOVSDBConnectionUDS connects to the OVSDB server on the UNIX domain socket
Expand Down Expand Up @@ -361,11 +371,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 +446,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 +518,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 +547,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 +651,11 @@ func buildPortDataCommon(port, intf map[string]interface{}, portData *OVSPortDat
} else { // ofport not assigned by OVS yet
portData.OFPort = 0
}
var ok bool
portData.AntreaIFType, ok = buildMapFromOVSDBMap(intf["external_ids"].([]interface{}))[AntreaIFTypeKey]
if !ok {
portData.AntreaIFType = AntreaUnSet
}
}

// GetPortData retrieves port data given the OVS port UUID and interface name.
Expand All @@ -655,7 +671,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 +724,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 Expand Up @@ -879,3 +895,21 @@ func (br *OVSBridge) getHardwareOffload() (bool, Error) {
func (br *OVSBridge) GetOVSDatapathType() OVSDatapathType {
return br.datapathType
}

func (br *OVSBridge) SetAntreaInterfaceType(ifName, antreaIFType string) Error {
tx := br.ovsdb.Transaction(openvSwitchSchema)
externalIDsMap := map[string]interface{}{AntreaIFTypeKey: antreaIFType}
tx.Update(dbtransaction.Update{
Table: "Interface",
Where: [][]interface{}{{"name", "==", ifName}},
Row: map[string]interface{}{
"external_ids": helpers.MakeOVSDBMap(externalIDsMap),
},
})
_, err, temporary := tx.Commit()
if err != nil {
klog.Error("Transaction failed", err)
return NewTransactionError(err, temporary)
}
return nil
}
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"`
}
Loading

0 comments on commit 648c4bc

Please sign in to comment.