2 * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc.workaround;
11 import com.google.common.base.Preconditions;
12 import java.util.List;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
16 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
17 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
19 import org.opendaylight.ovsdb.openstack.netvirt.sfc.INetvirtSfcOF13Provider;
20 import org.opendaylight.ovsdb.openstack.netvirt.sfc.ISfcClassifierService;
21 import org.opendaylight.ovsdb.openstack.netvirt.sfc.NshUtils;
22 import org.opendaylight.ovsdb.openstack.netvirt.sfc.SfcUtils;
23 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
24 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
25 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
26 import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
27 import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
28 import org.opendaylight.sfc.provider.api.SfcProviderServiceFunctionAPI;
29 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
30 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.Ip;
31 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
32 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.path.first.hop.info.RenderedServicePathFirstHop;
34 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
35 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
36 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
37 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
38 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.Acl;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.Ace;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.Matches;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.Classifier;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.Sff;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
56 import org.osgi.framework.ServiceReference;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
60 public class NetvirtSfcWorkaroundOF13Provider implements INetvirtSfcOF13Provider {
61 private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcWorkaroundOF13Provider.class);
62 private volatile NodeCacheManager nodeCacheManager;
63 private volatile Southbound southbound;
64 private volatile ISfcClassifierService sfcClassifierService;
65 private static final short SFC_TABLE = 150;
66 private static final int GPE_PORT = 6633;
67 private static final String NETWORK_TYPE_VXLAN = "vxlan";
68 private MdsalUtils mdsalUtils;
69 private SfcUtils sfcUtils;
70 private static final String VXGPE = "vxgpe";
71 private static final String TUNNEL_DST = "192.168.120.31";
72 private static final String TUNNEL_VNID = "10";
73 public static final String TUNNEL_ENDPOINT_KEY = "local_ip";
75 public NetvirtSfcWorkaroundOF13Provider(final DataBroker dataBroker, MdsalUtils mdsalUtils, SfcUtils sfcUtils) {
76 Preconditions.checkNotNull(dataBroker, "Input dataBroker cannot be NULL!");
77 Preconditions.checkNotNull(mdsalUtils, "Input mdsalUtils cannot be NULL!");
78 Preconditions.checkNotNull(sfcUtils, "Input sfcUtils cannot be NULL!");
80 this.mdsalUtils = mdsalUtils;
81 this.sfcUtils = sfcUtils;
82 //this.setDependencies(null);
85 public void setSfcClassifierService(ISfcClassifierService sfcClassifierService) {
86 this.sfcClassifierService = sfcClassifierService;
90 public void addClassifierRules(Bridge bridge, Acl acl) {
95 public void addClassifierRules(Bridges bridges, Acl acl) {
96 Preconditions.checkNotNull(bridges, "Input bridges cannot be NULL!");
97 Preconditions.checkNotNull(acl, "Input acl cannot be NULL!");
101 public void removeClassifierRules(Sff sff, Acl acl) {
106 public void addClassifierRules(Acl acl) {
107 String aclName = acl.getAclName();
108 Classifiers classifiers = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, sfcUtils.getClassifierIid());
109 if (classifiers == null) {
110 LOG.debug("addClassifierRules: No Classifiers found");
114 LOG.debug("addClassifierRules: Classifiers: {}", classifiers);
115 for (Classifier classifier : classifiers.getClassifier()) {
116 if (classifier.getAcl().equals(aclName)) {
117 for (Ace ace : acl.getAccessListEntries().getAce()) {
118 processAclEntry(ace);
125 public void removeClassifierRules(Acl acl) {
129 private void processAclEntry(Ace entry) {
130 Matches matches = entry.getMatches();
131 Preconditions.checkNotNull(matches, "Input bridges cannot be NULL!");
133 RenderedServicePath rsp = getRenderedServicePath(entry);
135 LOG.warn("Failed to get renderedServicePatch for entry: {}", entry);
139 handleRenderedServicePath(rsp, entry);
142 private void handleRenderedServicePathOld(RenderedServicePath rsp, Ace entry) {
143 LOG.info("handleRenderedServicePath: RSP: {}", rsp);
145 Matches matches = entry.getMatches();
146 if (matches == null) {
147 LOG.warn("processAclEntry: matches not found");
151 List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
152 if (pathHopList.isEmpty()) {
153 LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
156 LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
158 final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
159 if (bridgeNodes == null || bridgeNodes.isEmpty()) {
160 LOG.warn("handleRenderedServicePath: There are no bridges to process");
163 for (Node bridgeNode : bridgeNodes) {
164 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
165 if (ovsdbBridgeAugmentation == null) {
168 long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
169 if (vxGpeOfPort == 0L) {
170 LOG.warn("programAclEntry: Could not identify tunnel port {} -> OF ({}) on {}",
171 VXGPE, vxGpeOfPort, bridgeNode);
174 long dataPathId = southbound.getDataPathId(bridgeNode);
175 if (dataPathId == 0L) {
176 LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
180 // Find the first Hop within an RSP.
181 // The classifier flow needs to send all matched traffic to this first hop SFF.
182 RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
183 .readRenderedServicePathFirstHop(rsp.getName());
185 LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
186 LOG.debug("handleRenderedServicePath: First Hop IPAddress = {}, Port = {}",
187 firstRspHop.getIp().getIpv4Address().getValue(),
188 firstRspHop.getPort().getValue());
190 NshUtils nshHeader = new NshUtils();
191 nshHeader.setNshMetaC1(NshUtils.convertIpAddressToLong(new Ipv4Address(TUNNEL_DST)));
192 nshHeader.setNshMetaC2(Long.parseLong(TUNNEL_VNID)); // get from register //get from
193 nshHeader.setNshNsp(rsp.getPathId());
195 RenderedServicePathHop firstHop = pathHopList.get(0);
196 RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
197 ServiceFunction serviceFunction =
198 SfcProviderServiceFunctionAPI.readServiceFunction(
199 SfName.getDefaultInstance(firstHop.getServiceFunctionName().getValue()));
200 if (serviceFunction == null) {
201 LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
202 firstHop.getServiceFunctionName().getValue(), bridgeNode);
206 nshHeader.setNshNsi(firstHop.getServiceIndex());
207 // workaround: bypass sff and got directly to sf
208 //nshHeader.setNshTunIpDst(firstRspHop.getIp().getIpv4Address());
209 IpAddress sfIpAddress = sfcUtils.getSfIpAddress(serviceFunction);
210 String sfDplName = sfcUtils.getSfDplName(serviceFunction);
211 //sfcUtils.getSfIp(firstHop.getServiceFunctionName().getValue());
212 nshHeader.setNshTunIpDst(sfIpAddress.getIpv4Address());
213 nshHeader.setNshTunUdpPort(firstRspHop.getPort());
214 LOG.debug("handleRenderedServicePath: NSH Header = {}", nshHeader);
216 sfcClassifierService.programIngressClassifier(dataPathId, entry.getRuleName(), matches,
217 nshHeader, vxGpeOfPort, true);
219 sfcClassifierService.program_sfEgress(dataPathId, GPE_PORT, true);
220 long sfOfPort = getSfPort(bridgeNode, sfDplName);
222 String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
223 String sfIpString = new String(sfIpAddress.getValue());
224 LOG.info("handleRenderedServicePath: sfDplName: {}, sfMac: {}, sfOfPort: {}, sfIpAddress: {}",
225 sfDplName, sfMac, sfOfPort, sfIpString);
226 if (sfMac != null) { // install if the sf is on this bridge, expand when using multiple bridges
227 sfcClassifierService.program_sfIngress(dataPathId, GPE_PORT, sfOfPort, sfIpString, sfDplName, true);
228 sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpString, true);
231 short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
232 sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
233 lastServiceindex, sfOfPort, 0, true);
234 sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
235 lastServiceindex, sfOfPort, 0, true);
237 sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
241 private void handleRenderedServicePath(RenderedServicePath rsp, Ace entry) {
242 LOG.info("handleRenderedServicePath: RSP: {}", rsp);
244 Matches matches = entry.getMatches();
245 if (matches == null) {
246 LOG.warn("processAclEntry: matches not found");
250 List<RenderedServicePathHop> pathHopList = rsp.getRenderedServicePathHop();
251 if (pathHopList.isEmpty()) {
252 LOG.warn("handleRenderedServicePath: RSP {} has empty hops!!", rsp.getName());
255 LOG.info("handleRenderedServicePath: pathHopList: {}", pathHopList);
257 RenderedServicePathFirstHop firstRspHop = SfcProviderRenderedPathAPI
258 .readRenderedServicePathFirstHop(rsp.getName());
259 LOG.info("handleRenderedServicePath: firstRspHop: {}", firstRspHop);
261 RenderedServicePathHop firstHop = pathHopList.get(0);
262 RenderedServicePathHop lastHop = pathHopList.get(pathHopList.size()-1);
264 final List<Node> bridgeNodes = nodeCacheManager.getBridgeNodes();
265 if (bridgeNodes == null || bridgeNodes.isEmpty()) {
266 LOG.warn("handleRenderedServicePath: There are no bridges to process");
269 for (RenderedServicePathHop hop : pathHopList) {
270 for (Node bridgeNode : bridgeNodes) {
271 // ignore bridges other than br-int
272 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = southbound.getBridge(bridgeNode, "br-int");
273 if (ovsdbBridgeAugmentation == null) {
276 long vxGpeOfPort = getOFPort(bridgeNode, VXGPE);
277 if (vxGpeOfPort == 0L) {
278 LOG.warn("programAclEntry: Could not identify gpe vtep {} -> OF ({}) on {}",
279 VXGPE, vxGpeOfPort, bridgeNode);
282 long dataPathId = southbound.getDataPathId(bridgeNode);
283 if (dataPathId == 0L) {
284 LOG.warn("programAclEntry: Could not identify datapathId on {}", bridgeNode);
288 ServiceFunction serviceFunction =
289 SfcProviderServiceFunctionAPI.readServiceFunction(firstHop.getServiceFunctionName());
290 if (serviceFunction == null) {
291 LOG.warn("programAclEntry: Could not identify ServiceFunction {} on {}",
292 firstHop.getServiceFunctionName().getValue(), bridgeNode);
295 ServiceFunctionForwarder serviceFunctionForwarder =
296 SfcProviderServiceForwarderAPI
297 .readServiceFunctionForwarder(hop.getServiceFunctionForwarder());
298 if (serviceFunctionForwarder == null) {
299 LOG.warn("programAclEntry: Could not identify ServiceFunctionForwarder {} on {}",
300 firstHop.getServiceFunctionName().getValue(), bridgeNode);
304 handleSf(bridgeNode, serviceFunction);
305 handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, firstHop, lastHop,
306 entry.getRuleName(), matches, vxGpeOfPort, rsp);
307 if (firstHop == lastHop) {
308 handleSff(bridgeNode, serviceFunctionForwarder, serviceFunction, hop, null, lastHop,
309 entry.getRuleName(), matches, vxGpeOfPort, rsp);
315 private void handleSff(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder,
316 ServiceFunction serviceFunction,
317 RenderedServicePathHop hop,
318 RenderedServicePathHop firstHop,
319 RenderedServicePathHop lastHop,
320 String ruleName, Matches matches,
321 long vxGpeOfPort, RenderedServicePath rsp) {
322 long dataPathId = southbound.getDataPathId(bridgeNode);
324 if (hop == firstHop) {
325 LOG.info("handleSff: first hop processing {} - {}",
326 bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
327 NshUtils nshHeader = new NshUtils();
328 nshHeader.setNshNsp(rsp.getPathId());
329 nshHeader.setNshNsi(firstHop.getServiceIndex());
330 if (isSffOnBridge(bridgeNode, serviceFunctionForwarder)) {
331 LOG.info("handleSff: sff and bridge are the same: {} - {}, skipping first sff",
332 bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
333 Ip ip = sfcUtils.getSfIp(serviceFunction);
334 nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
335 nshHeader.setNshTunUdpPort(ip.getPort());
337 LOG.info("handleSff: sff and bridge are not the same: {} - {}, sending to first sff",
338 bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
339 Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
340 nshHeader.setNshTunIpDst(ip.getIp().getIpv4Address());
341 nshHeader.setNshTunUdpPort(ip.getPort());
343 sfcClassifierService.programIngressClassifier(dataPathId, ruleName, matches,
344 nshHeader, vxGpeOfPort, true);
345 } else if (hop == lastHop) {
346 LOG.info("handleSff: last hop processing {} - {}",
347 bridgeNode.getNodeId(), serviceFunctionForwarder.getName());
348 short lastServiceindex = (short)((lastHop.getServiceIndex()).intValue() - 1);
349 String sfDplName = sfcUtils.getSfDplName(serviceFunction);
350 long sfOfPort = getSfPort(bridgeNode, sfDplName);
351 sfcClassifierService.programEgressClassifier(dataPathId, vxGpeOfPort, rsp.getPathId(),
352 lastServiceindex, sfOfPort, 0, true);
353 sfcClassifierService.programEgressClassifierBypass(dataPathId, vxGpeOfPort, rsp.getPathId(),
354 lastServiceindex, sfOfPort, 0, true);
356 // add typical sff flows
359 sfcClassifierService.programSfcTable(dataPathId, vxGpeOfPort, SFC_TABLE, true);
362 void handleSf(Node bridgeNode, ServiceFunction serviceFunction) {
363 if (isSfOnBridge(bridgeNode, serviceFunction)) {
364 LOG.info("handleSf: sf and bridge are on the same node: {} - {}, adding workaround and arp",
365 bridgeNode.getNodeId(), serviceFunction.getName());
366 long dataPathId = southbound.getDataPathId(bridgeNode);
367 Ip ip = sfcUtils.getSfIp(serviceFunction);
368 String sfIpAddr = String.valueOf(ip.getIp().getValue());
369 int sfIpPort = ip.getPort().getValue(); //GPE_PORT
370 String sfDplName = sfcUtils.getSfDplName(serviceFunction);
371 long sfOfPort = getSfPort(bridgeNode, sfDplName);
372 String sfMac = getMacFromExternalIds(bridgeNode, sfDplName);
374 LOG.warn("handleSff: could not find mac for {} on {}", sfDplName, bridgeNode);
377 //should be sffdplport, but they should all be the same 6633/4790
378 sfcClassifierService.program_sfEgress(dataPathId, sfIpPort, true);
379 sfcClassifierService.program_sfIngress(dataPathId, sfIpPort, sfOfPort, sfIpAddr, sfDplName, true);
380 sfcClassifierService.programStaticArpEntry(dataPathId, 0L, sfMac, sfIpAddr, true);
384 private boolean isSffOnBridge(Node bridgeNode, ServiceFunctionForwarder serviceFunctionForwarder) {
385 String local_ip = "";
386 Ip ip = sfcUtils.getSffIp(serviceFunctionForwarder);
387 Node ovsdbNode = southbound.readOvsdbNode(bridgeNode);
388 if (ovsdbNode != null) {
389 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
390 if (ovsdbNodeAugmentation != null && ovsdbNodeAugmentation.getOpenvswitchOtherConfigs() != null) {
391 southbound.getOtherConfig(ovsdbNode, OvsdbTables.OPENVSWITCH, TUNNEL_ENDPOINT_KEY);
395 return local_ip.equals(String.valueOf(ip.getIp().getValue()));
398 private boolean isSfOnBridge(Node bridgeNode, ServiceFunction serviceFunction) {
399 String sfDplName = sfcUtils.getSfDplName(serviceFunction);
400 long sfOfPort = getSfPort(bridgeNode, sfDplName);
401 return sfOfPort != 0L;
404 private RenderedServicePath getRenderedServicePath (Ace entry) {
405 RenderedServicePath rsp = null;
406 RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
407 LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
408 if (sfcRedirect == null) {
409 LOG.warn("processAClEntry: sfcRedirect is null");
413 if (sfcRedirect.getRspName() != null) {
414 rsp = getRenderedServicePathFromRsp(sfcRedirect.getRspName());
415 } else if (sfcRedirect.getSfpName() != null) {
416 LOG.warn("getRenderedServicePath: sfp not handled yet");
418 rsp = getRenderedServicePathFromSfc(entry);
420 LOG.info("getRenderedServicePath: rsp: {}", rsp);
424 private RenderedServicePath getRenderedServicePathFromRsp(String rspName) {
425 return sfcUtils.getRsp(rspName);
428 private RenderedServicePath getRenderedServicePathFromSfc (Ace entry) {
429 RedirectToSfc sfcRedirect = entry.getActions().getAugmentation(RedirectToSfc.class);
430 LOG.debug("Processing ACL entry = {} sfcRedirect = {}", entry.getRuleName(), sfcRedirect);
431 if (sfcRedirect == null) {
432 LOG.warn("processAClEntry: sfcRedirect is null");
436 String sfcName = sfcRedirect.getSfcName();
437 ServiceFunctionPath sfp = sfcUtils.getSfp(sfcName);
438 if (sfp == null || sfp.getName() == null) {
439 LOG.warn("There is no configured SFP with sfcName = {}; so skip installing the ACL entry!!", sfcName);
443 LOG.debug("Processing Redirect to SFC = {}, SFP = {}", sfcName, sfp);
444 // If RSP doesn't exist, create an RSP.
445 String sfpName = sfp.getName().getValue();
446 RenderedServicePath rsp = sfcUtils.getRspforSfp(sfpName);
447 String rspName = sfp.getName().getValue() + "_rsp";
449 LOG.info("No configured RSP corresponding to SFP = {}, Creating new RSP = {}", sfpName, rspName);
450 CreateRenderedPathInput rspInput = new CreateRenderedPathInputBuilder()
451 .setParentServiceFunctionPath(sfpName)
453 .setSymmetric(sfp.isSymmetric())
455 rsp = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, rspInput);
457 LOG.warn("failed to add RSP");
461 // If SFP is symmetric, create RSP in the reverse direction.
462 if (sfp.isSymmetric()) {
463 LOG.info("SFP = {} is symmetric, installing RSP in the reverse direction!!", sfpName);
464 String rspNameRev = rspName + "-Reverse";
465 RenderedServicePath rspReverse = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
466 sfcUtils.getRspId(rspNameRev));
467 if (rspReverse == null) {
468 rspReverse = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
469 if (rspReverse == null) {
470 LOG.warn("failed to add reverse RSP");
479 // loop through all ports looking for vxlan types, skip vxgpe, keep the rest
480 // first pass we only have two tunnels: one for normal vxlan and the other for gpe
481 // so just return the first non-gpe vxlan port
482 private long getTunnelOfPort(Node bridgeNode, String vxGpePortName) {
484 List<OvsdbTerminationPointAugmentation> ovsdbTerminationPointAugmentations =
485 southbound.getTerminationPointsOfBridge(bridgeNode);
486 if (!ovsdbTerminationPointAugmentations.isEmpty()) {
487 for (OvsdbTerminationPointAugmentation terminationPointAugmentation :
488 ovsdbTerminationPointAugmentations) {
489 if (terminationPointAugmentation.getInterfaceType() ==
490 SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(NETWORK_TYPE_VXLAN)) {
491 if (!terminationPointAugmentation.getName().equals(vxGpePortName)) {
492 port = terminationPointAugmentation.getOfport();
501 private long getSfPort(Node bridgeNode, String sfPortName) {
503 port = getOFPort(bridgeNode, sfPortName);
507 private long getOFPort(Node bridgeNode, String portName) {
509 OvsdbTerminationPointAugmentation port =
510 southbound.extractTerminationPointAugmentation(bridgeNode, portName);
512 ofPort = southbound.getOFPort(port);
515 for (int i = 0; i < 5; i++) {
516 LOG.info("Looking for ofPort {}, try: {}", portName, i);
518 TerminationPoint tp = southbound.readTerminationPoint(bridgeNode, null, portName);
520 port = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
522 ofPort = southbound.getOFPort(port);
529 } catch (InterruptedException e) {
537 private String getMacFromOptions(Node bridgeNode, String portName) {
539 OvsdbTerminationPointAugmentation port = southbound.extractTerminationPointAugmentation(bridgeNode, portName);
540 LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
541 if (port != null && port.getOptions() != null) {
542 //mac = southbound.getOptionsValue(port.getOptions(), EXTERNAL_ID_VM_MAC);
543 for (Options option : port.getOptions()) {
544 LOG.info("getMac: option: {}", option);
545 if (option.getOption().equals(Constants.EXTERNAL_ID_VM_MAC)) {
546 mac = option.getValue();
554 private String getMacFromExternalIds(Node bridgeNode, String portName) {
556 OvsdbTerminationPointAugmentation port = southbound.getTerminationPointOfBridge(bridgeNode, portName);
557 LOG.info("getMac: portName: {}, bridgeNode: {},,, port: {}", portName, bridgeNode, port);
558 if (port != null && port.getInterfaceExternalIds() != null) {
559 mac = southbound.getInterfaceExternalIdsValue(port, Constants.EXTERNAL_ID_VM_MAC);
565 public void setDependencies(ServiceReference serviceReference) {
566 nodeCacheManager = (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this);
567 southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
568 sfcClassifierService =
569 (ISfcClassifierService) ServiceHelper.getGlobalInstance(ISfcClassifierService.class, this);
570 LOG.info("sfcClassifierService= {}", sfcClassifierService);