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