// CreatePort creates a port in ovs switch
func (sw *OvsSwitch) CreatePort(intfName string, cfgEp *mastercfg.CfgEndpointState, pktTag int) error {
	var ovsIntfType string

	// Get OVS port name
	ovsPortName := getOvsPostName(intfName)

	// Create Veth pairs if required
	if useVethPair {
		ovsIntfType = ""

		// Create a Veth pair
		err := createVethPair(intfName, ovsPortName)
		if err != nil {
			log.Errorf("Error creating veth pairs. Err: %v", err)
			return err
		}

		// Set the OVS side of the port as up
		err = setLinkUp(ovsPortName)
		if err != nil {
			log.Errorf("Error setting link %s up. Err: %v", ovsPortName, err)
			return err
		}
	} else {
		ovsPortName = intfName
		ovsIntfType = "internal"

	}

	// Set the link mtu to 1450 to allow for 50 bytes vxlan encap
	// (inner eth header(14) + outer IP(20) outer UDP(8) + vxlan header(8))
	err := setLinkMtu(intfName, vxlanEndpointMtu)
	if err != nil {
		log.Errorf("Error setting link %s mtu. Err: %v", intfName, err)
		return err
	}

	// Ask OVSDB driver to add the port
	err = sw.ovsdbDriver.CreatePort(ovsPortName, ovsIntfType, cfgEp.ID, pktTag)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			sw.ovsdbDriver.DeletePort(intfName)
		}
	}()

	// Wait a little for OVS to create the interface
	time.Sleep(300 * time.Millisecond)

	// Set the interface mac address
	err = netutils.SetInterfaceMac(intfName, cfgEp.MacAddress)
	if err != nil {
		log.Errorf("Error setting interface Mac %s on port %s", cfgEp.MacAddress, intfName)
		return err
	}

	// Add the endpoint to ofnet
	// Get the openflow port number for the interface
	ofpPort, err := sw.ovsdbDriver.GetOfpPortNo(ovsPortName)
	if err != nil {
		log.Errorf("Could not find the OVS port %s. Err: %v", ovsPortName, err)
		return err
	}

	macAddr, _ := net.ParseMAC(cfgEp.MacAddress)

	// Build the endpoint info
	endpoint := ofnet.EndpointInfo{
		PortNo:        ofpPort,
		MacAddr:       macAddr,
		Vlan:          uint16(pktTag),
		IpAddr:        net.ParseIP(cfgEp.IPAddress),
		EndpointGroup: cfgEp.EndpointGroupID,
	}

	log.Infof("Adding local endpoint: {%+v}", endpoint)

	// Add the local port to ofnet
	err = sw.ofnetAgent.AddLocalEndpoint(endpoint)
	if err != nil {
		log.Errorf("Error adding local port %s to ofnet. Err: %v", ovsPortName, err)
		return err
	}
	return nil
}
Example #2
0
// AddHostPort adds a host port to the OVS
func (sw *OvsSwitch) AddHostPort(intfName string, intfNum int, isHostNS bool) error {
	var err error

	// some error checking
	if sw.netType != "host" {
		log.Fatalf("Can not add host port to OVS type %s.", sw.netType)
	}

	if sw.hostBridge == nil {
		log.Fatalf("Cannot add host port -- no host bridge")
	}

	ovsPortType := ""
	ovsPortName := getOvsPortName(intfName, isHostNS)
	if isHostNS {
		ovsPortType = "internal"
	} else {

		// Create a Veth pair
		err := createVethPair(intfName, ovsPortName)
		// Set the OVS side of the port as up
		err = setLinkUp(ovsPortName)
		if err != nil {
			log.Errorf("Error setting link %s up. Err: %v", ovsPortName, err)
			return err
		}
	}

	portID := "host" + intfName

	// If the port already exists in OVS, remove it first
	if sw.ovsdbDriver.IsPortNamePresent(ovsPortName) {
		log.Debugf("Removing existing interface entry %s from OVS", ovsPortName)

		// Delete it from ovsdb
		err := sw.ovsdbDriver.DeletePort(ovsPortName)
		if err != nil {
			log.Errorf("Error deleting port %s from OVS. Err: %v", ovsPortName, err)
		}
	}

	// Ask OVSDB driver to add the port as an access port
	err = sw.ovsdbDriver.CreatePort(ovsPortName, ovsPortType, portID, hostVLAN, 0, 0)
	if err != nil {
		log.Errorf("Error adding hostport %s to OVS. Err: %v", intfName, err)
		return err
	}

	// Get the openflow port number for the interface
	ofpPort, err := sw.ovsdbDriver.GetOfpPortNo(ovsPortName)
	if err != nil {
		log.Errorf("Could not find the OVS port %s. Err: %v", intfName, err)
		return err
	}

	// Assign an IP based on the intfnumber
	ipStr, macStr := netutils.PortToHostIPMAC(intfNum)
	mac, _ := net.ParseMAC(macStr)
	ip := net.ParseIP(ipStr)

	portInfo := ofnet.EndpointInfo{
		PortNo:  ofpPort,
		MacAddr: mac,
		IpAddr:  ip,
	}
	// Add to ofnet if this is the hostNS port.
	netutils.SetInterfaceMac(intfName, macStr)
	netutils.SetInterfaceIP(intfName, ipStr)
	err = setLinkUp(intfName)

	if isHostNS {
		err = sw.hostBridge.AddHostPort(portInfo)
		if err != nil {
			log.Errorf("Error adding host port %s. Err: %v", intfName, err)
			return err
		}

		log.Infof("Added host port %s to OVS switch %s.", intfName, sw.bridgeName)
	}

	defer func() {
		if err != nil {
			sw.ovsdbDriver.DeletePort(intfName)
		}
	}()

	return nil
}