f8e7a645f375de15cf565fff7933702e957b931b
[sfc.git] /
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise Development LP. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.sfc.ofrenderer.processors;
10
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;
20
21 public class SfcRspProcessorMacChaining extends SfcRspTransportProcessorBase {
22
23
24     /*
25     * Set the RSP path egress DPL and SFF Hop Ingress DPLs for
26     * the MAC Chainig considering connected SFF dictionary
27     */
28     @Override
29     public void setRspTransports() {
30         LOG.debug("SfcRspProcessorMacChaining - setRspTransports");
31
32         Iterator<SffGraph.SffGraphEntry> sffGraphIter = sffGraph.getGraphEntryIterator();
33
34         while (sffGraphIter.hasNext()) {
35
36             SffGraph.SffGraphEntry entry = sffGraphIter.next();
37             LOG.info("RspTransport entry: {}", entry.toString());
38
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
43                 continue;
44             }
45
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)) {
52
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());
59
60                 } else {
61                     sffGraph.setSffEgressDpl(entry.getSrcSff(),rsp.getPathId(), srcSffDplEgress.getName());
62                 }
63
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());
70
71                 } else {
72                     sffGraph.setSffEgressDpl(entry.getDstSff(),rsp.getPathId(), dstSffDplIngress.getName());
73                 }
74             }
75
76             dpl.setLocatorType(macBuilder.build());
77
78             if (entry.getDstSff().equals(SffGraph.EGRESS)) {
79                 sffGraph.setPathEgressDpl(entry.getPathId(), dpl.build());
80                 LOG.info("sffGraph {}", sffGraph.getPathEgressDpl(rsp.getPathId()).toString());
81             } else {
82                 sffGraph.setHopIngressDpl(entry.getDstSff(), entry.getPathId(), dpl.build());
83                 LOG.info("sffGraph {}", sffGraph.getHopIngressDpl(entry.getDstSff(), rsp.getPathId()).toString());
84             }
85         }
86     }
87
88     @Override
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);
94     }
95
96     @Override
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);
102     }
103
104     @Override
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");
108
109     }
110
111     @Override
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");
115
116     }
117
118
119
120     @Override
121     public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator srcSfDpl,
122                                      SfDataPlaneLocator dstSfDpl) {
123         LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sf {} to sf {} ", entry.getServiceIndex(),
124                 srcSfDpl == null
125                         ? "null" : srcSfDpl.getName().toString(),
126                 dstSfDpl == null
127                         ? "null" : dstSfDpl.getName().toString());
128         // nothing to do
129     }
130
131     @Override
132     public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
133                                      SffDataPlaneLocator dstSffDpl) {
134         LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sff {} to sff {}", entry.getServiceIndex(),
135                 srcSffDpl == null
136                         ? "null" : srcSffDpl.getName().toString(),
137                 dstSffDpl == null
138                         ? "null" : dstSffDpl.getName().toString());
139         // nothing to do
140     }
141
142     /**
143      * Configure the Next Hop flow from an SFF to an SF.
144      *
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
148      */
149     @Override
150     public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SffDataPlaneLocator srcSffDpl,
151                                      SfDataPlaneLocator dstSfDpl) {
152         LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sff {} to sf {}", entry.getServiceIndex(),
153                 srcSffDpl == null
154                         ? "null" : srcSffDpl.getName().toString(),
155                 dstSfDpl == null
156                         ? "null" : dstSfDpl.getName().toString());
157
158         String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
159
160         VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(entry.getPathId(), 0);
161
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();
165
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();
173             }
174         }
175
176         this.sfcFlowProgrammer.configureMacChainingNextHopFlow(sffNodeName, vmac, dstSfMac, nextVMac, isL2Transparent);
177
178     }
179
180     /**
181      * Configure the Next Hop flow from an SF to an SFF.
182      *
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
186      */
187     @Override
188     public void configureNextHopFlow(SffGraph.SffGraphEntry entry, SfDataPlaneLocator srcSfDpl,
189                                      SffDataPlaneLocator dstSffDpl) {
190         LOG.debug("SfcRspProcessorMacChaining - configureNextHopFlow {} sf {} to sff {}", entry.getServiceIndex(),
191                 srcSfDpl == null
192                         ? "null" : srcSfDpl.getName().toString(),
193                 dstSffDpl == null
194                         ? "null" : dstSffDpl.getName().toString());
195
196         VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(entry.getPathId(), 0);
197
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());
200
201         String vmac = hopMac.getHop(entry.getServiceIndex()).getValue();
202         String nextSfMac = null;
203         if (dstSffDpl != null) {
204             nextSfMac = sfcProviderUtils.getSffDplMac(dstSffDpl);
205         }
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();
213             }
214         }
215
216         this.sfcFlowProgrammer.configureMacChainingNextHopFlow(sffNodeName, vmac, nextSfMac, null, isL2Transparent);
217     }
218
219     /**
220      * Configure the Transport Egress flow from an SFF to an SF.
221      *
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
226      */
227     @Override
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(),
232                 srcSffDpl == null
233                         ? "null" : srcSffDpl.getName().toString(),
234                 dstSfDpl == null
235                         ? "null" : dstSfDpl.getName().toString());
236
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() + "]");
241         }
242
243         String sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
244
245         String dstMac = sfcProviderUtils.getSfDplMac(dstSfDpl);
246
247         LOG.info("SFFNodeName {}", sffNodeName);
248         this.sfcFlowProgrammer.configureMacChainingSfTransportEgressFlow(sffNodeName, dstMac, srcOfsPortStr, null);
249
250     }
251
252     /**
253      * Configure the Transport Egress flow from an SFF to an SFF.
254      *
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
259      */
260     @Override
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(),
265                 srcSffDpl == null
266                         ? "null" : srcSffDpl.getName().toString(),
267                 dstSffDpl == null
268                         ? "null" : dstSffDpl.getName().toString());
269
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() + "]");
274         }
275
276         // For the SF transport Ingress flow, we'll write to the Dst SFF as opposed to typically writing to the Src SFF
277         String sffNodeName;
278         if (entry.getSrcSff().equals(SffGraph.INGRESS)) {
279             sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getDstSff(), entry.getPathId());
280         } else {
281             sffNodeName = sfcProviderUtils.getSffOpenFlowNodeName(entry.getSrcSff(), entry.getPathId());
282
283         }
284
285         String dstMac = null;
286         if (dstSffDpl != null) {
287             dstMac = sfcProviderUtils.getSffDplMac(dstSffDpl);
288         }
289         if (dstMac == null) {
290             // if the dstMac is null this is not a valid flow
291             return;
292         }
293
294         VirtualMacAddress hopMac = VirtualMacAddress.getForwardAddress(entry.getPathId(), 0);
295         String vmac = hopMac.getHop(entry.getServiceIndex()).getValue();
296
297         LOG.info("SFFNodeName {}", sffNodeName);
298
299         this.sfcFlowProgrammer.configureMacChainingSfTransportEgressFlow(sffNodeName, dstMac, srcOfsPortStr, vmac);
300     }
301
302 }