Пример #1
0
// DeleteEndpoint deletes an endpoint by named identifier.
func (d *OvsDriver) DeleteEndpoint(id string) (err error) {

	epOper := OvsOperEndpointState{}
	epOper.StateDriver = d.oper.StateDriver
	err = epOper.Read(id)
	if err != nil {
		return err
	}
	defer func() {
		epOper.Clear()
	}()

	// Get the network state
	cfgNw := mastercfg.CfgNetworkState{}
	cfgNw.StateDriver = d.oper.StateDriver
	err = cfgNw.Read(epOper.NetID)
	if err != nil {
		return err
	}

	// Find the switch based on network type
	var sw *OvsSwitch
	if cfgNw.PktTagType == "vxlan" {
		sw = d.switchDb["vxlan"]
	} else {
		sw = d.switchDb["vlan"]
	}

	err = sw.DeletePort(&epOper)
	if err != nil {
		log.Errorf("Error deleting endpoint: %+v. Err: %v", epOper, err)
	}

	return nil
}
Пример #2
0
func handleNetworkEvents(netPlugin *plugin.NetPlugin, opts core.InstanceInfo, retErr chan error) {
	rsps := make(chan core.WatchState)
	go processStateEvent(netPlugin, opts, rsps)
	cfg := mastercfg.CfgNetworkState{}
	cfg.StateDriver = netPlugin.StateDriver
	retErr <- cfg.WatchAll(rsps)
	log.Errorf("Error from handleNetworkEvents")
}
Пример #3
0
func handleNetworkEvents(netPlugin *plugin.NetPlugin, opts cliOpts, retErr chan error) {
	rsps := make(chan core.WatchState)
	go processStateEvent(netPlugin, opts, rsps)
	cfg := mastercfg.CfgNetworkState{}
	cfg.StateDriver = netPlugin.StateDriver
	retErr <- cfg.WatchAll(rsps)
	return
}
Пример #4
0
// Allocate an address from the network
func networkAllocAddress(nwCfg *mastercfg.CfgNetworkState, reqAddr string) (string, error) {
	var ipAddress string
	var ipAddrValue uint
	var found bool
	var err error

	// alloc address
	if reqAddr == "" {
		ipAddrValue, found = nwCfg.IPAllocMap.NextClear(0)
		if !found {
			log.Errorf("auto allocation failed - address exhaustion in subnet %s/%d",
				nwCfg.SubnetIP, nwCfg.SubnetLen)
			err = core.Errorf("auto allocation failed - address exhaustion in subnet %s/%d",
				nwCfg.SubnetIP, nwCfg.SubnetLen)
			return "", err
		}

		ipAddress, err = netutils.GetSubnetIP(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddrValue)
		if err != nil {
			log.Errorf("create eps: error acquiring subnet ip. Error: %s", err)
			return "", err
		}

		// Docker, Mesos issue a Alloc Address first, followed by a CreateEndpoint
		// Kubernetes issues a create endpoint directly
		// since networkAllocAddress is called from both AllocAddressHandler and CreateEndpointHandler,
		// we need to make sure that the EpCount is incremented only when we are allocating
		// a new IP. In case of Docker, Mesos CreateEndPoint will already request a IP that
		// allocateAddress had allocated in the earlier call.
		nwCfg.EpAddrCount++

	} else if reqAddr != "" && nwCfg.SubnetIP != "" {
		ipAddrValue, err = netutils.GetIPNumber(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, reqAddr)
		if err != nil {
			log.Errorf("create eps: error getting host id from hostIP %s Subnet %s/%d. Error: %s",
				reqAddr, nwCfg.SubnetIP, nwCfg.SubnetLen, err)
			return "", err
		}

		ipAddress = reqAddr
	}

	// Set the bitmap
	nwCfg.IPAllocMap.Set(ipAddrValue)

	err = nwCfg.Write()
	if err != nil {
		log.Errorf("error writing nw config. Error: %s", err)
		return "", err
	}

	return ipAddress, nil
}
Пример #5
0
// CreateEndpoint creates an endpoint
func CreateEndpoint(stateDriver core.StateDriver, nwCfg *mastercfg.CfgNetworkState,
	ep *intent.ConfigEP) (*mastercfg.CfgEndpointState, error) {
	epCfg := &mastercfg.CfgEndpointState{}
	epCfg.StateDriver = stateDriver
	epCfg.ID = getEpName(nwCfg.ID, ep)
	err := epCfg.Read(epCfg.ID)
	if err == nil {
		// TODO: check for diffs and possible updates
		return epCfg, nil
	}

	epCfg.NetID = nwCfg.ID
	epCfg.ContName = ep.Container
	epCfg.AttachUUID = ep.AttachUUID
	epCfg.HomingHost = ep.Host
	epCfg.ServiceName = ep.ServiceName

	// Allocate addresses
	err = allocSetEpAddress(ep, epCfg, nwCfg)
	if err != nil {
		log.Errorf("error allocating and/or reserving IP. Error: %s", err)
		return nil, err
	}

	// Set endpoint group
	// Skip for infra nw
	if nwCfg.NwType != "infra" {
		epCfg.EndpointGroupKey = mastercfg.GetEndpointGroupKey(ep.ServiceName, nwCfg.Tenant)
		epCfg.EndpointGroupID, err = mastercfg.GetEndpointGroupID(stateDriver, ep.ServiceName, nwCfg.Tenant)
		if err != nil {
			log.Errorf("Error getting endpoint group for %s.%s. Err: %v", ep.ServiceName, nwCfg.ID, err)
			return nil, err
		}
	}

	err = nwCfg.IncrEpCount()
	if err != nil {
		log.Errorf("Error incrementing ep count. Err: %v", err)
		return nil, err
	}

	err = epCfg.Write()
	if err != nil {
		log.Errorf("error writing ep config. Error: %s", err)
		return nil, err
	}

	return epCfg, nil
}
Пример #6
0
// Allocate an address from the network
func networkAllocAddress(nwCfg *mastercfg.CfgNetworkState, reqAddr string) (string, error) {
	var ipAddress string
	var ipAddrValue uint
	var found bool
	var err error

	// alloc address
	if reqAddr == "" {
		ipAddrValue, found = nwCfg.IPAllocMap.NextClear(0)
		if !found {
			log.Errorf("auto allocation failed - address exhaustion in subnet %s/%d",
				nwCfg.SubnetIP, nwCfg.SubnetLen)
			err = core.Errorf("auto allocation failed - address exhaustion in subnet %s/%d",
				nwCfg.SubnetIP, nwCfg.SubnetLen)
			return "", err
		}

		ipAddress, err = netutils.GetSubnetIP(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddrValue)
		if err != nil {
			log.Errorf("create eps: error acquiring subnet ip. Error: %s", err)
			return "", err
		}
	} else if reqAddr != "" && nwCfg.SubnetIP != "" {
		ipAddrValue, err = netutils.GetIPNumber(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, reqAddr)
		if err != nil {
			log.Errorf("create eps: error getting host id from hostIP %s Subnet %s/%d. Error: %s",
				reqAddr, nwCfg.SubnetIP, nwCfg.SubnetLen, err)
			return "", err
		}

		ipAddress = reqAddr
	}

	// Set the bitmap
	nwCfg.IPAllocMap.Set(ipAddrValue)

	err = nwCfg.Write()
	if err != nil {
		log.Errorf("error writing nw config. Error: %s", err)
		return "", err
	}

	return ipAddress, nil
}
Пример #7
0
// XXX: This function should be returning logical state instead of driver state
func (d *daemon) networks(id string) ([]core.State, error) {
	var (
		err error
		nw  *mastercfg.CfgNetworkState
	)

	nw = &mastercfg.CfgNetworkState{}
	if nw.StateDriver, err = utils.GetStateDriver(); err != nil {
		return nil, err
	}

	if id == "all" {
		return nw.ReadAll()
	} else if err := nw.Read(id); err == nil {
		return []core.State{core.State(nw)}, nil
	}

	return nil, core.Errorf("Unexpected code path")
}
Пример #8
0
// CreateNetwork creates a network by named identifier
func (d *OvsDriver) CreateNetwork(id string) error {
	cfgNw := mastercfg.CfgNetworkState{}
	cfgNw.StateDriver = d.oper.StateDriver
	err := cfgNw.Read(id)
	if err != nil {
		log.Errorf("Failed to read net %s \n", cfgNw.ID)
		return err
	}
	log.Infof("create net %+v \n", cfgNw)

	// Find the switch based on network type
	var sw *OvsSwitch
	if cfgNw.PktTagType == "vxlan" {
		sw = d.switchDb["vxlan"]
	} else {
		sw = d.switchDb["vlan"]
	}

	return sw.CreateNetwork(uint16(cfgNw.PktTag), uint32(cfgNw.ExtPktTag), cfgNw.Gateway, cfgNw.Tenant)
}
Пример #9
0
// networkReleaseAddress release the ip address
func networkReleaseAddress(nwCfg *mastercfg.CfgNetworkState, ipAddress string) error {
	isIPv6 := netutils.IsIPv6(ipAddress)
	if isIPv6 {
		hostID, err := netutils.GetIPv6HostID(nwCfg.SubnetIP, nwCfg.SubnetLen, ipAddress)
		if err != nil {
			log.Errorf("error getting host id from hostIP %s Subnet %s/%d. Error: %s",
				ipAddress, nwCfg.SubnetIP, nwCfg.SubnetLen, err)
			return err
		}
		// networkReleaseAddress is called from multiple places
		// Make sure we decrement the EpCount only if the IPAddress
		// was not already freed earlier
		if _, found := nwCfg.IPv6AllocMap[hostID]; found {
			nwCfg.EpAddrCount--
		}
		delete(nwCfg.IPv6AllocMap, hostID)
	} else {
		ipAddrValue, err := netutils.GetIPNumber(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddress)
		if err != nil {
			log.Errorf("error getting host id from hostIP %s Subnet %s/%d. Error: %s",
				ipAddress, nwCfg.SubnetIP, nwCfg.SubnetLen, err)
			return err
		}
		// networkReleaseAddress is called from multiple places
		// Make sure we decrement the EpCount only if the IPAddress
		// was not already freed earlier
		if nwCfg.IPAllocMap.Test(ipAddrValue) {
			nwCfg.EpAddrCount--
		}
		nwCfg.IPAllocMap.Clear(ipAddrValue)
	}

	err := nwCfg.Write()
	if err != nil {
		log.Errorf("error writing nw config. Error: %s", err)
		return err
	}

	return nil
}
Пример #10
0
// DeleteEndpoint deletes an endpoint by named identifier.
func (d *OvsDriver) DeleteEndpoint(id string) error {
	epOper := OvsOperEndpointState{}
	epOper.StateDriver = d.oper.StateDriver
	err := epOper.Read(id)
	if err != nil {
		return err
	}
	defer func() {
		epOper.Clear()
	}()

	// Get the network state
	cfgNw := mastercfg.CfgNetworkState{}
	cfgNw.StateDriver = d.oper.StateDriver
	err = cfgNw.Read(epOper.NetID)
	if err != nil {
		return err
	}

	// Find the switch based on network type
	var sw *OvsSwitch
	if cfgNw.PktTagType == "vxlan" {
		sw = d.switchDb["vxlan"]
	} else {
		sw = d.switchDb["vlan"]
	}

	skipVethPair := (cfgNw.NwType == "infra")
	err = sw.DeletePort(&epOper, skipVethPair)
	if err != nil {
		log.Errorf("Error deleting endpoint: %+v. Err: %v", epOper, err)
	}

	d.oper.localEpInfoMutex.Lock()
	delete(d.oper.LocalEpInfo, id)
	d.oper.localEpInfoMutex.Unlock()

	return nil
}
Пример #11
0
// CreateEndpoint creates an endpoint by named identifier
func (d *OvsDriver) CreateEndpoint(id string) error {
	var (
		err          error
		intfName     string
		epgKey       string
		epgBandwidth int64
		dscp         int
	)

	cfgEp := &mastercfg.CfgEndpointState{}
	cfgEp.StateDriver = d.oper.StateDriver
	err = cfgEp.Read(id)
	if err != nil {
		return err
	}

	// Get the nw config.
	cfgNw := mastercfg.CfgNetworkState{}
	cfgNw.StateDriver = d.oper.StateDriver
	err = cfgNw.Read(cfgEp.NetID)
	if err != nil {
		log.Errorf("Unable to get network %s. Err: %v", cfgEp.NetID, err)
		return err
	}

	pktTagType := cfgNw.PktTagType
	pktTag := cfgNw.PktTag
	cfgEpGroup := &mastercfg.EndpointGroupState{}
	// Read pkt tags from endpoint group if available
	if cfgEp.EndpointGroupKey != "" {
		cfgEpGroup.StateDriver = d.oper.StateDriver

		err = cfgEpGroup.Read(cfgEp.EndpointGroupKey)
		if err == nil {
			log.Debugf("pktTag: %v ", cfgEpGroup.PktTag)
			pktTagType = cfgEpGroup.PktTagType
			pktTag = cfgEpGroup.PktTag
			epgKey = cfgEp.EndpointGroupKey
			dscp = cfgEpGroup.DSCP
			log.Infof("Received endpoint create with bandwidth:%s", cfgEpGroup.Bandwidth)
			if cfgEpGroup.Bandwidth != "" {
				epgBandwidth = netutils.ConvertBandwidth(cfgEpGroup.Bandwidth)
			}

		} else if core.ErrIfKeyExists(err) == nil {
			log.Infof("EPG %s not found: %v. will use network based tag ", cfgEp.EndpointGroupKey, err)
		} else {
			return err
		}
	}

	// Find the switch based on network type
	var sw *OvsSwitch
	if pktTagType == "vxlan" {
		sw = d.switchDb["vxlan"]
	} else {
		sw = d.switchDb["vlan"]
	}

	// Skip Veth pair creation for infra nw endpoints
	skipVethPair := (cfgNw.NwType == "infra")

	operEp := &OvsOperEndpointState{}
	operEp.StateDriver = d.oper.StateDriver
	err = operEp.Read(id)
	if core.ErrIfKeyExists(err) != nil {
		return err
	} else if err == nil {
		// check if oper state matches cfg state. In case of mismatch cleanup
		// up the EP and continue add new one. In case of match just return.
		if operEp.Matches(cfgEp) {
			log.Printf("Found matching oper state for ep %s, noop", id)

			// Ask the switch to update the port
			err = sw.UpdatePort(operEp.PortName, cfgEp, pktTag, cfgNw.PktTag, dscp, skipVethPair)
			if err != nil {
				log.Errorf("Error creating port %s. Err: %v", intfName, err)
				return err
			}

			return nil
		}
		log.Printf("Found mismatching oper state for Ep, cleaning it. Config: %+v, Oper: %+v",
			cfgEp, operEp)
		d.DeleteEndpoint(operEp.ID)
	}

	if cfgNw.NwType == "infra" {
		// For infra nw, port name is network name
		intfName = cfgNw.NetworkName
	} else {
		// Get the interface name to use
		intfName, err = d.getIntfName()
		if err != nil {
			return err
		}
	}

	// Get OVS port name
	ovsPortName := getOvsPortName(intfName, skipVethPair)

	// Ask the switch to create the port
	err = sw.CreatePort(intfName, cfgEp, pktTag, cfgNw.PktTag, cfgEpGroup.Burst, dscp, skipVethPair, epgBandwidth)
	if err != nil {
		log.Errorf("Error creating port %s. Err: %v", intfName, err)
		return err
	}

	// save local endpoint info
	d.oper.localEpInfoMutex.Lock()
	d.oper.LocalEpInfo[id] = &EpInfo{
		Ovsportname: ovsPortName,
		EpgKey:      epgKey,
		BridgeType:  pktTagType,
	}
	d.oper.localEpInfoMutex.Unlock()
	err = d.oper.Write()
	if err != nil {
		return err
	}
	// Save the oper state
	operEp = &OvsOperEndpointState{
		NetID:       cfgEp.NetID,
		EndpointID:  cfgEp.EndpointID,
		ServiceName: cfgEp.ServiceName,
		IPAddress:   cfgEp.IPAddress,
		MacAddress:  cfgEp.MacAddress,
		IntfName:    cfgEp.IntfName,
		PortName:    intfName,
		HomingHost:  cfgEp.HomingHost,
		VtepIP:      cfgEp.VtepIP}
	operEp.StateDriver = d.oper.StateDriver
	operEp.ID = id
	err = operEp.Write()
	if err != nil {
		return err
	}

	defer func() {
		if err != nil {
			operEp.Clear()
		}
	}()
	return nil
}
Пример #12
0
// CreateEndpoint creates an endpoint by named identifier
func (d *OvsDriver) CreateEndpoint(id string) error {
	var (
		err      error
		intfName string
	)

	cfgEp := &mastercfg.CfgEndpointState{}
	cfgEp.StateDriver = d.oper.StateDriver
	err = cfgEp.Read(id)
	if err != nil {
		return err
	}

	// Ignore VTEP endpoints and uplink endpoints
	// FIXME: we need to stop publiching these from netmaster
	if cfgEp.VtepIP != "" {
		return nil
	}
	if cfgEp.IntfName != "" {
		return nil
	}

	cfgEpGroup := &mastercfg.EndpointGroupState{}
	cfgEpGroup.StateDriver = d.oper.StateDriver
	err = cfgEpGroup.Read(strconv.Itoa(cfgEp.EndpointGroupID))
	if err == nil {
		log.Debugf("pktTag: %v ", cfgEpGroup.PktTag)
	} else if core.ErrIfKeyExists(err) == nil {
		// FIXME: this should be deprecated once we remove old style intent
		// In case EpGroup is not specified, get the tag from nw.
		// this is mainly for the intent based system tests
		log.Warnf("%v will use network based tag ", err)
		cfgNw := mastercfg.CfgNetworkState{}
		cfgNw.StateDriver = d.oper.StateDriver
		err1 := cfgNw.Read(cfgEp.NetID)
		if err1 != nil {
			log.Errorf("Unable to get tag neither epg nor nw")
			return err1
		}

		cfgEpGroup.PktTagType = cfgNw.PktTagType
		cfgEpGroup.PktTag = cfgNw.PktTag
	} else {
		return err
	}

	// Find the switch based on network type
	var sw *OvsSwitch
	if cfgEpGroup.PktTagType == "vxlan" {
		sw = d.switchDb["vxlan"]
	} else {
		sw = d.switchDb["vlan"]
	}

	operEp := &OvsOperEndpointState{}
	operEp.StateDriver = d.oper.StateDriver
	err = operEp.Read(id)
	if core.ErrIfKeyExists(err) != nil {
		return err
	} else if err == nil {
		// check if oper state matches cfg state. In case of mismatch cleanup
		// up the EP and continue add new one. In case of match just return.
		if operEp.Matches(cfgEp) {
			log.Printf("Found matching oper state for ep %s, noop", id)

			// Ask the switch to update the port
			err = sw.UpdatePort(operEp.PortName, cfgEp, cfgEpGroup.PktTag)
			if err != nil {
				log.Errorf("Error creating port %s. Err: %v", intfName, err)
				return err
			}

			return nil
		}
		log.Printf("Found mismatching oper state for Ep, cleaning it. Config: %+v, Oper: %+v",
			cfgEp, operEp)
		d.DeleteEndpoint(operEp.ID)
	}

	// add an internal ovs port with vlan-tag information from the state

	// XXX: revisit, the port name might need to come from user. Also revisit
	// the algorithm to take care of port being deleted and reuse unused port
	// numbers
	d.oper.CurrPortNum++
	err = d.oper.Write()
	if err != nil {
		return err
	}
	intfName = d.getIntfName()

	// Ask the switch to create the port
	err = sw.CreatePort(intfName, cfgEp, cfgEpGroup.PktTag)
	if err != nil {
		log.Errorf("Error creating port %s. Err: %v", intfName, err)
		return err
	}

	// Save the oper state
	operEp = &OvsOperEndpointState{
		NetID:       cfgEp.NetID,
		AttachUUID:  cfgEp.AttachUUID,
		ContName:    cfgEp.ContName,
		ServiceName: cfgEp.ServiceName,
		IPAddress:   cfgEp.IPAddress,
		MacAddress:  cfgEp.MacAddress,
		IntfName:    cfgEp.IntfName,
		PortName:    intfName,
		HomingHost:  cfgEp.HomingHost,
		VtepIP:      cfgEp.VtepIP}
	operEp.StateDriver = d.oper.StateDriver
	operEp.ID = id
	err = operEp.Write()
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			operEp.Clear()
		}
	}()

	return nil
}
Пример #13
0
// CreateEndpoint creates an endpoint
func CreateEndpoint(stateDriver core.StateDriver, nwCfg *mastercfg.CfgNetworkState,
	epReq *CreateEndpointRequest) (*mastercfg.CfgEndpointState, error) {

	ep := &epReq.ConfigEP
	epCfg := &mastercfg.CfgEndpointState{}
	epCfg.StateDriver = stateDriver
	epCfg.ID = getEpName(nwCfg.ID, ep)
	err := epCfg.Read(epCfg.ID)
	if err == nil {
		// TODO: check for diffs and possible updates
		return epCfg, nil
	}

	epCfg.NetID = nwCfg.ID
	epCfg.EndpointID = ep.Container
	epCfg.HomingHost = ep.Host
	epCfg.ServiceName = ep.ServiceName
	epCfg.EPCommonName = epReq.EPCommonName

	// Allocate addresses
	err = allocSetEpAddress(ep, epCfg, nwCfg)
	if err != nil {
		log.Errorf("error allocating and/or reserving IP. Error: %s", err)
		return nil, err
	}

	// cleanup relies on var err being used for all error checking
	defer freeAddrOnErr(nwCfg, epCfg.IPAddress, &err)

	// Set endpoint group
	// Skip for infra nw
	if nwCfg.NwType != "infra" {
		epCfg.EndpointGroupKey = mastercfg.GetEndpointGroupKey(ep.ServiceName, nwCfg.Tenant)
		epCfg.EndpointGroupID, err = mastercfg.GetEndpointGroupID(stateDriver, ep.ServiceName, nwCfg.Tenant)
		if err != nil {
			log.Errorf("Error getting endpoint group ID for %s.%s. Err: %v", ep.ServiceName, nwCfg.ID, err)
			return nil, err
		}

		if epCfg.EndpointGroupKey != "" {
			epgCfg := &mastercfg.EndpointGroupState{}
			epgCfg.StateDriver = stateDriver
			err = epgCfg.Read(epCfg.EndpointGroupKey)
			if err != nil {
				log.Errorf("Error reading Epg info for EP: %+v. Error: %v", ep, err)
				return nil, err
			}

			epgCfg.EpCount++

			err = epgCfg.Write()
			if err != nil {
				log.Errorf("Error saving epg state: %+v", epgCfg)
				return nil, err
			}
		}
	}

	err = nwCfg.IncrEpCount()
	if err != nil {
		log.Errorf("Error incrementing ep count. Err: %v", err)
		return nil, err
	}

	err = epCfg.Write()
	if err != nil {
		log.Errorf("error writing ep config. Error: %s", err)
		return nil, err
	}

	return epCfg, nil
}
Пример #14
0
// CreateEndpoint creates an endpoint by named identifier
func (d *OvsDriver) CreateEndpoint(id string) error {
	var (
		err      error
		intfName string
	)

	cfgEp := &mastercfg.CfgEndpointState{}
	cfgEp.StateDriver = d.oper.StateDriver
	err = cfgEp.Read(id)
	if err != nil {
		return err
	}

	// Get the nw config.
	cfgNw := mastercfg.CfgNetworkState{}
	cfgNw.StateDriver = d.oper.StateDriver
	err = cfgNw.Read(cfgEp.NetID)
	if err != nil {
		log.Errorf("Unable to get network %s. Err: %v", cfgEp.NetID, err)
		return err
	}

	cfgEpGroup := &mastercfg.EndpointGroupState{}
	cfgEpGroup.StateDriver = d.oper.StateDriver
	err = cfgEpGroup.Read(strconv.Itoa(cfgEp.EndpointGroupID))
	if err == nil {
		log.Debugf("pktTag: %v ", cfgEpGroup.PktTag)
	} else if core.ErrIfKeyExists(err) == nil {
		log.Infof("%v will use network based tag ", err)
		cfgEpGroup.PktTagType = cfgNw.PktTagType
		cfgEpGroup.PktTag = cfgNw.PktTag
	} else {
		return err
	}

	// Find the switch based on network type
	var sw *OvsSwitch
	if cfgEpGroup.PktTagType == "vxlan" {
		sw = d.switchDb["vxlan"]
	} else {
		sw = d.switchDb["vlan"]
	}

	operEp := &OvsOperEndpointState{}
	operEp.StateDriver = d.oper.StateDriver
	err = operEp.Read(id)
	if core.ErrIfKeyExists(err) != nil {
		return err
	} else if err == nil {
		// check if oper state matches cfg state. In case of mismatch cleanup
		// up the EP and continue add new one. In case of match just return.
		if operEp.Matches(cfgEp) {
			log.Printf("Found matching oper state for ep %s, noop", id)

			// Ask the switch to update the port
			err = sw.UpdatePort(operEp.PortName, cfgEp, cfgEpGroup.PktTag)
			if err != nil {
				log.Errorf("Error creating port %s. Err: %v", intfName, err)
				return err
			}

			return nil
		}
		log.Printf("Found mismatching oper state for Ep, cleaning it. Config: %+v, Oper: %+v",
			cfgEp, operEp)
		d.DeleteEndpoint(operEp.ID)
	}

	// Get the interface name to use
	intfName, err = d.getIntfName()
	if err != nil {
		return err
	}

	// Ask the switch to create the port
	err = sw.CreatePort(intfName, cfgEp, cfgEpGroup.PktTag, cfgNw.PktTag)
	if err != nil {
		log.Errorf("Error creating port %s. Err: %v", intfName, err)
		return err
	}

	// Save the oper state
	operEp = &OvsOperEndpointState{
		NetID:       cfgEp.NetID,
		AttachUUID:  cfgEp.AttachUUID,
		ContName:    cfgEp.ContName,
		ServiceName: cfgEp.ServiceName,
		IPAddress:   cfgEp.IPAddress,
		MacAddress:  cfgEp.MacAddress,
		IntfName:    cfgEp.IntfName,
		PortName:    intfName,
		HomingHost:  cfgEp.HomingHost,
		VtepIP:      cfgEp.VtepIP}
	operEp.StateDriver = d.oper.StateDriver
	operEp.ID = id
	err = operEp.Write()
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			operEp.Clear()
		}
	}()

	return nil
}