Beispiel #1
0
// addNATFlow sets up a NAT flow
// natT must be "Src" or "Dst"
func (svcOp *proxyOper) addNATFlow(this, next *ofctrl.Table, p *PortSpec,
	ipSa, ipDa, ipNew *net.IP, natT string) {

	// Check if we already installed this flow
	key := ""
	if natT == "Dst" {
		key = getNATKey(ipSa.String(), natT, p)
	} else {
		key = getNATKey(ipDa.String(), natT, p)
	}
	f, found := svcOp.natFlows[key]
	if found && f != nil {
		log.Infof("Flow already exists for %v", key)
		return
	}

	match := ofctrl.FlowMatch{
		Priority:  FLOW_MATCH_PRIORITY,
		Ethertype: 0x0800,
		IpSa:      ipSa,
		IpDa:      ipDa,
		IpProto:   getIPProto(p.Protocol),
	}

	if p.Protocol == "TCP" {
		if natT == spDNAT {
			match.TcpDstPort = p.SvcPort
		} else {
			match.TcpSrcPort = p.ProvPort
		}
	} else {
		if natT == spDNAT {
			match.UdpDstPort = p.SvcPort
		} else {
			match.UdpSrcPort = p.ProvPort
		}
	}

	natFlow, err := this.NewFlow(match)

	if err != nil {
		log.Errorf("Proxy addNATFlow failed")
		return
	}

	l4field := p.Protocol + natT // evaluates to TCP[Src,Dst] or UDP[Src,Dst]

	// add actions to update ipda and dest port
	natFlow.SetIPField(*ipNew, natT)
	if natT == spDNAT {
		natFlow.SetL4Field(p.ProvPort, l4field)
	} else {
		natFlow.SetL4Field(p.SvcPort, l4field)
	}
	natFlow.Next(next)
	svcOp.natFlows[key] = natFlow
	log.Infof("Added NAT %s to %s", key, ipNew.String())
}
Beispiel #2
0
// createPortVlanFlow creates port vlan flow based on endpoint metadata
func createPortVlanFlow(agent *OfnetAgent, vlanTable, nextTable *ofctrl.Table, endpoint *OfnetEndpoint) (*ofctrl.Flow, error) {
	// Install a flow entry for vlan mapping
	portVlanFlow, err := vlanTable.NewFlow(ofctrl.FlowMatch{
		Priority:  FLOW_FLOOD_PRIORITY,
		InputPort: endpoint.PortNo,
	})
	if err != nil {
		log.Errorf("Error creating portvlan entry. Err: %v", err)
		return nil, err
	}

	//set vrf id as METADATA
	vrfid := agent.getvrfId(endpoint.Vrf)
	metadata, metadataMask := Vrfmetadata(*vrfid)

	// set source EPG id if required
	if endpoint.EndpointGroup != 0 {
		srcMetadata, srcMetadataMask := SrcGroupMetadata(endpoint.EndpointGroup)
		metadata = metadata | srcMetadata
		metadataMask = metadataMask | srcMetadataMask

	}

	// set vlan if required
	if agent.dpName == "vxlan" {
		portVlanFlow.SetVlan(endpoint.Vlan)
	}

	// set metedata
	portVlanFlow.SetMetadata(metadata, metadataMask)

	// Point it to next table
	err = portVlanFlow.Next(nextTable)
	if err != nil {
		log.Errorf("Error installing portvlan entry. Err: %v", err)
		return nil, err
	}

	return portVlanFlow, nil
}
Beispiel #3
0
// createDscpFlow creates DSCP v4/v6 flows
func createDscpFlow(agent *OfnetAgent, vlanTable, nextTable *ofctrl.Table, endpoint *OfnetEndpoint) (*ofctrl.Flow, *ofctrl.Flow, error) {
	// if endpoint has no DSCP value, we are done..
	if endpoint.Dscp == 0 {
		return nil, nil, nil
	}

	// Install a flow entry for DSCP v4
	dscpV4Flow, err := vlanTable.NewFlow(ofctrl.FlowMatch{
		Priority:  FLOW_MATCH_PRIORITY,
		InputPort: endpoint.PortNo,
		Ethertype: 0x0800,
	})
	if err != nil {
		log.Errorf("Error creating DSCP v4 entry. Err: %v", err)
		return nil, nil, err
	}

	// Install a flow entry for DSCP v6
	dscpV6Flow, err := vlanTable.NewFlow(ofctrl.FlowMatch{
		Priority:  FLOW_MATCH_PRIORITY,
		InputPort: endpoint.PortNo,
		Ethertype: 0x86DD,
	})
	if err != nil {
		log.Errorf("Error creating DSCP v6 entry. Err: %v", err)
		return nil, nil, err
	}

	//set vrf id as METADATA
	vrfid := agent.getvrfId(endpoint.Vrf)
	metadata, metadataMask := Vrfmetadata(*vrfid)

	// set source EPG id if required
	if endpoint.EndpointGroup != 0 {
		srcMetadata, srcMetadataMask := SrcGroupMetadata(endpoint.EndpointGroup)
		metadata = metadata | srcMetadata
		metadataMask = metadataMask | srcMetadataMask

	}

	// set vlan if required
	if agent.dpName == "vxlan" {
		dscpV4Flow.SetVlan(endpoint.Vlan)
		dscpV6Flow.SetVlan(endpoint.Vlan)
	}

	// set dscp and metadata on the flow
	dscpV4Flow.SetDscp(uint8(endpoint.Dscp))
	dscpV6Flow.SetDscp(uint8(endpoint.Dscp))
	dscpV4Flow.SetMetadata(metadata, metadataMask)
	dscpV6Flow.SetMetadata(metadata, metadataMask)

	// Point it to next table
	err = dscpV4Flow.Next(nextTable)
	if err != nil {
		log.Errorf("Error installing dscp v4 entry. Err: %v", err)
		return nil, nil, err
	}
	err = dscpV6Flow.Next(nextTable)
	if err != nil {
		log.Errorf("Error installing dscp v6 entry. Err: %v", err)
		return nil, nil, err
	}

	return dscpV4Flow, dscpV6Flow, nil
}