2 * Copyright (c) 2014, 2017 Ericsson 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.sfc.ofrenderer.processors;
11 import java.util.Iterator;
13 import org.opendaylight.sfc.ofrenderer.processors.SffGraph.SffGraphEntry;
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.sf.rev140701.service.functions.ServiceFunction;
16 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.SffDataPlaneLocator;
17 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarder.base.sff.data.plane.locator.DataPlaneLocatorBuilder;
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.MacAddressLocator;
20 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sl.rev140701.data.plane.locator.locator.type.MacBuilder;
22 public class SfcRspProcessorVlan extends SfcRspTransportProcessorBase {
23 private static final int VLAN_ID_INCR_HOP = 1;
24 private static final int VLAN_ID_INCR_RSP = 100;
25 private static int lastVlanId = 0;
28 * Set the RSP path egress DPL and SFF Hop Ingress DPLs for the VLAN
32 public void setRspTransports() {
33 int hopIncrement = VLAN_ID_INCR_HOP;
34 int transportData = lastVlanId + VLAN_ID_INCR_RSP;
35 lastVlanId = transportData;
37 Iterator<SffGraph.SffGraphEntry> sffGraphIter = sffGraph.getGraphEntryIterator();
38 while (sffGraphIter.hasNext()) {
39 SffGraph.SffGraphEntry entry = sffGraphIter.next();
40 LOG.debug("RspTransport entry: {}", entry);
42 if (entry.getSrcSff().equals(entry.getDstSff())) {
43 // It may be that multiple SFs are on the same SFF
44 // If so, we dont need to set the transports again
45 // Otherwise the SFF ingress DPL will be overwritten
49 DataPlaneLocatorBuilder dpl = new DataPlaneLocatorBuilder();
50 dpl.setTransport(rsp.getTransportType());
51 MacBuilder macBuilder = new MacBuilder();
52 macBuilder.setVlanId(transportData);
53 dpl.setLocatorType(macBuilder.build());
55 if (entry.getDstSff().equals(SffGraph.EGRESS)) {
56 sffGraph.setPathEgressDpl(entry.getPathId(), dpl.build());
58 sffGraph.setHopIngressDpl(entry.getDstSff(), entry.getPathId(), dpl.build());
60 transportData += hopIncrement;
65 // TransportIngress methods
69 * Configure the Transport Ingress flow for SFs.
72 * - RSP hop info used to create the flow
75 public void configureSfTransportIngressFlow(SffGraphEntry entry, SfDataPlaneLocator sfDpl) {
76 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
77 this.sfcFlowProgrammer.configureVlanTransportIngressFlow(sffNodeName);
81 * Configure the Transport Ingress flow for SFFs.
84 * - RSP hop info used to create the flow
87 public void configureSffTransportIngressFlow(SffGraphEntry entry, SffDataPlaneLocator dstSffDpl) {
88 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
89 this.sfcFlowProgrammer.configureVlanTransportIngressFlow(sffNodeName);
97 * Configure the Path Mapper flow for SFs.
100 * - RSP hop info used to create the flow
102 * - the particular SF DPL used to create the flow
105 public void configureSfPathMapperFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator sfDpl) {
106 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
107 Integer vlanTag = ((MacAddressLocator) sfDpl.getLocatorType()).getVlanId();
108 if (vlanTag != null) {
109 this.sfcFlowProgrammer.configureVlanPathMapperFlow(sffNodeName, vlanTag, entry.getPathId(), true);
114 * Configure the Path Mapper flow for SFFs.
117 * - RSP hop info used to create the flow
119 * - the particular SFF Hop DPL used to create the flow
122 public void configureSffPathMapperFlow(SffGraph.SffGraphEntry entry, DataPlaneLocator hopDpl) {
123 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
124 Integer vlanTag = ((MacAddressLocator) hopDpl.getLocatorType()).getVlanId();
125 if (vlanTag != null) {
126 this.sfcFlowProgrammer.configureVlanPathMapperFlow(sffNodeName, vlanTag, entry.getPathId(), false);
135 * Configure the Next Hop flow from an SFF to an SF.
138 * - RSP hop info used to create the flow
140 * - the particular SFF DPL used to create the flow
142 * - the particular SF DPL used to create the flow
145 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
146 SfDataPlaneLocator dstSfDpl) {
147 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
148 String srcMac = sfcProviderUtils.getDplPortInfoMac(srcSffDpl);
149 String dstMac = sfcProviderUtils.getSfDplMac(dstSfDpl);
150 this.sfcFlowProgrammer.configureMacNextHopFlow(sffNodeName, entry.getPathId(), srcMac, dstMac);
154 * Configure the Next Hop flow from an SF to an SFF.
157 * - RSP hop info used to create the flow
159 * - the particular SF DPL used to create the flow
161 * - the particular SFF DPL used to create the flow
164 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator srcSfDpl,
165 SffDataPlaneLocator dstSffDpl) {
166 // in this case, we use the SrcSff instead of the typical DstSff
167 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getSrcSff(), entry.getPathId());
168 String srcMac = sfcProviderUtils.getSfDplMac(srcSfDpl);
169 String dstMac = sfcProviderUtils.getDplPortInfoMac(dstSffDpl);
170 this.sfcFlowProgrammer.configureMacNextHopFlow(sffNodeName, entry.getPathId(), srcMac, dstMac);
174 * Configure the Next Hop flow from an SF to an SF.
177 * - RSP hop info used to create the flow
179 * - the particular SF DPL used to create the flow
181 * - the particular SF DPL used to create the flow
184 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator srcSfDpl,
185 SfDataPlaneLocator dstSfDpl) {
186 // in this case, we use the SrcSff instead of the typical DstSff
187 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getSrcSff(), entry.getPathId());
188 String srcMac = sfcProviderUtils.getSfDplMac(srcSfDpl);
189 String dstMac = sfcProviderUtils.getSfDplMac(dstSfDpl);
190 this.sfcFlowProgrammer.configureMacNextHopFlow(sffNodeName, entry.getPathId(), srcMac, dstMac);
194 * Configure the Next Hop flow from an SFF to an SFF.
197 * - RSP hop info used to create the flow
199 * - the particular SFF DPL used to create the flow
201 * - the particular SFF DPL used to create the flow
204 public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
205 SffDataPlaneLocator dstSffDpl) {
206 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
207 String srcMac = sfcProviderUtils.getDplPortInfoMac(srcSffDpl);
208 String dstMac = sfcProviderUtils.getDplPortInfoMac(dstSffDpl);
209 this.sfcFlowProgrammer.configureMacNextHopFlow(sffNodeName, entry.getPathId(), srcMac, dstMac);
213 // TransportEgress methods
217 * Configure the Transport Egress flow from an SFF to an SF.
220 * - RSP hop info used to create the flow
222 * - the particular SFF DPL used to create the flow
224 * - the particular SF DPL used to create the flow
226 * - Hop DPL used to create the flow
229 public void configureSfTransportEgressFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
230 SfDataPlaneLocator dstSfDpl, DataPlaneLocator hopDpl) {
231 Integer vlanTag = ((MacAddressLocator) hopDpl.getLocatorType()).getVlanId();
232 if (vlanTag == null) {
236 String srcOfsPortStr = sfcProviderUtils.getDplPortInfoPort(srcSffDpl);
237 if (srcOfsPortStr == null) {
238 throw new SfcRenderingException("configureSffTransportEgressFlow OFS port not avail for SFF ["
239 + entry.getDstSff() + "] sffDpl [" + srcSffDpl.getName().getValue() + "]");
242 // For the SF transport Egress flow, we'll write to the Dst SFF as
243 // opposed to typically writing to the Src SFF
244 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
245 String srcMac = sfcProviderUtils.getDplPortInfoMac(srcSffDpl);
246 String dstMac = sfcProviderUtils.getSfDplMac(dstSfDpl);
248 boolean doPktIn = false;
249 ServiceFunction sf = sfcProviderUtils.getServiceFunction(entry.getSf(), entry.getPathId());
250 // FIXME: I would caution against this approach. Instead you may want to
252 // ServiceFunctionType has "bidirectional" = True in future.
253 if (sf.getType().getValue().equals("tcp-proxy")) {
254 LOG.info("SfcRspProcessorVlan::configureSfTransportEgressFlow TCP PROXY");
255 // If the SF is a TCP Proxy, we need this additional flow for the
257 // - a flow that will also check for TCP Syn and do a PktIn
258 this.sfcFlowProgrammer.configureArpTransportIngressFlow(sffNodeName, srcMac);
262 this.sfcFlowProgrammer.configureVlanSfTransportEgressFlow(sffNodeName, srcMac, dstMac, vlanTag, srcOfsPortStr,
263 entry.getPathId(), doPktIn);
267 * Configure the Transport Egress flow from an SFF to an SFF.
270 * - RSP hop info used to create the flow
272 * - the particular SFF DPL used to create the flow
274 * - the particular SFF DPL used to create the flow
276 * - Hop DPL used to create the flow
279 public void configureSffTransportEgressFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
280 SffDataPlaneLocator dstSffDpl, DataPlaneLocator hopDpl) {
281 Integer vlanTag = ((MacAddressLocator) hopDpl.getLocatorType()).getVlanId();
282 if (vlanTag == null) {
286 String srcOfsPortStr = sfcProviderUtils.getDplPortInfoPort(srcSffDpl);
287 if (srcOfsPortStr == null) {
288 throw new SfcRenderingException("configureSffTransportEgressFlow OFS port not avail for SFF ["
289 + entry.getDstSff() + "] sffDpl [" + srcSffDpl.getName().getValue() + "]");
292 String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getSrcSff(), entry.getPathId());
293 String srcMac = sfcProviderUtils.getDplPortInfoMac(srcSffDpl);
294 String dstMac = sfcProviderUtils.getDplPortInfoMac(dstSffDpl);
295 if (entry.getDstSff().equals(SffGraph.EGRESS)) {
296 this.sfcFlowProgrammer.configureVlanLastHopTransportEgressFlow(sffNodeName, srcMac, dstMac, vlanTag,
297 srcOfsPortStr, entry.getPathId());
299 this.sfcFlowProgrammer.configureVlanTransportEgressFlow(sffNodeName, srcMac, dstMac, vlanTag, srcOfsPortStr,