From: Sam Hague Date: Fri, 13 Nov 2015 03:48:16 +0000 (-0500) Subject: add rsp option X-Git-Tag: release/beryllium-sr2~279^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;ds=sidebyside;h=4b140b064818666ead36d084d2cacdd4ea7abbcc;p=netvirt.git add rsp option Change-Id: Idd0410436861ccc13ad581e42e75ea793102e3ad Signed-off-by: Sam Hague --- diff --git a/openstack/net-virt-sfc/api/pom.xml b/openstack/net-virt-sfc/api/pom.xml index c01db2bc0c..75049d0d0e 100644 --- a/openstack/net-virt-sfc/api/pom.xml +++ b/openstack/net-virt-sfc/api/pom.xml @@ -57,11 +57,8 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.yang.gen.v1.*, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.*, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.*, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.* diff --git a/openstack/net-virt-sfc/api/src/main/yang/netvirt-acl.yang b/openstack/net-virt-sfc/api/src/main/yang/netvirt-acl.yang index 31d1e1d867..44fa5a1847 100644 --- a/openstack/net-virt-sfc/api/src/main/yang/netvirt-acl.yang +++ b/openstack/net-virt-sfc/api/src/main/yang/netvirt-acl.yang @@ -10,7 +10,6 @@ module netvirt-sfc-acl { description "Initial revision of netvirt extensions to ietf-acl model"; } - // TODO: Add choice for Neutron and add fields there instead of at the root of matches //augment "/ietf-acl:access-lists/ietf-acl:access-list/ietf-acl:access-list-entries/ietf-acl:access-list-entry/ietf-acl:matches" { augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:matches" { description "Neutron network uuid"; @@ -20,11 +19,16 @@ module netvirt-sfc-acl { } } - // TODO: Add choice for Neutron and add fields there instead of at the root of matches augment "/ietf-acl:access-lists/ietf-acl:acl/ietf-acl:access-list-entries/ietf-acl:ace/ietf-acl:actions" { - description "Redirect traffic to SFC identified by SFC Path ID"; + description "Redirect traffic to SFC identified by either SFC, SFP or RSP"; ext:augment-identifier "redirect-to-sfc"; - leaf redirect-sfc { + leaf sfc-name { + type string; + } + leaf sfp-name { + type string; + } + leaf rsp-name { type string; } } diff --git a/openstack/net-virt-sfc/impl/pom.xml b/openstack/net-virt-sfc/impl/pom.xml index 21cdee3e26..27c3ab7309 100644 --- a/openstack/net-virt-sfc/impl/pom.xml +++ b/openstack/net-virt-sfc/impl/pom.xml @@ -178,6 +178,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html ${sonar-jacoco-listeners.version} test + + org.opendaylight.mdsal.model + iana-if-type-2014-05-08 + 2014.05.08.8-SNAPSHOT + diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java index 3983fa1250..40b8172393 100644 --- a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java +++ b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/SfcUtils.java @@ -20,10 +20,12 @@ import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev1407 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions; 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.ServiceFunctionKey; +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.sfp.rev140701.ServiceFunctionPaths; 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.sl.rev140701.data.plane.locator.locator.type.Ip; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; @@ -55,6 +57,10 @@ public class SfcUtils { .child(ServiceFunction.class, new ServiceFunctionKey(SfName.getDefaultInstance(sfName))).build(); } + public RenderedServicePath getRsp(String rspName) { + return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, getRspId(rspName)); + } + public RenderedServicePath getRspforSfp(String sfpName) { RenderedServicePath rspFound = null; RenderedServicePaths rsps = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, this.getRspsId()); @@ -83,7 +89,7 @@ public class SfcUtils { return sfpFound; } - public IpAddress getSfIp(String sfname) { + public IpAddress getSfIpAddress(String sfname) { ServiceFunction serviceFunction = SfcProviderServiceFunctionAPI.readServiceFunction(SfName.getDefaultInstance(sfname)); @@ -92,10 +98,10 @@ public class SfcUtils { return null; } - return getSfIp(serviceFunction); + return getSfIpAddress(serviceFunction); } - public IpAddress getSfIp(ServiceFunction serviceFunction) { + public IpAddress getSfIpAddress(ServiceFunction serviceFunction) { if (serviceFunction == null) { LOG.info("getSfIp: Servicefunction is null"); return null; @@ -105,6 +111,25 @@ public class SfcUtils { return ipLocator.getIp(); } + public PortNumber getSfPort(ServiceFunction serviceFunction) { + if (serviceFunction == null) { + LOG.info("getSfIp: Servicefunction is null"); + return null; + } + + Ip ipLocator = (Ip) serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType(); + return ipLocator.getPort(); + } + + public Ip getSfIp(ServiceFunction serviceFunction) { + if (serviceFunction == null) { + LOG.info("getSfIp: Servicefunction is null"); + return null; + } + + return (Ip)serviceFunction.getSfDataPlaneLocator().get(0).getLocatorType(); + } + public String getSfDplName(ServiceFunction serviceFunction) { String sfDplName = null; if (serviceFunction == null) { @@ -115,4 +140,13 @@ public class SfcUtils { sfDplName = serviceFunction.getSfDataPlaneLocator().get(0).getName().getValue(); return sfDplName; } + + public Ip getSffIp(ServiceFunctionForwarder serviceFunctionForwarder) { + if (serviceFunctionForwarder == null) { + LOG.info("getSfIp: ServicefunctionForwarder is null"); + return null; + } + + return (Ip)serviceFunctionForwarder.getSffDataPlaneLocator().get(0).getDataPlaneLocator().getLocatorType(); + } } diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java index 7cfcf6c96e..77ec178f65 100644 --- a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java +++ b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/standalone/openflow13/NetvirtSfcStandaloneOF13Provider.java @@ -154,59 +154,16 @@ public class NetvirtSfcStandaloneOF13Provider implements INetvirtSfcOF13Provider return; } - RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class); - LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect); - if (sfcRedirect == null) { - LOG.warn("processAClEntry: sfcRedirect is null"); - return; - } - - String sfcName = sfcRedirect.getRedirectSfc(); - LOG.debug("Processing Redirect to SFC = {}", sfcRedirect.getRedirectSfc()); - ServiceFunctionPath sfp = getSfp(sfcName); - if (sfp == null || sfp.getName() == null) { - LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName); - return; - } - - LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp); - // If RSP doesn't exist, create an RSP. - String sfpName = sfp.getName().getValue(); - RenderedServicePath rsp = getRspforSfp(sfpName); - String rspName = sfp.getName().getValue() + "_rsp"; + RenderedServicePath rsp = getRenderedServicePath(entry); if (rsp == null) { - LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName); - CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder() - .setParentServiceFunctionPath(sfpName) - .setName(rspName) - .setSymmetric(sfp.isSymmetric()) - .build(); - rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput); - if (rsp == null) { - LOG.warn("failed to add RSP"); - return; - } - - // If SFP is symmetric, create RSP in the reverse direction. - if (sfp.isSymmetric()) { - LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName); - String rspNameRev = rspName + "-Reverse"; - RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, - this.getRspId(rspNameRev)); - if (rspReverse == null) { - rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp); - if (rspReverse == null) { - LOG.warn("failed to add reverse RSP"); - return; - } - } - } + LOG.warn("Failed to get renderedServicePatch for entry: {}", entry); + return; } LOG.info("processAclEntry: RSP: {}", rsp); List pathHopList = rsp.getRenderedServicePathHop(); if (pathHopList.isEmpty()) { - LOG.warn("Service Path = {} has empty hops!!", sfpName); + LOG.warn("Service Path = {} has empty hops!!", rsp.getName()); return; } @@ -235,10 +192,10 @@ public class NetvirtSfcStandaloneOF13Provider implements INetvirtSfcOF13Provider // Find the first Hop within an RSP. // The classifier flow needs to send all matched traffic to this first hop SFF. RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI - .readRenderedServicePathFirstHop(new RspName(rspName)); + .readRenderedServicePathFirstHop(new RspName(rsp.getName())); LOG.debug("First Hop IPAddress = {}, Port = {}", firstRspHop.getIp().getIpv4Address().getValue(), - firstRspHop.getPort().getValue().intValue()); + firstRspHop.getPort().getValue()); NshUtils nshHeader = new NshUtils(); // C1 is the normal overlay dest ip and c2 is the vnid @@ -299,6 +256,81 @@ public class NetvirtSfcStandaloneOF13Provider implements INetvirtSfcOF13Provider } } + private RenderedServicePath getRenderedServicePath (Ace entry) { + RenderedServicePath rsp = null; + RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class); + LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect); + if (sfcRedirect == null) { + LOG.warn("processAClEntry: sfcRedirect is null"); + return null; + } + + if (sfcRedirect.getRspName() != null) { + rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName()); + } else if (sfcRedirect.getSfpName() != null) { + LOG.warn("getRenderedServicePath: sfp not handled yet"); + } else { + rsp = getRenderedServicePathFromSfc(entry); + } + LOG.info("getRenderedServicePath: rsp: {}", rsp); + return rsp; + } + + private RenderedServicePath getRenderedServicePathFromRsp(String rspName) { + return null;//getRsp(rspName); + } + + private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) { + RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class); + LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect); + if (sfcRedirect == null) { + LOG.warn("processAClEntry: sfcRedirect is null"); + return null; + } + + String sfcName = sfcRedirect.getSfcName(); + ServiceFunctionPath sfp = getSfp(sfcName); + if (sfp == null || sfp.getName() == null) { + LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName); + return null; + } + + LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp); + // If RSP doesn't exist, create an RSP. + String sfpName = sfp.getName().getValue(); + RenderedServicePath rsp = getRspforSfp(sfpName); + String rspName = sfp.getName().getValue() + "_rsp"; + if (rsp == null) { + LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName); + CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder() + .setParentServiceFunctionPath(sfpName) + .setName(rspName) + .setSymmetric(sfp.isSymmetric()) + .build(); + rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput); + if (rsp == null) { + LOG.warn("failed to add RSP"); + return null; + } + + // If SFP is symmetric, create RSP in the reverse direction. + if (sfp.isSymmetric()) { + LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName); + String rspNameRev = rspName + "-Reverse"; + RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, + getRspId(rspNameRev)); + if (rspReverse == null) { + rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp); + if (rspReverse == null) { + LOG.warn("failed to add reverse RSP"); + return null; + } + } + } + } + return rsp; + } + private void handleLocalEgressPort(long dataPathId, String s, long localOfPort, short writeTable, short gotoTable, boolean write) { diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java index 4d13ddb7e5..56aa8f79c0 100644 --- a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java +++ b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/NetvirtSfcWorkaroundOF13Provider.java @@ -14,24 +14,27 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.ovsdb.openstack.netvirt.api.Constants; import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager; +import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables; import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound; import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider; import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService; import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils; import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils; -import org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround.services.SfcClassifierService; import org.opendaylight.ovsdb.southbound.SouthboundConstants; import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils; import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper; import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI; +import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI; import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI; 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.sl.rev140701.data.plane.locator.locator.type.Ip; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop; 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.rendered.service.path.RenderedServicePathHop; 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.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder; 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.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace; @@ -45,6 +48,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff; 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.OvsdbNodeAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; @@ -66,6 +70,7 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider private static final String VXGPE = "vxgpe"; private static final String TUNNEL_DST = "192.168.120.31"; private static final String TUNNEL_VNID = "10"; + public static final String TUNNEL_ENDPOINT_KEY = "local_ip"; public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) { Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!"); @@ -131,7 +136,7 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider return; } - handleRenderedServicePath(rsp, entry); + handleRenderedServicePath2(rsp, entry); } private void handleRenderedServicePath(RenderedServicePath rsp, Ace entry) { @@ -180,7 +185,7 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop); LOG.debug("handleRenderedServicePath: First Hop IPAddress = {}, Port = {}", firstRspHop.getIp().getIpv4Address().getValue(), - firstRspHop.getPort().getValue().intValue()); + firstRspHop.getPort().getValue()); NshUtils nshHeader = new NshUtils(); nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST))); @@ -201,7 +206,7 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider nshHeader.setNshNsi(firstHop.getServiceIndex()); // workaround: bypass sff and got directly to sf //nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address()); - IpAddress sfIpAddress = sfcUtils.getSfIp(serviceFunction); + IpAddress sfIpAddress = sfcUtils.getSfIpAddress(serviceFunction); String sfDplName = sfcUtils.getSfDplName(serviceFunction); //sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue()); nshHeader.setNshTunIpDst(sfIpAddress.getIpv4Address()); @@ -212,7 +217,6 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider nshHeader, vxGpeOfPort, true); sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true); - //not needed if ip route and arp can be added to stack long sfOfPort = getSfPort(bridgeNode, sfDplName); String sfMac = getMacFromExternalIds(bridgeNode, sfDplName); @@ -234,7 +238,152 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider } } + private void handleRenderedServicePath2(RenderedServicePath rsp, Ace entry) { + LOG.info("handleRenderedServicePath: RSP: {}", rsp); + + Matches matches = entry.getMatches(); + if (matches == null) { + LOG.warn("processAclEntry: matches not found"); + return; + } + + List pathHopList = rsp.getRenderedServicePathHop(); + if (pathHopList.isEmpty()) { + LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName()); + return; + } + LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList); + + RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI + .readRenderedServicePathFirstHop(rsp.getName()); + LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop); + + RenderedServicePathHop firstHop = pathHopList.get(0); + RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1); + + final List bridgeNodes = nodeCacheManager.getBridgeNodes(); + if (bridgeNodes == null || bridgeNodes.isEmpty()) { + LOG.warn("handleRenderedServicePath: There are no bridges to process"); + return; + } + for (RenderedServicePathHop hop : pathHopList) { + for (Node bridgeNode : bridgeNodes) { + long vxGpeOfPort = getOFPort(bridgeNode, VXGPE); + if (vxGpeOfPort == 0L) { + LOG.warn("programAclEntry: Could not identify gpe vtep {} -> OF ({}) on {}", + VXGPE, vxGpeOfPort, bridgeNode); + continue; + } + long dataPathId = southbound.getDataPathId(bridgeNode); + if (dataPathId == 0L) { + LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode); + continue; + } + + ServiceFunction serviceFunction = + SfcProviderServiceFunctionAPI.readServiceFunction(firstHop.getServiceFunctionName()); + if (serviceFunction == null) { + LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}", + firstHop.getServiceFunctionName().getValue(), bridgeNode); + continue; + } + ServiceFunctionForwarder serviceFunctionForwarder = + SfcProviderServiceForwarderAPI + .readServiceFunctionForwarder(hop.getServiceFunctionForwarder()); + if (serviceFunctionForwarder == null) { + LOG.warn("programAclEntry: Could not identify ServiceFunctionForwarder {} on {}", + firstHop.getServiceFunctionName().getValue(), bridgeNode); + continue; + } + + handleSf(bridgeNode, serviceFunction); + handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, firstHop, lastHop, + entry.getRuleName(), matches, vxGpeOfPort, rsp); + if (firstHop == lastHop) { + handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, null, lastHop, + entry.getRuleName(), matches, vxGpeOfPort, rsp); + } + } + } + } + + private void handleSff(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder, + ServiceFunction serviceFunction, + RenderedServicePathHop hop, + RenderedServicePathHop firstHop, + RenderedServicePathHop lastHop, + String ruleName, Matches matches, + long vxGpeOfPort, RenderedServicePath rsp) { + long dataPathId = southbound.getDataPathId(bridgeNode); + + if (hop == firstHop) { + NshUtils nshHeader = new NshUtils(); + nshHeader.setNshNsp(rsp.getPathId()); + nshHeader.setNshNsi(firstHop.getServiceIndex()); + if (isSffOnBridge(bridgeNode, serviceFunctionForwarder)) { + Ip ip = sfcUtils.getSfIp(serviceFunction); + nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address()); + nshHeader.setNshTunUdpPort(ip.getPort()); + } else { + Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder); + nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address()); + nshHeader.setNshTunUdpPort(ip.getPort()); + } + sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches, + nshHeader, vxGpeOfPort, true); + } else if (hop == lastHop) { + short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1); + String sfDplName = sfcUtils.getSfDplName(serviceFunction); + long sfOfPort = getSfPort(bridgeNode, sfDplName); + sfcClassifierService.programEgressClassifier1(dataPathId, vxGpeOfPort, rsp.getPathId(), + lastServiceindex, (int)sfOfPort, 0, (short)0, true); + sfcClassifierService.programEgressClassifier2(dataPathId, vxGpeOfPort, rsp.getPathId(), + lastServiceindex, (int)sfOfPort, 0, true); + } else { + // add typical sff flows + } + + sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true); + } + + void handleSf(Node bridgeNode, ServiceFunction serviceFunction) { + if (isSfOnBridge(bridgeNode, serviceFunction)) { + long dataPathId = southbound.getDataPathId(bridgeNode); + Ip ip = sfcUtils.getSfIp(serviceFunction); + String sfIpAddr = String.valueOf(ip.getIp().getValue()); + int sfIpPort = ip.getPort().getValue(); //GPE_PORT + String sfDplName = sfcUtils.getSfDplName(serviceFunction); + long sfOfPort = getSfPort(bridgeNode, sfDplName); + String sfMac = getMacFromExternalIds(bridgeNode, sfDplName); + //should be sffdplport, but they should all be the same 6633/4790 + sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, true); + sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName, true); + sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpAddr, true); + } + } + + private boolean isSffOnBridge(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder) { + String local_ip = ""; + Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder); + Node ovsdbNode = southbound.readOvsdbNode(bridgeNode); + if (ovsdbNode != null) { + OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class); + if (ovsdbNodeAugmentation != null && ovsdbNodeAugmentation.getOpenvswitchOtherConfigs() != null) { + southbound.getOtherConfig(ovsdbNode, OvsdbTables.OPENVSWITCH, TUNNEL_ENDPOINT_KEY); + } + + } + return local_ip.equals(String.valueOf(ip.getIp().getValue())); + } + + private boolean isSfOnBridge(Node bridgeNode, ServiceFunction serviceFunction) { + String sfDplName = sfcUtils.getSfDplName(serviceFunction); + long sfOfPort = getSfPort(bridgeNode, sfDplName); + return sfOfPort != 0L; + } + private RenderedServicePath getRenderedServicePath (Ace entry) { + RenderedServicePath rsp = null; RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class); LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect); if (sfcRedirect == null) { @@ -242,14 +391,37 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider return null; } - String sfcName = sfcRedirect.getRedirectSfc(); + if (sfcRedirect.getRspName() != null) { + rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName()); + } else if (sfcRedirect.getSfpName() != null) { + LOG.warn("getRenderedServicePath: sfp not handled yet"); + } else { + rsp = getRenderedServicePathFromSfc(entry); + } + LOG.info("getRenderedServicePath: rsp: {}", rsp); + return rsp; + } + + private RenderedServicePath getRenderedServicePathFromRsp(String rspName) { + return sfcUtils.getRsp(rspName); + } + + private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) { + RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class); + LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect); + if (sfcRedirect == null) { + LOG.warn("processAClEntry: sfcRedirect is null"); + return null; + } + + String sfcName = sfcRedirect.getSfcName(); ServiceFunctionPath sfp = sfcUtils.getSfp(sfcName); if (sfp == null || sfp.getName() == null) { LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName); return null; } - LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcRedirect.getRedirectSfc(), sfp); + LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp); // If RSP doesn't exist, create an RSP. String sfpName = sfp.getName().getValue(); RenderedServicePath rsp = sfcUtils.getRspforSfp(sfpName); @@ -293,7 +465,8 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider List ovsdbTerminationPointAugmentations = southbound.getTerminationPointsOfBridge(bridgeNode); if (!ovsdbTerminationPointAugmentations.isEmpty()) { - for (OvsdbTerminationPointAugmentation terminationPointAugmentation : ovsdbTerminationPointAugmentations) { + for (OvsdbTerminationPointAugmentation terminationPointAugmentation : + ovsdbTerminationPointAugmentations) { if (terminationPointAugmentation.getInterfaceType() == SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(NETWORK_TYPE_VXLAN)) { if (!terminationPointAugmentation.getName().equals(vxGpePortName)) { @@ -314,7 +487,8 @@ public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider private long getOFPort(Node bridgeNode, String portName) { long ofPort = 0L; - OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName); + OvsdbTerminationPointAugmentation port = + southbound.extractTerminationPointAugmentation(bridgeNode, portName); if (port != null) { ofPort = southbound.getOFPort(port); } diff --git a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java index c597e5eb22..04877504d6 100644 --- a/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java +++ b/openstack/net-virt-sfc/impl/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/workaround/services/SfcClassifierService.java @@ -91,7 +91,6 @@ public class SfcClassifierService extends AbstractServiceInstance implements Con FlowBuilder flowBuilder = new FlowBuilder(); MatchBuilder matchBuilder = buildMatch(matches); - //flowBuilder.setMatch(matchBuilder.build()); flowBuilder.setMatch(MatchUtils.addNxRegMatch( matchBuilder, new MatchUtils.RegMatch(FlowUtils.REG_FIELD, FlowUtils.REG_VALUE_FROM_LOCAL)).build()); diff --git a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java index 76734d11d1..7657f2eee3 100644 --- a/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java +++ b/openstack/net-virt-sfc/it/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/sfc/utils/AclUtils.java @@ -46,7 +46,7 @@ public class AclUtils extends AbstractUtils { } public ActionsBuilder actionsBuilder(ActionsBuilder actionsBuilder, String sfcName) { - RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setRedirectSfc(sfcName); + RedirectToSfcBuilder redirectToSfcBuilder = new RedirectToSfcBuilder().setSfcName(sfcName); return actionsBuilder.addAugmentation(RedirectToSfc.class, redirectToSfcBuilder.build()); }