2 * Copyright (c) 2016 Hewlett Packard Enterprise Development LP. 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.sfc.ofrenderer.processors;
11 import java.util.Iterator;
12 import org.opendaylight.sfc.util.macchaining.SfcModelUtil;
13 import org.opendaylight.sfc.util.macchaining.VirtualMacAddress;
14 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.base.SfDataPlaneLocator;
15 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocator;
16 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.sff.data.plane.locator.DataPlaneLocatorBuilder;
17 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.service.function.types.ServiceFunctionType;
18 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.DataPlaneLocator;
19 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.MacBuilder;
21 public class SfcRspProcessorMacChaining extends SfcRspTransportProcessorBase {
25 * Set the RSP path egress DPL and SFF Hop Ingress DPLs for
26 * the MAC Chainig considering connected SFF dictionary
29 public void setRspTransports() {
30 LOG.debug("SfcRspProcessorMacChaining - setRspTransports");
32 Iterator<SffGraph.SffGraphEntry> sffGraphIter = sffGraph.getGraphEntryIterator();
34 while (sffGraphIter.hasNext()) {
36 SffGraph.SffGraphEntry entry = sffGraphIter.next();
37 LOG.info("RspTransport entry: {}", entry.toString());
39 if (entry.getSrcSff().equals(entry.getDstSff())) {
40 // It may be that multiple SFs are on the same SFF
41 // If so, we dont need to set the transports again
42 // Otherwise the SFF ingress DPL will be overwritten
46 DataPlaneLocatorBuilder dpl = new DataPlaneLocatorBuilder();
47 dpl.setTransport(rsp.getTransportType());
48 MacBuilder macBuilder = new MacBuilder();
49 if (!entry.getDstSff().equals(entry.getSrcSff())
50 && !entry.getSrcSff().equals(SffGraph.INGRESS)
51 && !entry.getDstSff().equals(SffGraph.EGRESS)) {
53 // setting Egress DPL of source SFF
54 SffDataPlaneLocator srcSffDplEgress = SfcModelUtil.searchSrcDplInConnectedSffs(
55 entry.getSrcSff(), entry.getDstSff());
56 if (srcSffDplEgress == null) {
57 LOG.error(" cannot find SFF dictionary in classifier {} to {} ",
58 entry.getSrcSff(), entry.getDstSff());
61 sffGraph.setSffEgressDpl(entry.getSrcSff(),rsp.getPathId(), srcSffDplEgress.getName());
64 // setting Ingress DPL of destination SFF
65 SffDataPlaneLocator dstSffDplIngress = SfcModelUtil.searchSrcDplInConnectedSffs(
66 entry.getDstSff(), entry.getSrcSff());
67 if (dstSffDplIngress == null) {
68 LOG.error(" cannot find SFF dictionary in classifier {} to {} ",
69 entry.getDstSff(), entry.getSrcSff());
72 sffGraph.setSffEgressDpl(entry.getDstSff(),rsp.getPathId(), dstSffDplIngress.getName());
76 dpl.setLocatorType(macBuilder.build());
78 if (entry.getDstSff().equals(SffGraph.EGRESS)) {
79 sffGraph.setPathEgressDpl(entry.getPathId(), dpl.build());
80 LOG.info("sffGraph {}", sffGraph.getPathEgressDpl(rsp.getPathId()).toString());
82 sffGraph.setHopIngressDpl(entry.getDstSff(), entry.getPathId(), dpl.build());
83 LOG.info("sffGraph {}", sffGraph.getHopIngressDpl(entry.getDstSff(), rsp.getPathId()).toString());
89 public void configureSfTransportIngressFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator sfDpl) {
90 LOG.debug("SfcRspProcessorMacChaining - "
91 + "configure-Sf-TransportIngressFlow nothing to do here, just go to next table");
92 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
93 this.sfcFlowProgrammer.configureMacChainingTransportIngressFlow(sffNodeName);
97 public void configureSffTransportIngressFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator dstSffDpl) {
98 LOG.debug("SfcRspProcessorMacChaining - "
99 + "configure-Sff-TransportIngressFlow nothing to do here, just go to next table");
100 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
101 this.sfcFlowProgrammer.configureMacChainingTransportIngressFlow(sffNodeName);
105 public void configureSfPathMapperFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator sfDpl) {
106 LOG.debug("SfcRspProcessorMacChaining - "
107 + "configure-Sf-PathMapperFlow nothing to do here, just got to next table");
112 public void configureSffPathMapperFlow(SffGraph.SffGraphEntry entry, DataPlaneLocator hopDpl) {
113 LOG.debug("SfcRspProcessorMacChaining - "
114 + "configure-Sff-PathMapperFlow nothing to do here, just got to next table");
121 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator srcSfDpl,
122 SfDataPlaneLocator dstSfDpl) {
123 LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sf {} to sf {} ", entry.getServiceIndex(),
125 ? "null" : srcSfDpl.getName().toString(),
127 ? "null" : dstSfDpl.getName().toString());
132 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
133 SffDataPlaneLocator dstSffDpl) {
134 LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sff {} to sff {}", entry.getServiceIndex(),
136 ? "null" : srcSffDpl.getName().toString(),
138 ? "null" : dstSffDpl.getName().toString());
143 * Configure the Next Hop flow from an SFF to an SF.
145 * @param entry - RSP hop info used to create the flow
146 * @param srcSffDpl - the particular SFF DPL used to create the flow
147 * @param dstSfDpl - the particular SF DPL used to create the flow
150 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
151 SfDataPlaneLocator dstSfDpl) {
152 LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sff {} to sf {}", entry.getServiceIndex(),
154 ? "null" : srcSffDpl.getName().toString(),
156 ? "null" : dstSfDpl.getName().toString());
158 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
160 VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(entry.getPathId(), 0);
162 String vmac = hopMac.getHop(entry.getServiceIndex()).getValue();
163 String dstSfMac = dstSfDpl == null ? null : sfcProviderUtils.getSfDplMac(dstSfDpl);
164 String nextVMac = hopMac.getHop((short)(entry.getServiceIndex() - 1)).getValue();
166 boolean isL2Transparent = false;
167 if (entry.getPrevSf() != null) {
168 ServiceFunctionType serviceFunctionType = sfcProviderUtils.getServiceFunctionType(
169 entry.getPrevSf(), entry.getPathId());
170 //if L2 Transparent boolean is not filled, assume it is not L2 transparent
171 if (serviceFunctionType.isL2Transparent() != null) {
172 isL2Transparent = serviceFunctionType.isL2Transparent();
176 this.sfcFlowProgrammer.configureMacChainingNextHopFlow(sffNodeName, vmac, dstSfMac, nextVMac, isL2Transparent);
181 * Configure the Next Hop flow from an SF to an SFF.
183 * @param entry - RSP hop info used to create the flow
184 * @param srcSfDpl - the particular SF DPL used to create the flow
185 * @param dstSffDpl - the particular SFF DPL used to create the flow
188 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator srcSfDpl,
189 SffDataPlaneLocator dstSffDpl) {
190 LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sf {} to sff {}", entry.getServiceIndex(),
192 ? "null" : srcSfDpl.getName().toString(),
194 ? "null" : dstSffDpl.getName().toString());
196 VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(entry.getPathId(), 0);
198 // as we are changing SFF need to write rule on srcSFF to forward packet to dstSFF
199 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getSrcSff(), entry.getPathId());
201 String vmac = hopMac.getHop(entry.getServiceIndex()).getValue();
202 String nextSfMac = null;
203 if (dstSffDpl != null) {
204 nextSfMac = sfcProviderUtils.getSffDplMac(dstSffDpl);
206 boolean isL2Transparent = false;
207 if (entry.getPrevSf() != null) {
208 ServiceFunctionType serviceFunctionType = sfcProviderUtils.getServiceFunctionType(
209 entry.getPrevSf(), entry.getPathId());
210 //if L2 Transparent boolean is not filled, asume it is not L2 transparent
211 if (serviceFunctionType.isL2Transparent() != null) {
212 isL2Transparent = serviceFunctionType.isL2Transparent();
216 this.sfcFlowProgrammer.configureMacChainingNextHopFlow(sffNodeName, vmac, nextSfMac, null, isL2Transparent);
220 * Configure the Transport Egress flow from an SFF to an SF.
222 * @param entry - RSP hop info used to create the flow
223 * @param srcSffDpl - the particular SFF DPL used to create the flow
224 * @param dstSfDpl - the particular SF DPL used to create the flow
225 * @param hopDpl - Hop DPL used to create the flow
228 public void configureSfTransportEgressFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
229 SfDataPlaneLocator dstSfDpl, DataPlaneLocator hopDpl) {
230 LOG.debug("SfcRspProcessorMacChaining - configureSfTransportEgressFlow {} srcSffDpl {} to dstSfDpl {}",
231 entry.getServiceIndex(),
233 ? "null" : srcSffDpl.getName().toString(),
235 ? "null" : dstSfDpl.getName().toString());
237 String srcOfsPortStr = sfcProviderUtils.getDplPortInfoPort(srcSffDpl);
238 if (srcOfsPortStr == null) {
239 throw new SfcRenderingException("configureSffTransportEgressFlow OFS port not avail for SFF ["
240 + entry.getDstSff() + "] sffDpl [" + srcSffDpl.getName().getValue() + "]");
243 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
245 String dstMac = sfcProviderUtils.getSfDplMac(dstSfDpl);
247 LOG.info("SFFNodeName {}", sffNodeName);
248 this.sfcFlowProgrammer.configureMacChainingSfTransportEgressFlow(sffNodeName, dstMac, srcOfsPortStr, null);
253 * Configure the Transport Egress flow from an SFF to an SFF.
255 * @param entry - RSP hop info used to create the flow
256 * @param srcSffDpl - the particular SFF DPL used to create the flow
257 * @param dstSffDpl - the particular SFF DPL used to create the flow
258 * @param hopDpl - Hop DPL used to create the flow
261 public void configureSffTransportEgressFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
262 SffDataPlaneLocator dstSffDpl, DataPlaneLocator hopDpl) {
263 LOG.debug("SfcRspProcessorMacChaining - configureSffTransportEgressFlow {} srcSffDpl {} to dstSffDpl {}",
264 entry.getServiceIndex(),
266 ? "null" : srcSffDpl.getName().toString(),
268 ? "null" : dstSffDpl.getName().toString());
270 String srcOfsPortStr = sfcProviderUtils.getDplPortInfoPort(srcSffDpl);
271 if (srcOfsPortStr == null) {
272 throw new SfcRenderingException("configureSffTransportEgressFlow OFS port not avail for SFF ["
273 + entry.getDstSff() + "] sffDpl [" + srcSffDpl.getName().getValue() + "]");
276 // For the SF transport Ingress flow, we'll write to the Dst SFF as opposed to typically writing to the Src SFF
278 if (entry.getSrcSff().equals(SffGraph.INGRESS)) {
279 sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
281 sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getSrcSff(), entry.getPathId());
285 String dstMac = null;
286 if (dstSffDpl != null) {
287 dstMac = sfcProviderUtils.getSffDplMac(dstSffDpl);
289 if (dstMac == null) {
290 // if the dstMac is null this is not a valid flow
294 VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(entry.getPathId(), 0);
295 String vmac = hopMac.getHop(entry.getServiceIndex()).getValue();
297 LOG.info("SFFNodeName {}", sffNodeName);
299 this.sfcFlowProgrammer.configureMacChainingSfTransportEgressFlow(sffNodeName, dstMac, srcOfsPortStr, vmac);