blob: 99d77a69b6a56cac9e5972bf0480c8c3f0f4d8e1 [file] [log] [blame]
Praseed Balakrishnane48aa682014-10-08 17:31:37 -07001package org.onlab.onos.openflow.drivers.impl;
2
3import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
4import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
5import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
6import org.onlab.onos.openflow.controller.Dpid;
7import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
8import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
9import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
10import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
11import org.projectfloodlight.openflow.protocol.OFErrorMsg;
12import org.projectfloodlight.openflow.protocol.OFMatchV3;
13import org.projectfloodlight.openflow.protocol.OFMessage;
14import org.projectfloodlight.openflow.protocol.OFOxmList;
15import org.projectfloodlight.openflow.protocol.OFPortDesc;
16import org.projectfloodlight.openflow.protocol.OFPortOptical;
17import org.projectfloodlight.openflow.protocol.action.OFAction;
18import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
19import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
20import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
21import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigid;
22import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
23import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigtype;
24import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigtypeBasic;
25import org.projectfloodlight.openflow.types.CircuitSignalID;
26import org.projectfloodlight.openflow.types.OFPort;
27import org.projectfloodlight.openflow.types.U8;
28import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
30
31import java.io.IOException;
32import java.util.ArrayList;
33import java.util.Collection;
34import java.util.Collections;
35import java.util.List;
36import java.util.concurrent.atomic.AtomicBoolean;
37
38/**
39 * LINC-OE Optical Emulator switch class.
40 */
41public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
42
43 private final AtomicBoolean driverHandshakeComplete;
44 private long barrierXidToWaitFor = -1;
45
46 private final Logger log =
47 LoggerFactory.getLogger(OFOpticalSwitchImplLINC13.class);
48
49 OFOpticalSwitchImplLINC13(Dpid dpid,OFDescStatsReply desc) {
50 super(dpid);
51 //setAttribute("optical", "true");
52 driverHandshakeComplete = new AtomicBoolean(false);
53 setSwitchDescription(desc);
54 }
55
56 @Override
57 public String toString() {
58 return "OFOpticalSwitchImplLINC13 [" + ((channel != null)
59 ? channel.getRemoteAddress() : "?")
60 + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
61 }
62
63 @Override
64 public void startDriverHandshake() {
65 log.debug("Starting driver handshake for sw {}", getStringId());
66 if (startDriverHandshakeCalled) {
67 throw new SwitchDriverSubHandshakeAlreadyStarted();
68 }
69 startDriverHandshakeCalled = true;
70 try {
71 sendHandshakeOFExperimenterPortDescRequest();
72 } catch (IOException e) {
73 e.printStackTrace();
74 }
75 }
76
77 @Override
78 public boolean isDriverHandshakeComplete() {
79 if (!startDriverHandshakeCalled) {
80 throw new SwitchDriverSubHandshakeNotStarted();
81 }
82 return driverHandshakeComplete.get();
83 }
84
85 @Override
86 public void processDriverHandshakeMessage(OFMessage m) {
87 if (!startDriverHandshakeCalled) {
88 throw new SwitchDriverSubHandshakeNotStarted();
89 }
90 if (driverHandshakeComplete.get()) {
91 throw new SwitchDriverSubHandshakeCompleted(m);
92 }
93
94 switch (m.getType()) {
95 case BARRIER_REPLY:
96 if (m.getXid() == barrierXidToWaitFor) {
97 log.debug("LINC-OE Received barrier response");
98 }
99 break;
100 case ERROR:
101 log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
102 break;
103 case FEATURES_REPLY:
104 break;
105 case FLOW_REMOVED:
106 break;
107 case GET_ASYNC_REPLY:
108 break;
109 case PACKET_IN:
110 break;
111 case PORT_STATUS:
112 break;
113 case QUEUE_GET_CONFIG_REPLY:
114 break;
115 case ROLE_REPLY:
116 break;
117 case STATS_REPLY:
118 log.debug("LINC-OE : Received stats reply message {}", m);
119 processHandshakeOFExperimenterPortDescRequest(
120 (OFCircuitPortsReply) m);
121 driverHandshakeComplete.set(true);
122 /* try {
123 testMA();
124 } catch (IOException e) {
125 e.printStackTrace();
126 }*/
127 break;
128 default:
129 log.debug("Received message {} during switch-driver " +
130 "subhandshake " + "from switch {} ... " +
131 "Ignoring message", m,
132 getStringId());
133
134 }
135 }
136
137
138 private void processHandshakeOFExperimenterPortDescRequest(
139 OFCircuitPortsReply sr) {
140 Collection<OFPortOptical> entries = sr.getEntries();
141 List<OFPortDesc> ofPortDescList = new ArrayList<>(entries.size());
142 for (OFPortOptical entry : entries) {
143 ofPortDescList.add(factory().buildPortDesc().
144 setPortNo(entry.getPortNo())
145 .setConfig(entry.getConfig())
146 .setState(entry.getState())
147 .setHwAddr(entry.getHwAddr())
148 .setName(entry.getName())
149 .build());
150 }
151 setPortDescReply(factory().buildPortDescStatsReply().
152 setEntries(ofPortDescList).build());
153 }
154
155
156 private void sendHandshakeOFExperimenterPortDescRequest() throws
157 IOException {
158 // send multi part message for port description for optical switches
159 OFCircuitPortsRequest circuitPortsRequest = factory()
160 .buildCircuitPortsRequest().setXid(getNextTransactionId())
161 .build();
162 log.debug("LINC-OE : Sending experimented circuit port stats " +
163 "message " +
164 "{}",
165 circuitPortsRequest.toString());
166 channel.write(Collections.singletonList(circuitPortsRequest));
167 }
168
169
170
171 //todo for testing
172 public static final U8 SIGNAL_TYPE = U8.of((short) 1);
173 private void testMA() throws IOException {
174 log.debug("LINC OE *** Testing MA ");
175 short lambda = 100;
176 if (getId() == 0x0000ffffffffff02L) {
177 final int inport = 10;
178 final int outport = 20;
179 //Circuit signal id
180 CircuitSignalID sigID = getSignalID(lambda);
181
182 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
183 OFOxmOchSigtype fieldSigType = factory()
184 .oxms()
185 .ochSigtype(SIGNAL_TYPE);
186
187 OFOxmOchSigidBasic ofOxmOchSigidBasic =
188 factory().oxms().ochSigidBasic(sigID);
189
190 OFOxmOchSigtypeBasic ofOxmOchSigtypeBasic =
191 factory().oxms().ochSigtypeBasic(SIGNAL_TYPE);
192
193 //Match Port
194 OFOxmInPort fieldPort = factory().oxms()
195 .inPort(OFPort.of(inport));
196 OFMatchV3 matchPort =
197 factory()
198 .buildMatchV3().
199 setOxmList(OFOxmList.of(fieldPort,
200 fieldSigType,
201 fieldSigIDMatch)).build();
202
203
204 // Set Action outport ,sigType and sigID
205 List<OFAction> actionList = new ArrayList<>();
206 OFAction actionOutPort =
207 factory().actions().output(OFPort.of(outport),
208 Short.MAX_VALUE);
209
210 OFActionCircuit actionCircuit = factory()
211 .actions()
212 .circuit(ofOxmOchSigidBasic);
213 OFActionCircuit setActionSigType = factory()
214 .actions()
215 .circuit(ofOxmOchSigtypeBasic);
216
217 actionList.add(actionOutPort);
218 actionList.add(setActionSigType);
219 actionList.add(actionCircuit);
220
221 OFInstruction instructionAction =
222 factory().instructions().buildApplyActions()
223 .setActions(actionList)
224 .build();
225 List<OFInstruction> instructions =
226 Collections.singletonList(instructionAction);
227
228 OFMessage opticalFlowEntry =
229 factory().buildFlowAdd()
230 .setMatch(matchPort)
231 .setInstructions(instructions)
232 .setXid(getNextTransactionId())
233 .build();
234 log.debug("Adding optical flow in sw {}", getStringId());
235 List<OFMessage> msglist = new ArrayList<>(1);
236 msglist.add(opticalFlowEntry);
237 write(msglist);
238 } else if (getId() == 0x0000ffffffffff03L) {
239 final int inport = 21;
240 final int outport = 22;
241 //Circuit signal id
242 CircuitSignalID sigID = getSignalID(lambda);
243
244 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
245 OFOxmOchSigtype fieldSigType = factory()
246 .oxms()
247 .ochSigtype(SIGNAL_TYPE);
248
249 OFOxmOchSigidBasic ofOxmOchSigidBasic =
250 factory().oxms().ochSigidBasic(sigID);
251
252 OFOxmOchSigtypeBasic ofOxmOchSigtypeBasic =
253 factory().oxms().ochSigtypeBasic(SIGNAL_TYPE);
254
255 //Match Port,SigType,SigID
256 OFOxmInPort fieldPort = factory()
257 .oxms()
258 .inPort(OFPort.of(inport));
259 OFMatchV3 matchPort = factory()
260 .buildMatchV3()
261 .setOxmList(OFOxmList.of(fieldPort,
262 fieldSigType,
263 fieldSigIDMatch))
264 .build();
265
266 // Set Action outport ,SigType, sigID
267 List<OFAction> actionList = new ArrayList<>();
268 OFAction actionOutPort =
269 factory().actions().output(OFPort.of(outport),
270 Short.MAX_VALUE);
271
272 OFActionCircuit setActionSigType = factory()
273 .actions()
274 .circuit(ofOxmOchSigtypeBasic);
275 OFActionCircuit actionCircuit = factory()
276 .actions()
277 .circuit(ofOxmOchSigidBasic);
278
279
280 actionList.add(actionOutPort);
281 actionList.add(setActionSigType);
282 actionList.add(actionCircuit);
283
284 OFInstruction instructionAction =
285 factory().instructions().buildApplyActions()
286 .setActions(actionList)
287 .build();
288 List<OFInstruction> instructions =
289 Collections.singletonList(instructionAction);
290
291 OFMessage opticalFlowEntry =
292 factory().buildFlowAdd()
293 .setMatch(matchPort)
294 .setInstructions(instructions)
295 .setXid(getNextTransactionId())
296 .build();
297 log.debug("Adding optical flow in sw {}", getStringId());
298 List<OFMessage> msglist = new ArrayList<>(1);
299 msglist.add(opticalFlowEntry);
300 write(msglist);
301
302 } else if (getId() == 0x0000ffffffffff04L) {
303 final int inport = 23;
304 final int outport = 11;
305 //Circuit signal id
306 CircuitSignalID sigID = getSignalID(lambda);
307
308 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
309 OFOxmOchSigtype fieldSigType = factory()
310 .oxms()
311 .ochSigtype(SIGNAL_TYPE);
312
313
314 //Match Port, sig type and sig id
315 OFOxmInPort fieldPort = factory()
316 .oxms()
317 .inPort(OFPort.of(inport));
318 OFMatchV3 matchPort =
319 factory().buildMatchV3()
320 .setOxmList(OFOxmList.of(fieldPort,
321 fieldSigType,
322 fieldSigIDMatch))
323 .build();
324
325 // Set Action outport
326 List<OFAction> actionList = new ArrayList<>();
327 OFAction actionOutPort =
328 factory().actions().output(OFPort.of(outport),
329 Short.MAX_VALUE);
330
331 actionList.add(actionOutPort);
332
333 OFInstruction instructionAction =
334 factory().instructions().buildApplyActions()
335 .setActions(actionList)
336 .build();
337 List<OFInstruction> instructions =
338 Collections.singletonList(instructionAction);
339
340 OFMessage opticalFlowEntry =
341 factory().buildFlowAdd()
342 .setMatch(matchPort)
343 .setInstructions(instructions)
344 .setXid(getNextTransactionId())
345 .build();
346 log.debug("Adding optical flow in sw {}", getStringId());
347 List<OFMessage> msglist = new ArrayList<>(1);
348 msglist.add(opticalFlowEntry);
349 write(msglist);
350 }
351
352 }
353
354 // Todo remove - for testing purpose only
355 private static CircuitSignalID getSignalID(short lambda) {
356 byte myGrid = 1;
357 byte myCs = 2;
358 short myCn = lambda;
359 short mySw = 1;
360
361 CircuitSignalID signalID = new CircuitSignalID(myGrid,
362 myCs,
363 myCn,
364 mySw);
365 return signalID;
366 }
367
368 @Override
369 public void write(OFMessage msg) {
370 this.channel.write(msg);
371 }
372
373 @Override
374 public void write(List<OFMessage> msgs) {
375 this.channel.write(msgs);
376 }
377
378 @Override
379 public Boolean supportNxRole() {
380 return false;
381 }
382
383}