blob: 79a162e91e6dd770f08d82b405b3d7a7a404a1c8 [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;
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -07008import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -07009import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
10import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
11import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
12import org.projectfloodlight.openflow.protocol.OFErrorMsg;
13import org.projectfloodlight.openflow.protocol.OFMatchV3;
14import org.projectfloodlight.openflow.protocol.OFMessage;
15import org.projectfloodlight.openflow.protocol.OFOxmList;
16import org.projectfloodlight.openflow.protocol.OFPortDesc;
17import org.projectfloodlight.openflow.protocol.OFPortOptical;
18import org.projectfloodlight.openflow.protocol.action.OFAction;
19import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
20import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
21import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
22import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigid;
23import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
24import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigtype;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070025import 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
Yuta HIGUCHIbccb6be2014-10-09 17:20:29 -070049 OFOpticalSwitchImplLINC13(Dpid dpid, OFDescStatsReply desc) {
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070050 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);
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700122 try {
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700123 testMA();
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700124 testReverseMA();
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700125 } catch (IOException e) {
126 e.printStackTrace();
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700127 }
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700128 break;
129 default:
130 log.debug("Received message {} during switch-driver " +
131 "subhandshake " + "from switch {} ... " +
132 "Ignoring message", m,
133 getStringId());
134
135 }
136 }
137
138
139 private void processHandshakeOFExperimenterPortDescRequest(
140 OFCircuitPortsReply sr) {
141 Collection<OFPortOptical> entries = sr.getEntries();
142 List<OFPortDesc> ofPortDescList = new ArrayList<>(entries.size());
143 for (OFPortOptical entry : entries) {
144 ofPortDescList.add(factory().buildPortDesc().
145 setPortNo(entry.getPortNo())
146 .setConfig(entry.getConfig())
147 .setState(entry.getState())
148 .setHwAddr(entry.getHwAddr())
149 .setName(entry.getName())
150 .build());
151 }
152 setPortDescReply(factory().buildPortDescStatsReply().
153 setEntries(ofPortDescList).build());
154 }
155
156
157 private void sendHandshakeOFExperimenterPortDescRequest() throws
158 IOException {
159 // send multi part message for port description for optical switches
160 OFCircuitPortsRequest circuitPortsRequest = factory()
161 .buildCircuitPortsRequest().setXid(getNextTransactionId())
162 .build();
163 log.debug("LINC-OE : Sending experimented circuit port stats " +
164 "message " +
165 "{}",
166 circuitPortsRequest.toString());
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700167 sendMsg(Collections.<OFMessage>singletonList(circuitPortsRequest));
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700168 }
169
170
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700171 public static final U8 SIGNAL_TYPE = U8.of((short) 10);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700172 private void testMA() throws IOException {
173 log.debug("LINC OE *** Testing MA ");
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700174 short lambda = 1;
175 if (getId() == 0x0000ffffffffff01L) {
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700176 final int inport = 10;
177 final int outport = 20;
178 //Circuit signal id
179 CircuitSignalID sigID = getSignalID(lambda);
180
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700181 OFOxmOchSigidBasic ofOxmOchSigidBasic =
182 factory().oxms().ochSigidBasic(sigID);
183
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700184
185 //Match Port
186 OFOxmInPort fieldPort = factory().oxms()
187 .inPort(OFPort.of(inport));
188 OFMatchV3 matchPort =
189 factory()
190 .buildMatchV3().
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700191 setOxmList(OFOxmList.of(fieldPort)).build();
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700192
193
194 // Set Action outport ,sigType and sigID
195 List<OFAction> actionList = new ArrayList<>();
196 OFAction actionOutPort =
197 factory().actions().output(OFPort.of(outport),
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700198 0xffff);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700199
200 OFActionCircuit actionCircuit = factory()
201 .actions()
202 .circuit(ofOxmOchSigidBasic);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700203
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700204 actionList.add(actionCircuit);
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700205 actionList.add(actionOutPort);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700206
207 OFInstruction instructionAction =
208 factory().instructions().buildApplyActions()
209 .setActions(actionList)
210 .build();
211 List<OFInstruction> instructions =
212 Collections.singletonList(instructionAction);
213
214 OFMessage opticalFlowEntry =
215 factory().buildFlowAdd()
216 .setMatch(matchPort)
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700217 .setPriority(100)
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700218 .setInstructions(instructions)
219 .setXid(getNextTransactionId())
220 .build();
221 log.debug("Adding optical flow in sw {}", getStringId());
222 List<OFMessage> msglist = new ArrayList<>(1);
223 msglist.add(opticalFlowEntry);
224 write(msglist);
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700225 sendBarrier(true);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700226 } else if (getId() == 0x0000ffffffffff03L) {
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700227 final int inport = 30;
228 final int outport = 31;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700229 //Circuit signal id
230 CircuitSignalID sigID = getSignalID(lambda);
231
232 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
233 OFOxmOchSigtype fieldSigType = factory()
234 .oxms()
235 .ochSigtype(SIGNAL_TYPE);
236
237 OFOxmOchSigidBasic ofOxmOchSigidBasic =
238 factory().oxms().ochSigidBasic(sigID);
239
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700240 //Match Port,SigType,SigID
241 OFOxmInPort fieldPort = factory()
242 .oxms()
243 .inPort(OFPort.of(inport));
244 OFMatchV3 matchPort = factory()
245 .buildMatchV3()
246 .setOxmList(OFOxmList.of(fieldPort,
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700247 fieldSigIDMatch,
248 fieldSigType
249 ))
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700250 .build();
251
252 // Set Action outport ,SigType, sigID
253 List<OFAction> actionList = new ArrayList<>();
254 OFAction actionOutPort =
255 factory().actions().output(OFPort.of(outport),
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700256 0xffff);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700257
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700258 OFActionCircuit actionCircuit = factory()
259 .actions()
260 .circuit(ofOxmOchSigidBasic);
261
262
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700263
264 //actionList.add(setActionSigType);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700265 actionList.add(actionCircuit);
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700266 actionList.add(actionOutPort);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700267
268 OFInstruction instructionAction =
269 factory().instructions().buildApplyActions()
270 .setActions(actionList)
271 .build();
272 List<OFInstruction> instructions =
273 Collections.singletonList(instructionAction);
274
275 OFMessage opticalFlowEntry =
276 factory().buildFlowAdd()
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700277 .setMatch(matchPort)
278 .setPriority(100)
279 .setInstructions(instructions)
280 .setXid(getNextTransactionId())
281 .build();
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700282 log.debug("Adding optical flow in sw {}", getStringId());
283 List<OFMessage> msglist = new ArrayList<>(1);
284 msglist.add(opticalFlowEntry);
285 write(msglist);
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700286 sendBarrier(true);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700287
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700288 } else if (getId() == 0x0000ffffffffff02L) {
289 final int inport = 21;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700290 final int outport = 11;
291 //Circuit signal id
292 CircuitSignalID sigID = getSignalID(lambda);
293
294 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
295 OFOxmOchSigtype fieldSigType = factory()
296 .oxms()
297 .ochSigtype(SIGNAL_TYPE);
298
299
300 //Match Port, sig type and sig id
301 OFOxmInPort fieldPort = factory()
302 .oxms()
303 .inPort(OFPort.of(inport));
304 OFMatchV3 matchPort =
305 factory().buildMatchV3()
306 .setOxmList(OFOxmList.of(fieldPort,
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700307 fieldSigIDMatch,
308 fieldSigType
309 ))
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700310 .build();
311
312 // Set Action outport
313 List<OFAction> actionList = new ArrayList<>();
314 OFAction actionOutPort =
315 factory().actions().output(OFPort.of(outport),
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700316 0xffff);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700317
318 actionList.add(actionOutPort);
319
320 OFInstruction instructionAction =
321 factory().instructions().buildApplyActions()
322 .setActions(actionList)
323 .build();
324 List<OFInstruction> instructions =
325 Collections.singletonList(instructionAction);
326
327 OFMessage opticalFlowEntry =
328 factory().buildFlowAdd()
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700329 .setMatch(matchPort)
330 .setPriority(100)
331 .setInstructions(instructions)
332 .setXid(getNextTransactionId())
333 .build();
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700334 log.debug("Adding optical flow in sw {}", getStringId());
335 List<OFMessage> msglist = new ArrayList<>(1);
336 msglist.add(opticalFlowEntry);
337 write(msglist);
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700338 sendBarrier(true);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700339 }
340
341 }
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700342 private void testReverseMA() throws IOException {
343 log.debug("LINC OE *** Testing MA ");
344 short lambda = 1;
345 if (getId() == 0x0000ffffffffff02L) {
346 final int inport = 11;
347 final int outport = 21;
348 //Circuit signal id
349 CircuitSignalID sigID = getSignalID(lambda);
350
351 OFOxmOchSigidBasic ofOxmOchSigidBasic =
352 factory().oxms().ochSigidBasic(sigID);
353
354 //Match Port
355 OFOxmInPort fieldPort = factory().oxms()
356 .inPort(OFPort.of(inport));
357 OFMatchV3 matchPort =
358 factory()
359 .buildMatchV3().
360 setOxmList(OFOxmList.of(fieldPort)).build();
361
362
363 // Set Action outport ,sigType and sigID
364 List<OFAction> actionList = new ArrayList<>();
365 OFAction actionOutPort =
366 factory().actions().output(OFPort.of(outport),
367 0xffff);
368
369 OFActionCircuit actionCircuit = factory()
370 .actions()
371 .circuit(ofOxmOchSigidBasic);
372 actionList.add(actionCircuit);
373 actionList.add(actionOutPort);
374
375 OFInstruction instructionAction =
376 factory().instructions().buildApplyActions()
377 .setActions(actionList)
378 .build();
379 List<OFInstruction> instructions =
380 Collections.singletonList(instructionAction);
381
382 OFMessage opticalFlowEntry =
383 factory().buildFlowAdd()
384 .setMatch(matchPort)
385 .setPriority(100)
386 .setInstructions(instructions)
387 .setXid(getNextTransactionId())
388 .build();
389 log.debug("Adding optical flow in sw {}", getStringId());
390 List<OFMessage> msglist = new ArrayList<>(1);
391 msglist.add(opticalFlowEntry);
392 write(msglist);
393 sendBarrier(true);
394 } else if (getId() == 0x0000ffffffffff03L) {
395 final int inport = 31;
396 final int outport = 30;
397 //Circuit signal id
398 CircuitSignalID sigID = getSignalID(lambda);
399
400 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
401 OFOxmOchSigtype fieldSigType = factory()
402 .oxms()
403 .ochSigtype(SIGNAL_TYPE);
404
405 OFOxmOchSigidBasic ofOxmOchSigidBasic =
406 factory().oxms().ochSigidBasic(sigID);
407
408 //Match Port,SigType,SigID
409 OFOxmInPort fieldPort = factory()
410 .oxms()
411 .inPort(OFPort.of(inport));
412 OFMatchV3 matchPort = factory()
413 .buildMatchV3()
414 .setOxmList(OFOxmList.of(fieldPort,
415 fieldSigIDMatch,
416 fieldSigType
417 ))
418 .build();
419
420 // Set Action outport ,SigType, sigID
421 List<OFAction> actionList = new ArrayList<>();
422 OFAction actionOutPort =
423 factory().actions().output(OFPort.of(outport),
424 0xffff);
425 OFActionCircuit actionCircuit = factory()
426 .actions()
427 .circuit(ofOxmOchSigidBasic);
428
429 actionList.add(actionCircuit);
430 actionList.add(actionOutPort);
431
432 OFInstruction instructionAction =
433 factory().instructions().buildApplyActions()
434 .setActions(actionList)
435 .build();
436 List<OFInstruction> instructions =
437 Collections.singletonList(instructionAction);
438
439 OFMessage opticalFlowEntry =
440 factory().buildFlowAdd()
441 .setMatch(matchPort)
442 .setPriority(100)
443 .setInstructions(instructions)
444 .setXid(getNextTransactionId())
445 .build();
446 log.debug("Adding optical flow in sw {}", getStringId());
447 List<OFMessage> msglist = new ArrayList<>(1);
448 msglist.add(opticalFlowEntry);
449 write(msglist);
450 sendBarrier(true);
451
452 } else if (getId() == 0x0000ffffffffff01L) {
453 final int inport = 20;
454 final int outport = 10;
455 //Circuit signal id
456 CircuitSignalID sigID = getSignalID(lambda);
457
458 OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
459 OFOxmOchSigtype fieldSigType = factory()
460 .oxms()
461 .ochSigtype(SIGNAL_TYPE);
462
463
464 //Match Port, sig type and sig id
465 OFOxmInPort fieldPort = factory()
466 .oxms()
467 .inPort(OFPort.of(inport));
468 OFMatchV3 matchPort =
469 factory().buildMatchV3()
470 .setOxmList(OFOxmList.of(fieldPort,
471 fieldSigIDMatch,
472 fieldSigType
473 ))
474 .build();
475
476 // Set Action outport
477 List<OFAction> actionList = new ArrayList<>();
478 OFAction actionOutPort =
479 factory().actions().output(OFPort.of(outport),
480 0xffff);
481
482 actionList.add(actionOutPort);
483
484 OFInstruction instructionAction =
485 factory().instructions().buildApplyActions()
486 .setActions(actionList)
487 .build();
488 List<OFInstruction> instructions =
489 Collections.singletonList(instructionAction);
490
491 OFMessage opticalFlowEntry =
492 factory().buildFlowAdd()
493 .setMatch(matchPort)
494 .setPriority(100)
495 .setInstructions(instructions)
496 .setXid(getNextTransactionId())
497 .build();
498 log.debug("Adding optical flow in sw {}", getStringId());
499 List<OFMessage> msglist = new ArrayList<>(1);
500 msglist.add(opticalFlowEntry);
501 write(msglist);
502 sendBarrier(true);
503 }
504
505 }
506
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700507
508 // Todo remove - for testing purpose only
509 private static CircuitSignalID getSignalID(short lambda) {
510 byte myGrid = 1;
511 byte myCs = 2;
512 short myCn = lambda;
513 short mySw = 1;
514
515 CircuitSignalID signalID = new CircuitSignalID(myGrid,
516 myCs,
517 myCn,
518 mySw);
519 return signalID;
520 }
521
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700522 private void sendBarrier(boolean finalBarrier) throws IOException {
523 int xid = getNextTransactionId();
524 if (finalBarrier) {
525 barrierXidToWaitFor = xid;
526 }
527 OFBarrierRequest br = factory()
528 .buildBarrierRequest()
529 .setXid(xid)
530 .build();
531 sendMsg(br);
532 }
533
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700534 @Override
535 public void write(OFMessage msg) {
Praseed Balakrishnan610c1e12014-10-15 16:34:59 -0700536 this.sendMsg(msg);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700537 }
538
539 @Override
540 public void write(List<OFMessage> msgs) {
541 this.channel.write(msgs);
542 }
543
544 @Override
545 public Boolean supportNxRole() {
546 return false;
547 }
548
549}