/*
* Copyright (c) 2015, 2017 Ericsson Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.sfc.ofrenderer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.opendaylight.sfc.ofrenderer.utils.SfcOfProviderUtilsTestMock;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfDataPlaneLocatorName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffDataPlaneLocatorName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SftTypeName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SnName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHopBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHopKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocatorBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocatorKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChain;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.ServiceFunctionChainKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunction;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfc.rev140701.service.function.chain.grouping.service.function.chain.SfcServiceFunctionKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocator;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocatorBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocatorKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.sff.data.plane.locator.DataPlaneLocatorBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionary;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionaryBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionaryKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.service.function.dictionary.SffSfDataPlaneLocatorBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathKey;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.service.function.types.ServiceFunctionType;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.service.function.types.ServiceFunctionTypeBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.Mac;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.Mpls;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.Nsh;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.SfcEncapsulationIdentity;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.SlTransportType;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.VxlanGpe;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.LocatorType;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.IpBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.MacBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.MplsBuilder;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sff.logical.rev160620.service.functions.service.function.sf.data.plane.locator.locator.type.LogicalInterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sff.ofs.rev150408.SffDataPlaneLocator1;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sff.ofs.rev150408.SffDataPlaneLocator1Builder;
import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sff.ofs.rev150408.port.details.OfsPortBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
public class RspBuilder {
private static String SF_NAME_PREFIX = "SF_";
private static String SFF_NAME_PREFIX = "SFF_";
private static String SFF_DPL_NAME_PREFIX = "SFF_DPL_";
private static String SFC_NAME_PREFIX = "SFC_";
private static String SFP_NAME_PREFIX = "SFP_";
private static String RSP_NAME_PREFIX = "RSP_";
private static String MAC_ADDRESS_PREFIX = "00:00:00:00:00:";
private static String IP_ADDRESS_PREFIX = "192.168.0.";
private static int VLAN_BASE = 1;
private static int MPLS_BASE = 1;
private static int VXLAN_UDP_PORT = 6633;
private static String SWITCH_PORT_STR = "1";
private long rspPathIdIndex = 0;
private int sfNameIndex = 0;
private int sffNameIndex = 0;
private int sffDplNameIndex = 0;
private int sfcNameIndex = 0;
private int sfpNameIndex = 0;
private int rspNameIndex = 0;
private int macAddrIndex = 0;
private int idAddrIndex = 1;
private int vlanSffIndex = 0;
private int vlanSfIndex = 0;
private int mplsSffIndex = 0;
private int ifNameIndex = 0;
private static final Short STARTING_INDEX = 255;
SfcOfProviderUtilsTestMock sfcUtilsTestMock;
private boolean usesLogicalSff = false;
public RspBuilder(SfcOfProviderUtilsTestMock sfcUtilsTestMock) {
this.sfcUtilsTestMock = sfcUtilsTestMock;
}
public RenderedServicePath createRspFromSfTypes(List<SftTypeName> sfTypes, boolean usesLogicalSffs) {
List<ServiceFunction> sfList = new ArrayList<>();
List<ServiceFunctionForwarder> sffList = new ArrayList<>();
SffName logicalSff = new SffName("logical");
this.usesLogicalSff = usesLogicalSffs;
// build the logical sff
sffList.add(createServiceFunctionForwarder(logicalSff, null, Mac.class, usesLogicalSffs));
// build the SFs
sfTypes.forEach(sftTypeName -> {
SfName sfName = new SfName(SF_NAME_PREFIX + String.valueOf(sfNameIndex++));
sfList.add(createServiceFunction(sfName, logicalSff, sftTypeName, Mac.class));
});
return createRsp(sfTypes, sfList, sffList, Mac.class, Nsh.class);
}
public RenderedServicePath createRspFromSfTypes(List<SftTypeName> sfTypes,
Class<? extends SlTransportType> transportType, Class<? extends SfcEncapsulationIdentity> sfcEncap) {
List<ServiceFunction> sfList = new ArrayList<>();
List<ServiceFunctionForwarder> sffList = new ArrayList<>();
for (SftTypeName sfType : sfTypes) {
SfName sfName = new SfName(SF_NAME_PREFIX + String.valueOf(sfNameIndex++));
SffName sffName = new SffName(SFF_NAME_PREFIX + String.valueOf(sffNameIndex++));
ServiceFunction sf = createServiceFunction(sfName, sffName, sfType, transportType);
sfList.add(sf);
sffList.add(createServiceFunctionForwarder(sffName, sf, transportType));
}
return createRsp(sfTypes, sfList, sffList, transportType, sfcEncap);
}
public RenderedServicePath createRspFromSfList(List<ServiceFunction> sfList, SffName sffName,
Class<? extends SlTransportType> transportType, Class<? extends SfcEncapsulationIdentity> sfcEncap) {
List<ServiceFunctionForwarder> sffList = new ArrayList<>();
List<SftTypeName> sfTypes = new ArrayList<>();
for (ServiceFunction sf : sfList) {
sffList.add(createServiceFunctionForwarder(sffName, sf, transportType));
sfTypes.add(sf.getType());
}
return createRsp(sfTypes, sfList, sffList, transportType, sfcEncap);
}
public String getLogicalInterfaceName(int index) {
return String.format("tap0000-%02d", index);
}
public Short getStartingIndex() {
return STARTING_INDEX;
}
private RenderedServicePath createRsp(List<SftTypeName> sfTypes, List<ServiceFunction> sfList,
List<ServiceFunctionForwarder> sffList, Class<? extends SlTransportType> transportType,
Class<? extends SfcEncapsulationIdentity> sfcEncap) {
ServiceFunctionChain sfc = createServiceFunctionChain(sfTypes);
ServiceFunctionPath sfp = createServiceFunctionPath(sfc, transportType, sfcEncap);
return createRenderedServicePath(sfp, sfList, sffList);
}
private ServiceFunctionChain createServiceFunctionChain(List<SftTypeName> sfTypes) {
short order = 0;
List<SfcServiceFunction> sfcSfs = new ArrayList<>();
for (SftTypeName sfType : sfTypes) {
String name = sfType.getValue() + "Abstract";
SfcServiceFunctionBuilder sfcSfBuilder = new SfcServiceFunctionBuilder();
sfcSfBuilder.setKey(new SfcServiceFunctionKey(name));
sfcSfBuilder.setName(name);
sfcSfBuilder.setOrder(order++);
sfcSfBuilder.setType(sfType);
sfcSfs.add(sfcSfBuilder.build());
}
SfcName sfcName = new SfcName(SFC_NAME_PREFIX + String.valueOf(sfcNameIndex++));
ServiceFunctionChainBuilder sfcBuilder = new ServiceFunctionChainBuilder();
sfcBuilder.setName(sfcName);
sfcBuilder.setKey(new ServiceFunctionChainKey(sfcName));
sfcBuilder.setSymmetric(true);
sfcBuilder.setSfcServiceFunction(sfcSfs);
return sfcBuilder.build();
}
private ServiceFunctionPath createServiceFunctionPath(ServiceFunctionChain sfc,
Class<? extends SlTransportType> transportType, Class<? extends SfcEncapsulationIdentity> encap) {
SfpName sfpName = new SfpName(SFP_NAME_PREFIX + String.valueOf(sfpNameIndex++));
ServiceFunctionPathBuilder sfpBuilder = new ServiceFunctionPathBuilder();
sfpBuilder.setKey(new ServiceFunctionPathKey(sfpName));
sfpBuilder.setName(sfpName);
sfpBuilder.setServiceChainName(sfc.getName());
sfpBuilder.setSymmetric(true);
sfpBuilder.setTransportType(transportType);
sfpBuilder.setSfcEncapsulation(encap);
return sfpBuilder.build();
}
private RenderedServicePath createRenderedServicePath(ServiceFunctionPath sfp, List<ServiceFunction> sfList,
List<ServiceFunctionForwarder> sffList) {
RspName rspName = new RspName(RSP_NAME_PREFIX + String.valueOf(rspNameIndex++));
RenderedServicePathBuilder rspBuilder = new RenderedServicePathBuilder();
rspBuilder.setKey(new RenderedServicePathKey(rspName));
rspBuilder.setStartingIndex(STARTING_INDEX);
rspBuilder.setName(rspName);
rspBuilder.setParentServiceFunctionPath(sfp.getName());
rspBuilder.setPathId(rspPathIdIndex++);
rspBuilder.setTransportType(sfp.getTransportType());
rspBuilder.setSfcEncapsulation(sfp.getSfcEncapsulation());
short index = 0;
short serviceIndex = STARTING_INDEX;
List<RenderedServicePathHop> rspHopList = new ArrayList<>();
for (ServiceFunction sf : sfList) {
ServiceFunctionForwarder sff = sffList.get(usesLogicalSff ? 0 : index);
RenderedServicePathHopBuilder rspHopBuilder = new RenderedServicePathHopBuilder();
rspHopBuilder.setKey(new RenderedServicePathHopKey(index));
rspHopBuilder.setServiceFunctionForwarder(sff.getName());
rspHopBuilder.setServiceFunctionName(sf.getName());
// if we're using a logical SFF, there won't be any dataplane
// locators
rspHopBuilder.setServiceFunctionForwarderLocator(
!sff.getSffDataPlaneLocator().isEmpty() ? sff.getSffDataPlaneLocator().get(0).getName()
: new SffDataPlaneLocatorName(""));
rspHopBuilder.setServiceIndex(serviceIndex);
rspHopBuilder.setHopNumber(index);
rspHopList.add(rspHopBuilder.build());
--serviceIndex;
++index;
}
rspBuilder.setRenderedServicePathHop(rspHopList);
return rspBuilder.build();
}
private ServiceFunctionForwarder createServiceFunctionForwarder(SffName sffName, ServiceFunction sf,
Class<? extends SlTransportType> transportType, boolean isLogicalSff) {
if (!isLogicalSff) {
return createServiceFunctionForwarder(sffName, sf, transportType);
} else { // *do not set* the SFF dataplane locators
ServiceFunctionForwarder sff = buildServiceFunctionForwarder(new SffName("logical"),
Collections.emptyList(), Collections.emptyList());
sfcUtilsTestMock.addServiceFunctionForwarder(sffName, sff);
return sff;
}
}
private ServiceFunctionForwarder createServiceFunctionForwarder(SffName sffName, ServiceFunction sf,
Class<? extends SlTransportType> transportType) {
Class<? extends SlTransportType> sfTransport = sf.getSfDataPlaneLocator().get(0).getTransport();
List<SffDataPlaneLocator> sffDpls;
if (transportType.equals(sf.getSfDataPlaneLocator().get(0).getTransport())) {
sffDpls = createSffDpls(transportType);
} else {
sffDpls = createSffDpls(transportType, sfTransport);
}
List<ServiceFunctionDictionary> sfDictList = createSfDictList(sf, getSffDpl(sffDpls, sfTransport));
ServiceFunctionForwarder sff = buildServiceFunctionForwarder(sffName, sffDpls, sfDictList);
sfcUtilsTestMock.addServiceFunctionForwarder(sffName, sff);
return sff;
}
public ServiceFunction createServiceFunction(SfName sfName, SffName sffName, SftTypeName sfType,
Class<? extends SlTransportType> transportType) {
// For MPLS and MAC transport types, we want the SF to be MAC/VLAN
Class<? extends SlTransportType> sfTransportType = transportType.equals(VxlanGpe.class) ? transportType
: Mac.class;
SfDataPlaneLocator sfDpl = buildSfDataPlaneLocator(new SfDataPlaneLocatorName(sfName.getValue() + "_sfDpl"),
buildSfLocatorType(sfTransportType), sffName, sfTransportType);
ServiceFunction sf = buildServiceFunction(sfName, sfType, getIpMgmt(), sfDpl);
sfcUtilsTestMock.addServiceFunction(sfName, sf);
ServiceFunctionType sftType = buildServiceFunctionType(sf.getType(),false, false);
sfcUtilsTestMock.addServiceFunctionType(sf.getType(),sftType);
return sf;
}
// Notice, for now this method is only used for Vxgpe+NSH on SFF-SFF and Eth+NSH on SFF-SF
private List<SffDataPlaneLocator> createSffDpls(Class<? extends SlTransportType> sffTransportType,
Class<? extends SlTransportType> sfTransportType) {
// First create the sffTransportType, which will be Vxgpe+NSH
SffDataPlaneLocatorName name =
new SffDataPlaneLocatorName(SFF_DPL_NAME_PREFIX + String.valueOf(sffDplNameIndex++));
SffDataPlaneLocatorBuilder sffDplBuilder = new SffDataPlaneLocatorBuilder();
sffDplBuilder.setKey(new SffDataPlaneLocatorKey(name));
sffDplBuilder.setName(name);
DataPlaneLocatorBuilder dplBuilder = new DataPlaneLocatorBuilder();
dplBuilder.setLocatorType(buildLocatorTypeIp(getNextIpAddress(), VXLAN_UDP_PORT));
dplBuilder.setTransport(sffTransportType);
sffDplBuilder.setDataPlaneLocator(dplBuilder.build());
List<SffDataPlaneLocator> sffDpls = new ArrayList<>();
sffDpls.add(sffDplBuilder.build());
// Now create the SFF-SF DPL, which will be Eth+NSH
name = new SffDataPlaneLocatorName(SFF_DPL_NAME_PREFIX + String.valueOf(sffDplNameIndex++));
SffDataPlaneLocatorBuilder sffSfDplBuilder = new SffDataPlaneLocatorBuilder();
sffSfDplBuilder.setKey(new SffDataPlaneLocatorKey(name));
sffSfDplBuilder.setName(name);
DataPlaneLocatorBuilder dplBuilder2 = new DataPlaneLocatorBuilder();
dplBuilder2.setLocatorType(buildLocatorTypeMac(getNextMacAddress(), -1)); // no vlan
dplBuilder2.setTransport(sfTransportType);
sffSfDplBuilder.setDataPlaneLocator(dplBuilder2.build());
sffDpls.add(sffSfDplBuilder.build());
return sffDpls;
}
private List<SffDataPlaneLocator> createSffDpls(Class<? extends SlTransportType> transportType) {
int dplCount = transportType.equals(VxlanGpe.class) ? 1 : 2;
ArrayList<Integer> tunnelIds = new ArrayList<>();
int tunnelIdsIndex = 0;
// This allows us to have adjacent SFFs with matching tunnel info
if (transportType.equals(Mac.class)) {
tunnelIds.add(0, getLastSffVlanId());
tunnelIds.add(1, getNextSffVlanId());
} else if (transportType.equals(Mpls.class)) {
tunnelIds.add(0, getLastSffMplsLabel());
tunnelIds.add(1, getNextSffMplsLabel());
}
List<SffDataPlaneLocator> sffDpls = new ArrayList<>();
for (int i = 0; i < dplCount; ++i) {
SffDataPlaneLocatorName name = new SffDataPlaneLocatorName(
SFF_DPL_NAME_PREFIX + String.valueOf(sffDplNameIndex++));
SffDataPlaneLocatorBuilder sffDplBuilder = new SffDataPlaneLocatorBuilder();
sffDplBuilder.setKey(new SffDataPlaneLocatorKey(name));
sffDplBuilder.setName(name);
DataPlaneLocatorBuilder dplBuilder = new DataPlaneLocatorBuilder();
// check the transport type to see what type of locator to build
if (transportType.equals(Mac.class)) {
dplBuilder.setLocatorType(buildLocatorTypeMac(getNextMacAddress(), tunnelIds.get(tunnelIdsIndex++)));
} else if (transportType.equals(Mpls.class)) {
dplBuilder.setLocatorType(buildLocatorTypeMpls(tunnelIds.get(tunnelIdsIndex++)));
} else if (transportType.equals(VxlanGpe.class)) {
dplBuilder.setLocatorType(buildLocatorTypeIp(getNextIpAddress(), VXLAN_UDP_PORT));
}
dplBuilder.setTransport(transportType);
sffDplBuilder.setDataPlaneLocator(dplBuilder.build());
// Augment the SFF DPL if its not VxLan
if (!transportType.equals(VxlanGpe.class)) {
SffDataPlaneLocator1Builder ofsSffDplBuilder = new SffDataPlaneLocator1Builder();
OfsPortBuilder ofsPortBuilder = new OfsPortBuilder();
ofsPortBuilder.setMacAddress(new MacAddress(getNextMacAddress()));
ofsPortBuilder.setPortId(SWITCH_PORT_STR);
ofsSffDplBuilder.setOfsPort(ofsPortBuilder.build());
sffDplBuilder.addAugmentation(SffDataPlaneLocator1.class, ofsSffDplBuilder.build());
}
sffDpls.add(sffDplBuilder.build());
}
return sffDpls;
}
private List<ServiceFunctionDictionary> createSfDictList(ServiceFunction sf, SffDataPlaneLocatorName sffDplName) {
SffSfDataPlaneLocatorBuilder sffSfDplBuilder = new SffSfDataPlaneLocatorBuilder();
sffSfDplBuilder.setSfDplName(sf.getSfDataPlaneLocator().get(0).getName()); // TODO
// what
// if
// there
// is
// more
// than
// one
// DPL?
sffSfDplBuilder.setSffDplName(sffDplName);
ServiceFunctionDictionaryBuilder sfDictBuilder = new ServiceFunctionDictionaryBuilder();
sfDictBuilder.setName(sf.getName());
sfDictBuilder.setSffSfDataPlaneLocator(sffSfDplBuilder.build());
sfDictBuilder.setKey(new ServiceFunctionDictionaryKey(sf.getName()));
List<ServiceFunctionDictionary> sfDictList = new ArrayList<>();
sfDictList.add(sfDictBuilder.build());
return sfDictList;
}
//
// Internal Util methods
//
private String getNextMacAddress() {
return MAC_ADDRESS_PREFIX + String.format("%02d", macAddrIndex++);
}
private int getNextSffVlanId() {
return VLAN_BASE + (++vlanSffIndex);
}
private int getLastSffVlanId() {
return VLAN_BASE + vlanSffIndex;
}
private int getNextSfVlanId() {
return VLAN_BASE + (++vlanSfIndex);
}
private int getNextSffMplsLabel() {
return MPLS_BASE + (++mplsSffIndex);
}
private int getLastSffMplsLabel() {
return MPLS_BASE + mplsSffIndex;
}
private String getNextIpAddress() {
return IP_ADDRESS_PREFIX + String.valueOf(idAddrIndex++);
}
private IpAddress getIpMgmt() {
// For now, using the same Mgmt address everywhere
return new IpAddress(new Ipv4Address("10.0.0.1"));
}
private String getNextLogicalInterfaceName() {
return String.format("tap0000-%02d", ifNameIndex++);
}
private SffDataPlaneLocatorName getSffDpl(List<SffDataPlaneLocator> sffDpls,
Class<? extends SlTransportType> sfTransport) {
for (SffDataPlaneLocator sffDpl : sffDpls) {
if (sffDpl.getDataPlaneLocator().getTransport().equals(sfTransport)) {
return sffDpl.getName();
}
}
return null;
}
private LocatorType buildSfLocatorType(Class<? extends SlTransportType> transport) {
LocatorType lt = null;
if (transport.equals(Mac.class)) {
if (!usesLogicalSff) {
lt = buildLocatorTypeMac(getNextMacAddress(), getNextSfVlanId());
} else {
lt = new LogicalInterfaceBuilder().setInterfaceName(getNextLogicalInterfaceName()).build();
}
} else if (transport.equals(Mpls.class)) {
// NOTICE for now, we're not dealing with MPLS SFs
lt = buildLocatorTypeMac(getNextMacAddress(), getNextSfVlanId());
} else if (transport.equals(VxlanGpe.class)) {
lt = buildLocatorTypeIp(getNextIpAddress(), VXLAN_UDP_PORT);
}
return lt;
}
private org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc
.sl.rev140701.data.plane.locator.locator.type.Mac buildLocatorTypeMac(
String macAddress, int vlan) {
MacBuilder macBuilder = new MacBuilder();
macBuilder.setMac(new MacAddress(macAddress));
if (vlan >= 0) {
macBuilder.setVlanId(vlan);
}
return macBuilder.build();
}
private org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc
.sl.rev140701.data.plane.locator.locator.type.Mpls buildLocatorTypeMpls(
long label) {
MplsBuilder mplsBuilder = new MplsBuilder();
mplsBuilder.setMplsLabel(label);
return mplsBuilder.build();
}
private Ip buildLocatorTypeIp(String ipAddressStr, int port) {
IpBuilder ipBuilder = new IpBuilder();
ipBuilder.setIp(new IpAddress(new Ipv4Address(ipAddressStr)));
ipBuilder.setPort(new PortNumber(port));
return ipBuilder.build();
}
//
// Builder methods copied from SfcProvider SimpleTestEntityBuilder
//
private SfDataPlaneLocator buildSfDataPlaneLocator(SfDataPlaneLocatorName name, LocatorType locatorType,
SffName serviceFunctionForwarder, Class<? extends SlTransportType> transport) {
SfDataPlaneLocatorBuilder locatorBuilder = new SfDataPlaneLocatorBuilder();
locatorBuilder.setName(name).setKey(new SfDataPlaneLocatorKey(name)).setLocatorType(locatorType)
.setServiceFunctionForwarder(serviceFunctionForwarder).setTransport(transport);
return locatorBuilder.build();
}
private ServiceFunction buildServiceFunction(SfName name, SftTypeName type, IpAddress ipMgmtAddress,
SfDataPlaneLocator sfDataPlaneLocator) {
List<SfDataPlaneLocator> dsfDataPlaneLocatorList = new ArrayList<>();
dsfDataPlaneLocatorList.add(sfDataPlaneLocator);
return buildServiceFunction(name, type, ipMgmtAddress, dsfDataPlaneLocatorList);
}
private ServiceFunction buildServiceFunction(SfName name, SftTypeName type, IpAddress ipMgmtAddress,
List<SfDataPlaneLocator> dsfDataPlaneLocatorList) {
ServiceFunctionBuilder sfBuilder = new ServiceFunctionBuilder();
sfBuilder.setName(name).setKey(new ServiceFunctionKey(name)).setType(type).setIpMgmtAddress(ipMgmtAddress)
.setSfDataPlaneLocator(dsfDataPlaneLocatorList);
return sfBuilder.build();
}
private ServiceFunctionForwarder buildServiceFunctionForwarder(SffName name,
List<SffDataPlaneLocator> sffDataplaneLocatorList, List<ServiceFunctionDictionary> dictionaryList) {
ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder();
sffBuilder.setName(name).setKey(new ServiceFunctionForwarderKey(name))
.setServiceNode(new SnName(name.getValue())).setSffDataPlaneLocator(sffDataplaneLocatorList)
.setServiceFunctionDictionary(dictionaryList);
return sffBuilder.build();
}
private ServiceFunctionType buildServiceFunctionType(SftTypeName name, boolean bidirectional,
boolean l2Transparent) {
ServiceFunctionTypeBuilder sfTypeBuilder = new ServiceFunctionTypeBuilder();
sfTypeBuilder.setType(name).setBidirectional(bidirectional).setL2Transparent(l2Transparent);
return sfTypeBuilder.build();
}
}