예제 #1
0
//UpdateEndpointGroup updates the epg
func (d *OvsDriver) UpdateEndpointGroup(id string) error {
	log.Infof("Received endpoint group update for %s", id)
	var (
		err          error
		epgBandwidth int64
		sw           *OvsSwitch
	)
	//gets the EndpointGroupState object
	cfgEpGroup := &mastercfg.EndpointGroupState{}
	cfgEpGroup.StateDriver = d.oper.StateDriver
	err = cfgEpGroup.Read(id)
	if err != nil {
		return err
	}

	if cfgEpGroup.ID != "" {
		if cfgEpGroup.Bandwidth != "" {
			epgBandwidth = netutils.ConvertBandwidth(cfgEpGroup.Bandwidth)
		}

		d.oper.localEpInfoMutex.Lock()
		defer d.oper.localEpInfoMutex.Unlock()
		for _, epInfo := range d.oper.LocalEpInfo {
			if epInfo.EpgKey == id {
				log.Debugf("Applying bandwidth: %s on: %s ", cfgEpGroup.Bandwidth, epInfo.Ovsportname)
				// Find the switch based on network type
				if epInfo.BridgeType == "vxlan" {
					sw = d.switchDb["vxlan"]
				} else {
					sw = d.switchDb["vlan"]
				}

				// update the endpoint in ovs switch
				err = sw.UpdateEndpoint(epInfo.Ovsportname, cfgEpGroup.Burst, cfgEpGroup.DSCP, epgBandwidth)
				if err != nil {
					log.Errorf("Error adding bandwidth %v , err: %+v", epgBandwidth, err)
					return err
				}
			}
		}
	}
	return err
}
예제 #2
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
}