blob: f274a281367e547b1a36bd5834a10a8056a0d454 [file] [log] [blame]
alshabib1f44e8e2014-08-14 15:19:57 -07001/**
2 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
17
18package net.onrc.onos.of.ctl;
19
20import java.io.IOException;
21import java.util.Collection;
22import java.util.Date;
23import java.util.List;
24import java.util.Map;
25import java.util.Set;
26import java.util.concurrent.Future;
27
28import net.onrc.onos.of.ctl.debugcounter.IDebugCounterService;
29import net.onrc.onos.of.ctl.debugcounter.IDebugCounterService.CounterException;
30import net.onrc.onos.of.ctl.util.OrderedCollection;
31
32import org.jboss.netty.channel.Channel;
33import org.projectfloodlight.openflow.protocol.OFActionType;
34import org.projectfloodlight.openflow.protocol.OFCapabilities;
35import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
36import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
37import org.projectfloodlight.openflow.protocol.OFMessage;
38import org.projectfloodlight.openflow.protocol.OFPortDesc;
39import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
40import org.projectfloodlight.openflow.protocol.OFPortStatus;
41import org.projectfloodlight.openflow.protocol.OFStatsReply;
42import org.projectfloodlight.openflow.protocol.OFStatsRequest;
43import org.projectfloodlight.openflow.protocol.OFVersion;
44import org.projectfloodlight.openflow.types.U64;
45
46
47public interface IOFSwitch {
48
49 /**
50 * OF1.3 switches should support role-request messages as in the 1.3 spec.
51 * OF1.0 switches may or may not support the Nicira role request extensions.
52 * To indicate the support, this property should be set by the associated
53 * OF1.0 switch driver in the net.onrc.onos.core.drivermanager package.
54 * The property will be ignored for OF1.3 switches.
55 */
56 public static final String SWITCH_SUPPORTS_NX_ROLE = "supportsNxRole";
57
58
59 //************************
60 // Channel related
61 //************************
62
63 /**
64 * Disconnects the switch by closing the TCP connection. Results in a call
65 * to the channel handler's channelDisconnected method for cleanup
66 * @throws IOException
67 */
68 public void disconnectSwitch();
69
70 /**
71 * Writes to the OFMessage to the output stream.
72 * The message will be handed to the floodlightProvider for possible filtering
73 * and processing by message listeners
74 *
75 * @param m
76 * @param bc
77 * @throws IOException
78 */
79 public void write(OFMessage m) throws IOException;
80
81 /**
82 * Writes the list of messages to the output stream.
83 * The message will be handed to the floodlightProvider for possible filtering
84 * and processing by message listeners.
85 *
86 * @param msglist
87 * @param bc
88 * @throws IOException
89 */
90 public void write(List<OFMessage> msglist) throws IOException;
91
92 /**
93 * Gets the date the switch connected to this controller.
94 *
95 * @return the date
96 */
97 public Date getConnectedSince();
98
99 /**
100 * Gets the next available transaction id.
101 *
102 * @return the next transaction ID
103 */
104 public int getNextTransactionId();
105
106 /**
107 * Checks if the switch is still connected.
108 * Only call while holding processMessageLock
109 *
110 * @return whether the switch is still disconnected
111 */
112 public boolean isConnected();
113
114 /**
115 * Sets whether the switch is connected.
116 * Only call while holding modifySwitchLock
117 *
118 * @param connected whether the switch is connected
119 */
120 public void setConnected(boolean connected);
121
122 /**
123 * Flushes all flows queued for this switch in the current thread.
124 * NOTE: The contract is limited to the current thread
125 */
126 public void flush();
127
128 /**
129 * Sets the Netty Channel this switch instance is associated with.
130 * <p>
131 * Called immediately after instantiation
132 *
133 * @param channel the channel
134 */
135 public void setChannel(Channel channel);
136
137 //************************
138 // Switch features related
139 //************************
140
141 /**
142 * Gets the datapathId of the switch.
143 *
144 * @return the switch buffers
145 */
146 public long getId();
147
148 /**
149 * Gets a string version of the ID for this switch.
150 *
151 * @return string version of the ID
152 */
153 public String getStringId();
154
155 /**
156 * Gets the number of buffers.
157 *
158 * @return the number of buffers
159 */
160 public int getNumBuffers();
161
162 public Set<OFCapabilities> getCapabilities();
163
164 public byte getNumTables();
165
166 /**
167 * Returns an OFDescStatsReply message object. Use the methods contained
168 * to retrieve switch descriptions for Manufacturer, Hw/Sw version etc.
169 */
170 public OFDescStatsReply getSwitchDescription();
171
172 /**
173 * Cancel features reply with a specific transaction ID.
174 * @param transactionId the transaction ID
175 */
176 public void cancelFeaturesReply(int transactionId);
177
178 /**
179 * Gets the OFActionType set.
180 * <p>
181 * getActions has relevance only for an OpenFlow 1.0 switch.
182 * For OF1.3, each table can support different actions
183 *
184 * @return the action set
185 */
186 public Set<OFActionType> getActions();
187
188 public void setOFVersion(OFVersion ofv);
189
190 public OFVersion getOFVersion();
191
192
193 //************************
194 // Switch port related
195 //************************
196
197 /**
198 * the type of change that happened to an open flow port.
199 */
200 public enum PortChangeType {
201 /** Either a new port has been added by the switch, or we are
202 * adding a port we just deleted (via a prior notification) due to
203 * a change in the portNumber-portName mapping.
204 */
205 ADD,
206 /** some other feature of the port has changed (eg. speed)*/
207 OTHER_UPDATE,
208 /** Either a port has been deleted by the switch, or we are deleting
209 * a port whose portNumber-portName mapping has changed. Note that in
210 * the latter case, a subsequent notification will be sent out to add a
211 * port with the new portNumber-portName mapping.
212 */
213 DELETE,
214 /** Port is up (i.e. enabled). Presumably an earlier notification had
215 * indicated that it was down. To be UP implies that the port is
216 * administratively considered UP (see ofp_port_config) AND the port
217 * link is up AND the port is no longer blocked (see ofp_port_state).
218 */
219 UP,
220 /** Port is down (i.e. disabled). Presumably an earlier notification had
221 * indicated that it was up, or the port was always up.
222 * To be DOWN implies that the port has been either
223 * administratively brought down (see ofp_port_config) OR the port
224 * link is down OR the port is blocked (see ofp_port_state).
225 */
226 DOWN,
227 }
228
229 /**
230 * Describes a change of an open flow port.
231 */
232 public static class PortChangeEvent {
233 public final OFPortDesc port;
234 public final PortChangeType type;
235 /**
236 * @param port
237 * @param type
238 */
239 public PortChangeEvent(OFPortDesc port,
240 PortChangeType type) {
241 this.port = port;
242 this.type = type;
243 }
244 /* (non-Javadoc)
245 * @see java.lang.Object#hashCode()
246 */
247 @Override
248 public int hashCode() {
249 final int prime = 31;
250 int result = 1;
251 result = prime * result + ((port == null) ? 0 : port.hashCode());
252 result = prime * result + ((type == null) ? 0 : type.hashCode());
253 return result;
254 }
255 /* (non-Javadoc)
256 * @see java.lang.Object#equals(java.lang.Object)
257 */
258 @Override
259 public boolean equals(Object obj) {
260 if (this == obj) {
261 return true;
262 }
263 if (obj == null) {
264 return false;
265 }
266 if (getClass() != obj.getClass()) {
267 return false;
268 }
269 PortChangeEvent other = (PortChangeEvent) obj;
270 if (port == null) {
271 if (other.port != null) {
272 return false;
273 }
274 } else if (!port.equals(other.port)) {
275 return false;
276 }
277 if (type != other.type) {
278 return false;
279 }
280 return true;
281 }
282 /* (non-Javadoc)
283 * @see java.lang.Object#toString()
284 */
285 @Override
286 public String toString() {
287 return "[" + type + " " + port.toString() + "]";
288 }
289 }
290
291
292 /**
293 * Get list of all enabled ports. This will typically be different from
294 * the list of ports in the OFFeaturesReply, since that one is a static
295 * snapshot of the ports at the time the switch connected to the controller
296 * whereas this port list also reflects the port status messages that have
297 * been received.
298 *
299 * @return Unmodifiable list of ports not backed by the underlying collection
300 */
301 public Collection<OFPortDesc> getEnabledPorts();
302
303 /**
304 * Get list of the port numbers of all enabled ports. This will typically
305 * be different from the list of ports in the OFFeaturesReply, since that
306 * one is a static snapshot of the ports at the time the switch connected
307 * to the controller whereas this port list also reflects the port status
308 * messages that have been received.
309 *
310 * @return Unmodifiable list of ports not backed by the underlying collection
311 */
312 public Collection<Integer> getEnabledPortNumbers();
313
314 /**
315 * Retrieve the port object by the port number. The port object
316 * is the one that reflects the port status updates that have been
317 * received, not the one from the features reply.
318 *
319 * @param portNumber
320 * @return port object
321 */
322 public OFPortDesc getPort(int portNumber);
323
324 /**
325 * Retrieve the port object by the port name. The port object
326 * is the one that reflects the port status updates that have been
327 * received, not the one from the features reply.
328 *
329 * @param portName
330 * @return port object
331 */
332 public OFPortDesc getPort(String portName);
333
334 /**
335 * Add or modify a switch port. This is called by the core controller
336 * code in response to a OFPortStatus message. It should not typically be
337 * called by other floodlight applications.
338 *
339 * OFPPR_MODIFY and OFPPR_ADD will be treated as equivalent. The OpenFlow
340 * spec is not clear on whether portNames are portNumbers are considered
341 * authoritative identifiers. We treat portNames <-> portNumber mappings
342 * as fixed. If they change, we delete all previous conflicting ports and
343 * add all new ports.
344 *
345 * @param ps the port status message
346 * @return the ordered Collection of changes "applied" to the old ports
347 * of the switch according to the PortStatus message. A single PortStatus
348 * message can result in multiple changes.
349 * If portName <-> portNumber mappings have
350 * changed, the iteration order ensures that delete events for old
351 * conflicting appear before before events adding new ports
352 */
353 public OrderedCollection<PortChangeEvent> processOFPortStatus(OFPortStatus ps);
354
355 /**
356 * Get list of all ports. This will typically be different from
357 * the list of ports in the OFFeaturesReply, since that one is a static
358 * snapshot of the ports at the time the switch connected to the controller
359 * whereas this port list also reflects the port status messages that have
360 * been received.
361 *
362 * @return Unmodifiable list of ports
363 */
364 public Collection<OFPortDesc> getPorts();
365
366 /**
367 * @param portName
368 * @return Whether a port is enabled per latest port status message
369 * (not configured down nor link down nor in spanning tree blocking state)
370 */
371 public boolean portEnabled(int portName);
372
373 /**
374 * @param portNumber
375 * @return Whether a port is enabled per latest port status message
376 * (not configured down nor link down nor in spanning tree blocking state)
377 */
378 public boolean portEnabled(String portName);
379
380 /**
381 * Compute the changes that would be required to replace the old ports
382 * of this switch with the new ports.
383 * @param ports new ports to set
384 * @return the ordered collection of changes "applied" to the old ports
385 * of the switch in order to set them to the new set.
386 * If portName <-> portNumber mappings have
387 * changed, the iteration order ensures that delete events for old
388 * conflicting appear before before events adding new ports
389 */
390 public OrderedCollection<PortChangeEvent>
391 comparePorts(Collection<OFPortDesc> ports);
392
393 /**
394 * Replace the ports of this switch with the given ports.
395 * @param ports new ports to set
396 * @return the ordered collection of changes "applied" to the old ports
397 * of the switch in order to set them to the new set.
398 * If portName <-> portNumber mappings have
399 * changed, the iteration order ensures that delete events for old
400 * conflicting appear before before events adding new ports
401 */
402 public OrderedCollection<PortChangeEvent>
403 setPorts(Collection<OFPortDesc> ports);
404
405// XXX S The odd use of providing an API call to 'set ports' (above) would
406// logically suggest that there should be a way to delete or unset the ports.
407// Right now we forbid this. We should probably not use setPorts too.
408//
409// /**
410// * Delete a port for the switch. This is called by the core controller
411// * code in response to a OFPortStatus message. It should not typically be
412// * called by other floodlight applications.
413// *
414// * @param portNumber
415// */
416// public void deletePort(short portNumber);
417//
418// /**
419// * Delete a port for the switch. This is called by the core controller
420// * code in response to a OFPortStatus message. It should not typically be
421// * called by other floodlight applications.
422// *
423// * @param portName
424// */
425// public void deletePort(String portName);
426
427
428 //*******************************************
429 // IOFSwitch object attributes
430 //************************
431
432 /**
433 * Gets attributes of this switch.
434 *
435 * @return attributes of the switch
436 */
437 public Map<Object, Object> getAttributes();
438
439 /**
440 * Checks if a specific switch property exists for this switch.
441 *
442 * @param name name of property
443 * @return value for name
444 */
445 boolean hasAttribute(String name);
446
447 /**
448 * Gets properties for switch specific behavior.
449 *
450 * @param name name of property
451 * @return 'value' for 'name', or null if no entry for 'name' exists
452 */
453 Object getAttribute(String name);
454
455 /**
456 * Sets properties for switch specific behavior.
457 *
458 * @param name name of property
459 * @param value value for name
460 */
461 void setAttribute(String name, Object value);
462
463 /**
464 * Removes properties for switch specific behavior.
465 *
466 * @param name name of property
467 * @return current value for name or null (if not present)
468 */
469 Object removeAttribute(String name);
470
471 //************************
472 // Switch statistics
473 //************************
474
475 /**
476 * Delivers the statistics future reply.
477 *
478 * @param reply the reply to deliver
479 */
480 public void deliverStatisticsReply(OFMessage reply);
481
482 /**
483 * Cancels the statistics reply with the given transaction ID.
484 *
485 * @param transactionId the transaction ID
486 */
487 public void cancelStatisticsReply(int transactionId);
488
489 /**
490 * Cancels all statistics replies.
491 */
492 public void cancelAllStatisticsReplies();
493
494 /**
495 * Gets a Future object that can be used to retrieve the asynchronous.
496 * OFStatisticsReply when it is available.
497 *
498 * @param request statistics request
499 * @return Future object wrapping OFStatisticsReply
500 * @throws IOException
501 */
502 public Future<List<OFStatsReply>> getStatistics(OFStatsRequest<?> request)
503 throws IOException;
504
505 //************************
506 // Switch other utilities
507 //************************
508
509 /**
510 * Clears all flowmods on this switch.
511 */
512 public void clearAllFlowMods();
513
514 /**
515 * Gets the current role of this controller for this IOFSwitch.
516 */
517 public Role getRole();
518
519 /**
520 * Sets this controller's Role for this IOFSwitch to role.
521 *
522 * @param role
523 */
524 public void setRole(Role role);
525
526 /**
527 * Gets the next generation ID.
528 * <p>
529 * Note: relevant for role request messages in OF1.3
530 *
531 * @return next generation ID
532 */
533 public U64 getNextGenerationId();
534
535
536 /**
537 * Set debug counter service for per-switch counters.
538 * Called immediately after instantiation.
539 * @param debugCounters
540 * @throws CounterException
541 */
542 public void setDebugCounterService(IDebugCounterService debugCounter)
543 throws CounterException;
544
545 /**
546 * Start this switch driver's sub handshake. This might be a no-op but
547 * this method must be called at least once for the switch to be become
548 * ready.
549 * This method must only be called from the I/O thread
550 * @throws IOException
551 * @throws SwitchDriverSubHandshakeAlreadyStarted if the sub-handshake has
552 * already been started
553 */
554 public void startDriverHandshake() throws IOException;
555
556 /**
557 * Check if the sub-handshake for this switch driver has been completed.
558 * This method can only be called after startDriverHandshake()
559 *
560 * This methods must only be called from the I/O thread
561 * @return true if the sub-handshake has been completed. False otherwise
562 * @throws SwitchDriverSubHandshakeNotStarted if startDriverHandshake() has
563 * not been called yet.
564 */
565 public boolean isDriverHandshakeComplete();
566
567 /**
568 * Pass the given OFMessage to the driver as part of this driver's
569 * sub-handshake. Must not be called after the handshake has been completed
570 * This methods must only be called from the I/O thread
571 * @param m The message that the driver should process
572 * @throws SwitchDriverSubHandshakeCompleted if isDriverHandshake() returns
573 * false before this method call
574 * @throws SwitchDriverSubHandshakeNotStarted if startDriverHandshake() has
575 * not been called yet.
576 */
577 public void processDriverHandshakeMessage(OFMessage m);
578
579 /**
580 * Set the flow table full flag in the switch.
581 * XXX S Rethink this for multiple tables
582 */
583 public void setTableFull(boolean isFull);
584
585 /**
586 * Save the features reply for this switch.
587 *
588 * @param featuresReply
589 */
590 public void setFeaturesReply(OFFeaturesReply featuresReply);
591
592 /**
593 * Save the portset for this switch.
594 *
595 * @param portDescReply
596 */
597 public void setPortDescReply(OFPortDescStatsReply portDescReply);
598
599 //************************
600 // Message handling
601 //************************
602 /**
603 * Handle the message coming from the dataplane.
604 *
605 * @param m the actual message
606 */
607 public void handleMessage(OFMessage m);
608
609
610}