<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:netvirt:sfc">prefix:netvirt-sfc</type>
<name>netvirt-sfc-default</name>
<of13provider>workaround</of13provider>
+ <addsfflows>false</addsfflows>
<broker>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
<name>binding-osgi-broker</name>
void programEgressClassifierBypass(long dataPathId, long vxGpeOfPort, long nsp, short nsi,
long sfOfPort, int tunnelId, String rspName, boolean write);
- void program_sfEgress(long dataPathId, int dstPort, boolean write);
+ void program_sfEgress(long dataPathId, int dstPort, String rspName, boolean write);
void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
- String ipAddress, String sfDplName, boolean write);
+ String ipAddress, String sfDplName, String rspName, boolean write);
void programStaticArpEntry(long dataPathId, long ofPort, String macAddressStr,
String ipAddress, String rspName, boolean write);
private NetvirtSfcAclListener aclListener;
private NetvirtSfcClassifierListener classifierListener;
private RspListener rspListener;
+ private Boolean addSfFlows;
public void setOf13Provider(String of13Provider) {
LOG.info("of13Provider is: {}", of13Provider);
if (of13Provider.equals("standalone")) {
provider = new NetvirtSfcStandaloneOF13Provider(dataBroker);
} else {
- provider = new NetvirtSfcWorkaroundOF13Provider(dataBroker, mdsalUtils, sfcUtils);
+ provider = new NetvirtSfcWorkaroundOF13Provider(dataBroker, mdsalUtils, sfcUtils, addSfFlows);
}
aclListener = new NetvirtSfcAclListener(provider, dataBroker);
classifierListener = new NetvirtSfcClassifierListener(provider, dataBroker);
new String[] {AbstractServiceInstance.class.getName(),interfaceClassName},
properties, impl);
}
+
+ public void setAddSfFlows(Boolean addSfFlows) {
+ LOG.info("setAddSfFlows: addSfFlows is {}", addSfFlows);
+ this.addSfFlows = addSfFlows;
+ }
}
private DataBroker dataBroker;
private static final String VXGPE = "vxgpe";
public static final String TUNNEL_ENDPOINT_KEY = "local_ip";
+ private Boolean addSfFlows;
- public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) {
+ public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils,
+ SfcUtils sfcUtils, Boolean addSfFlows) {
Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
Preconditions.checkNotNull(mdsalUtils, "Input mdsalUtils cannot be NULL!");
Preconditions.checkNotNull(sfcUtils, "Input sfcUtils cannot be NULL!");
this.dataBroker = dataBroker;
this.mdsalUtils = mdsalUtils;
this.sfcUtils = sfcUtils;
+ this.addSfFlows = addSfFlows;
}
public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
Ip ip = sfcUtils.getSfIp(serviceFunction);
nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
nshHeader.setNshTunUdpPort(ip.getPort());
+ sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
+ rsp.getPathId(), rsp.getStartingIndex(),
+ nshHeader, 0, rsp.getName().getValue(), true);
} else {
LOG.info("handleSff: sff and bridge are not the same: {} - {}, sending to first sff",
bridgeNode.getNodeId().getValue(), serviceFunctionForwarder.getName().getValue());
Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
nshHeader.setNshTunUdpPort(ip.getPort());
+ sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
+ rsp.getPathId(), rsp.getStartingIndex(),
+ nshHeader, vxGpeOfPort, rsp.getName().getValue(), true);
}
- sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
- rsp.getPathId(), rsp.getStartingIndex(),
- nshHeader, vxGpeOfPort, rsp.getName().getValue(), true);
} else if (hop == lastHop) {
LOG.info("handleSff: last hop processing {} - {}",
bridgeNode.getNodeId().getValue(), serviceFunctionForwarder.getName().getValue());
}
//should be sffdplport, but they should all be the same 6633/4790
// TODO: Coexistence: SFC flows should take this using new sf dpl augmentation
- //sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, true);
- //sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName, true);
+ if (addSfFlows == true) {
+ sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, rsp.getName().getValue(), true);
+ sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName,
+ rsp.getName().getValue(), true);
+ }
sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpAddr,
rsp.getName().getValue(), true);
} else {
getNshAction(nshHeader, actionList);
- ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
- ab.setOrder(actionList.size());
- ab.setKey(new ActionKey(actionList.size()));
- actionList.add(ab.build());
+ if (vxGpeOfPort != 0) {
+ ab.setAction(ActionUtils.outputAction(FlowUtils.getNodeConnectorId(dataPathId, vxGpeOfPort)));
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+ } else {
+ ab.setAction(ActionUtils.nxResubmitAction(null, Service.CLASSIFIER.getTable()));
+ ab.setOrder(actionList.size());
+ ab.setKey(new ActionKey(actionList.size()));
+ actionList.add(ab.build());
+ }
ApplyActionsBuilder aab = new ApplyActionsBuilder();
aab.setAction(actionList);
// packet from sf to sff that need to go out local
@Override
- public void program_sfEgress(long dataPathId, int dstPort, boolean write) {
+ public void program_sfEgress(long dataPathId, int dstPort, String rspName, boolean write) {
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = FlowNames.getSfEgress(dstPort);
isb.setInstruction(instructions);
flowBuilder.setInstructions(isb.build());
- writeFlow(flowBuilder, nodeBuilder);
+ writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFEGRESS);
} else {
- removeFlow(flowBuilder, nodeBuilder);
+ removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFEGRESS);
}
}
// looped back sff to sf packets
@Override
public void program_sfIngress(long dataPathId, int dstPort, long sfOfPort,
- String ipAddress, String sfDplName, boolean write) {
+ String ipAddress, String sfDplName, String rspName, boolean write) {
NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dataPathId);
FlowBuilder flowBuilder = new FlowBuilder();
String flowName = FlowNames.getSfIngress(dstPort, ipAddress);
isb.setInstruction(instructions);
flowBuilder.setInstructions(isb.build());
- writeFlow(flowBuilder, nodeBuilder);
+ writeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFINGRESS);
} else {
- removeFlow(flowBuilder, nodeBuilder);
+ removeFlow(flowBuilder, nodeBuilder, rspName, FlowID.FLOW_SFINGRESS);
}
}
}
private static FlowID flowSet[] = {FlowID.FLOW_INGRESSCLASS, FlowID.FLOW_EGRESSCLASS,
- FlowID.FLOW_EGRESSCLASSBYPASS, FlowID.FLOW_SFARP};
+ FlowID.FLOW_EGRESSCLASSBYPASS, FlowID.FLOW_SFARP, FlowID.FLOW_SFINGRESS, FlowID.FLOW_SFEGRESS};
@Override
public void clearFlows(DataBroker dataBroker, String rspName) {
LOG.info("Netvirt SFC module initialization.");
NetvirtSfcProvider sfcProvider = new NetvirtSfcProvider(bundleContext);
sfcProvider.setOf13Provider(getOf13provider());
+ sfcProvider.setAddSfFlows(getAddsfflows());
getBrokerDependency().registerProvider(sfcProvider);
return sfcProvider;
}
leaf of13provider {
type string;
}
+
+ leaf addsfflows {
+ type boolean;
+ }
}
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
}
private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder() {
+ return serviceFunctionForwardersBuilder(null);
+ }
+
+ private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder(OvsdbNodeRef ovsdbNodeRef) {
String sf1Name = SF1NAME;
String sf1Ip = SF1IP;
String sf1DplName = SF1DPLNAME;
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
- sff1Name, sff1Ip, port, sffDpl1Name, sf1Ip, sn1Name, bridge1Name, sf1Name, sf1DplName);
+ sff1Name, sff1Ip, port, sffDpl1Name, sf1Ip, sn1Name, bridge1Name, sf1Name, sf1DplName,
+ ovsdbNodeRef);
List<ServiceFunctionForwarder> serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
new ArrayList<ServiceFunctionForwarder>(), serviceFunctionForwarderBuilder);
new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, rspIid, waitList);
rspOperationalListener.registerDataChangeListener(dataBroker);
+ OvsdbBridgeAugmentation bridgeAugmentation = southbound.extractBridgeAugmentation(nodeInfo.bridgeNode);
+ OvsdbNodeRef ovsdbNodeRef = null;
+ if (bridgeAugmentation != null) {
+ ovsdbNodeRef = bridgeAugmentation.getManagedBy();
+ }
+
testModelPut(serviceFunctionsBuilder(), ServiceFunctions.class);
- testModelPut(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class);
+ testModelPut(serviceFunctionForwardersBuilder(ovsdbNodeRef), ServiceFunctionForwarders.class);
testModelPut(serviceFunctionChainsBuilder(), ServiceFunctionChains.class);
testModelPut(serviceFunctionPathsBuilder(), ServiceFunctionPaths.class);
verifyFlow(nodeInfo.datapathId, flowId, Service.CLASSIFIER);
flowId = FlowNames.getArpResponder(SF1IP);
verifyFlow(nodeInfo.datapathId, flowId, Service.ARP_RESPONDER);
+ // Only verify these flows if NetVirt adds them and not SFC
+ //flowId = FlowNames.getSfEgress(GPEUDPPORT);
+ //verifyFlow(nodeInfo.datapathId, flowId, Service.SFC_CLASSIFIER);
+ //flowId = FlowNames.getSfIngress(GPEUDPPORT, SF1IP);
+ //verifyFlow(nodeInfo.datapathId, flowId, Service.CLASSIFIER.getTable());
LOG.info("check for flows!!!!!!!!!!!!!");
Thread.sleep(30000);
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsBridgeAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentation;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsLocatorOptionsAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsNodeAugmentation;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.SffOvsNodeAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.bridge.OvsBridgeBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.node.OvsNodeBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.ovs.rev140701.options.OvsOptionsBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
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.service.function.forwarder.SffDataPlaneLocatorBuilder;
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.sff.rev140701.service.function.forwarders.service.function.forwarder.sff.data.plane.locator.DataPlaneLocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public class ServiceFunctionForwarderUtils extends AbstractUtils {
public OvsOptionsBuilder ovsOptionsBuilder(OvsOptionsBuilder ovsOptionsBuilder, int port) {
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder,
String sffName, String serviceNodeName, String bridgeName,
List<SffDataPlaneLocator> sffDataPlaneLocatorList,
- List<ServiceFunctionDictionary> serviceFunctionDictionaryList) {
+ List<ServiceFunctionDictionary> serviceFunctionDictionaryList,
+ OvsdbNodeRef ovsdbNodeRef) {
SffOvsBridgeAugmentationBuilder sffOvsBridgeAugmentationBuilder = new SffOvsBridgeAugmentationBuilder();
sffOvsBridgeAugmentationBuilder.setOvsBridge(ovsBridgeBuilder(new OvsBridgeBuilder(), bridgeName).build());
+ SffOvsNodeAugmentationBuilder sffOvsNodeAugmentationBuilder = new SffOvsNodeAugmentationBuilder();
+ OvsNodeBuilder ovsNodeBuilder = new OvsNodeBuilder();
+ ovsNodeBuilder.setNodeId(ovsdbNodeRef);
+ sffOvsNodeAugmentationBuilder.setOvsNode(ovsNodeBuilder.build());
+
return serviceFunctionForwarderBuilder
.setName(new SffName(sffName))
.setServiceNode(new SnName(serviceNodeName))
.setServiceFunctionDictionary(serviceFunctionDictionaryList)
.setSffDataPlaneLocator(sffDataPlaneLocatorList)
+ .addAugmentation(SffOvsNodeAugmentation.class, sffOvsNodeAugmentationBuilder.build())
.addAugmentation(SffOvsBridgeAugmentation.class, sffOvsBridgeAugmentationBuilder.build());
}
public ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder(
String sffName, String sffIp, int port, String sffDplName,
- String sfIp, String snName, String bridgeName, String sfName, String sfDplName) {
+ String sfIp, String snName, String bridgeName, String sfName, String sfDplName,
+ OvsdbNodeRef ovsdbNodeRef) {
DataPlaneLocatorBuilder dataPlaneLocatorBuilder =
dataPlaneLocatorBuilder(new DataPlaneLocatorBuilder(), sffIp, port);
ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
serviceFunctionForwarderBuilder(
new ServiceFunctionForwarderBuilder(), sffName, snName, bridgeName,
- sffDataPlaneLocatorList, serviceFunctionDictionaryList);
+ sffDataPlaneLocatorList, serviceFunctionDictionaryList, ovsdbNodeRef);
return serviceFunctionForwarderBuilder;
}
}
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.sl.rev140701.VxlanGpe;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sf.ovs.rev160107.SfDplOvsAugmentation;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sf.ovs.rev160107.SfDplOvsAugmentationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.sfc.sf.ovs.rev160107.connected.port.OvsPortBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
public class ServiceFunctionUtils extends AbstractUtils {
public SfDataPlaneLocatorBuilder sfDataPlaneLocatorBuilder(SfDataPlaneLocatorBuilder sfDataPlaneLocatorBuilder,
String ip, int port, String dplName, String sffName) {
+ SfDplOvsAugmentationBuilder sfDplOvsAugmentationBuilder = new SfDplOvsAugmentationBuilder();
+ OvsPortBuilder ovsPortBuilder = new OvsPortBuilder().setPortId(dplName);
+ sfDplOvsAugmentationBuilder.setOvsPort(ovsPortBuilder.build());
+
return sfDataPlaneLocatorBuilder
+ .addAugmentation(SfDplOvsAugmentation.class, sfDplOvsAugmentationBuilder.build())
.setLocatorType(ipBuilder(ip, port).build())
- .setName(new SfDataPlaneLocatorName(dplName))
+ .setName(SfDataPlaneLocatorName.getDefaultInstance(dplName))
.setTransport(VxlanGpe.class)
- .setServiceFunctionForwarder(new SffName(sffName));
+ .setServiceFunctionForwarder(SffName.getDefaultInstance(sffName));
}
public ServiceFunctionBuilder serviceFunctionBuilder(ServiceFunctionBuilder serviceFunctionBuilder,