blob: 858eda6a5651393d9bb59d4f1e637a5c0a298978 [file] [log] [blame]
Yotam Harcholf3f11152013-09-05 16:47:16 -07001package org.projectfloodlight.openflow.types;
2
3import org.jboss.netty.buffer.ChannelBuffer;
4import org.projectfloodlight.openflow.annotations.Immutable;
5import org.projectfloodlight.openflow.exceptions.OFParseError;
6
7/**
8 * Abstraction of an logical / OpenFlow switch port (ofp_port_no) in OpenFlow.
9 * Immutable. Note: Switch port numbers were changed in OpenFlow 1.1 from uint16
10 * to uint32. This class uses a 32 bit representation internally. Port numbers
11 * are converted from/to uint16 when constructed / getPortNumberasShort is
12 * called. If this port is not representable in OpenFlow 1.0, an
13 * IllegalStateException is raised.
14 *
15 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
16 */
17@Immutable
18public class OFPort implements OFValueType<OFPort> {
19 static final int LENGTH = 4;
Andreas Wundsamb75c4ad2013-09-23 14:45:35 -070020
Yotam Harcholf3f11152013-09-05 16:47:16 -070021 // private int constants (OF1.1+) to avoid duplication in the code
22 // should not have to use these outside this class
23 private static final int OFPP_ANY_INT = 0xFFffFFff;
24 private static final int OFPP_LOCAL_INT = 0xFFffFFfe;
25 private static final int OFPP_CONTROLLER_INT = 0xFFffFFfd;
26 private static final int OFPP_ALL_INT = 0xFFffFFfc;
27 private static final int OFPP_FLOOD_INT = 0xFFffFFfb;
28 private static final int OFPP_NORMAL_INT = 0xFFffFFfa;
29 private static final int OFPP_TABLE_INT = 0xFFffFFf9;
30 private static final int OFPP_MAX_INT = 0xFFffFF00;
31 private static final int OFPP_IN_PORT_INT = 0xFFffFFf8;
32
33 // private short constants (OF1.0) to avoid duplication in the code
34 // should not have to use these outside this class
35 private static final short OFPP_ANY_SHORT = (short) 0xFFff;
36 private static final short OFPP_LOCAL_SHORT = (short) 0xFFfe;
37 private static final short OFPP_CONTROLLER_SHORT = (short) 0xFFfd;
38 private static final short OFPP_ALL_SHORT = (short) 0xFFfc;
39 private static final short OFPP_FLOOD_SHORT = (short) 0xFFfb;
40 private static final short OFPP_NORMAL_SHORT = (short) 0xFFfa;
41 private static final short OFPP_TABLE_SHORT = (short) 0xFFf9;
42 private static final short OFPP_IN_PORT_SHORT = (short) 0xFFf8;
43 private static final short OFPP_MAX_SHORT = (short) 0xFF00;
44 private static final int OFPP_MAX_SHORT_UNSIGNED = 0xFF00;
45
46 // ////////////// public constants - use to access well known OpenFlow ports
47
48 /** Maximum number of physical and logical switch ports. */
49 public final static OFPort MAX = new NamedPort(OFPP_MAX_INT, "max");
50
51 /**
52 * Send the packet out the input port. This reserved port must be explicitly
53 * used in order to send back out of the input port.
54 */
55 public final static OFPort IN_PORT = new NamedPort(OFPP_IN_PORT_INT, "in_port");
56
57 /**
58 * Submit the packet to the first flow table NB: This destination port can
59 * only be used in packet-out messages.
60 */
61 public final static OFPort TABLE = new NamedPort(OFPP_TABLE_INT, "table");
62
63 /** Process with normal L2/L3 switching. */
64 public final static OFPort NORMAL = new NamedPort(OFPP_NORMAL_INT, "normal");
65
66 /**
67 * All physical ports in VLAN, except input port and those blocked or link
68 * down
69 */
70 public final static OFPort FLOOD = new NamedPort(OFPP_FLOOD_INT, "flood");
71
72 /** All physical ports except input port */
73 public final static OFPort ALL = new NamedPort(OFPP_ALL_INT, "all");
74
75 /** Send to controller */
76 public final static OFPort CONTROLLER =
77 new NamedPort(OFPP_CONTROLLER_INT, "controller");
78
79 /** local openflow "port" */
80 public final static OFPort LOCAL = new NamedPort(OFPP_LOCAL_INT, "local");
81
82 /**
83 * Wildcard port used only for flow mod (delete) and flow stats requests.
84 * Selects all flows regardless of output port (including flows with no
85 * output port). NOTE: OpenFlow 1.0 calls this 'NONE'
86 */
87 public final static OFPort ANY = new NamedPort(OFPP_ANY_INT, "any");
88
89 public static final OFPort NO_MASK = OFPort.of(0xFFFFFFFF);
90 public static final OFPort FULL_MASK = OFPort.of(0x0);
Andreas Wundsamb75c4ad2013-09-23 14:45:35 -070091
Yotam Harcholf3f11152013-09-05 16:47:16 -070092 /** cache of frequently used ports */
93 private static class PrecachedPort {
94 private final static OFPort p1 = new OFPort(1);
95 private final static OFPort p2 = new OFPort(2);
96 private final static OFPort p3 = new OFPort(3);
97 private final static OFPort p4 = new OFPort(4);
98 private final static OFPort p5 = new OFPort(5);
99 private final static OFPort p6 = new OFPort(6);
100 private final static OFPort p7 = new OFPort(7);
101 private final static OFPort p8 = new OFPort(8);
102 private final static OFPort p9 = new OFPort(9);
103 private final static OFPort p10 = new OFPort(10);
104 private final static OFPort p11 = new OFPort(11);
105 private final static OFPort p12 = new OFPort(12);
106 private final static OFPort p13 = new OFPort(13);
107 private final static OFPort p14 = new OFPort(14);
108 private final static OFPort p15 = new OFPort(15);
109 private final static OFPort p16 = new OFPort(16);
110 private final static OFPort p17 = new OFPort(17);
111 private final static OFPort p18 = new OFPort(18);
112 private final static OFPort p19 = new OFPort(19);
113 private final static OFPort p20 = new OFPort(20);
114 private final static OFPort p21 = new OFPort(21);
115 private final static OFPort p22 = new OFPort(22);
116 private final static OFPort p23 = new OFPort(23);
117 private final static OFPort p24 = new OFPort(24);
118 private final static OFPort p25 = new OFPort(25);
119 private final static OFPort p26 = new OFPort(26);
120 private final static OFPort p27 = new OFPort(27);
121 private final static OFPort p28 = new OFPort(28);
122 private final static OFPort p29 = new OFPort(29);
123 private final static OFPort p31 = new OFPort(31);
124 private final static OFPort p32 = new OFPort(32);
125 private final static OFPort p33 = new OFPort(33);
126 private final static OFPort p34 = new OFPort(34);
127 private final static OFPort p35 = new OFPort(35);
128 private final static OFPort p36 = new OFPort(36);
129 private final static OFPort p37 = new OFPort(37);
130 private final static OFPort p38 = new OFPort(38);
131 private final static OFPort p39 = new OFPort(39);
132 private final static OFPort p40 = new OFPort(40);
133 private final static OFPort p41 = new OFPort(41);
134 private final static OFPort p42 = new OFPort(42);
135 private final static OFPort p43 = new OFPort(43);
136 private final static OFPort p44 = new OFPort(44);
137 private final static OFPort p45 = new OFPort(45);
138 private final static OFPort p46 = new OFPort(46);
139 private final static OFPort p47 = new OFPort(47);
140 private final static OFPort p48 = new OFPort(48);
141 }
142
143 /** raw openflow port number as a signed 32 bit integer */
144 private final int portNumber;
145
146 /** private constructor. use of*-Factory methods instead */
147 private OFPort(final int portNumber) {
148 this.portNumber = portNumber;
149 }
150
151 /**
152 * get an OFPort object corresponding to a raw 32-bit integer port number.
153 * NOTE: The port object may either be newly allocated or cached. Do not
154 * rely on either behavior.
155 *
156 * @param portNumber
157 * @return a corresponding OFPort
158 */
159 public static OFPort ofInt(final int portNumber) {
160 switch (portNumber) {
161 case 1:
162 return PrecachedPort.p1;
163 case 2:
164 return PrecachedPort.p2;
165 case 3:
166 return PrecachedPort.p3;
167 case 4:
168 return PrecachedPort.p4;
169 case 5:
170 return PrecachedPort.p5;
171 case 6:
172 return PrecachedPort.p6;
173 case 7:
174 return PrecachedPort.p7;
175 case 8:
176 return PrecachedPort.p8;
177 case 9:
178 return PrecachedPort.p9;
179 case 10:
180 return PrecachedPort.p10;
181 case 11:
182 return PrecachedPort.p11;
183 case 12:
184 return PrecachedPort.p12;
185 case 13:
186 return PrecachedPort.p13;
187 case 14:
188 return PrecachedPort.p14;
189 case 15:
190 return PrecachedPort.p15;
191 case 16:
192 return PrecachedPort.p16;
193 case 17:
194 return PrecachedPort.p17;
195 case 18:
196 return PrecachedPort.p18;
197 case 19:
198 return PrecachedPort.p19;
199 case 20:
200 return PrecachedPort.p20;
201 case 21:
202 return PrecachedPort.p21;
203 case 22:
204 return PrecachedPort.p22;
205 case 23:
206 return PrecachedPort.p23;
207 case 24:
208 return PrecachedPort.p24;
209 case 25:
210 return PrecachedPort.p25;
211 case 26:
212 return PrecachedPort.p26;
213 case 27:
214 return PrecachedPort.p27;
215 case 28:
216 return PrecachedPort.p28;
217 case 29:
218 return PrecachedPort.p29;
219 case 31:
220 return PrecachedPort.p31;
221 case 32:
222 return PrecachedPort.p32;
223 case 33:
224 return PrecachedPort.p33;
225 case 34:
226 return PrecachedPort.p34;
227 case 35:
228 return PrecachedPort.p35;
229 case 36:
230 return PrecachedPort.p36;
231 case 37:
232 return PrecachedPort.p37;
233 case 38:
234 return PrecachedPort.p38;
235 case 39:
236 return PrecachedPort.p39;
237 case 40:
238 return PrecachedPort.p40;
239 case 41:
240 return PrecachedPort.p41;
241 case 42:
242 return PrecachedPort.p42;
243 case 43:
244 return PrecachedPort.p43;
245 case 44:
246 return PrecachedPort.p44;
247 case 45:
248 return PrecachedPort.p45;
249 case 46:
250 return PrecachedPort.p46;
251 case 47:
252 return PrecachedPort.p47;
253 case 48:
254 return PrecachedPort.p48;
255 case OFPP_MAX_INT:
256 return MAX;
257 case OFPP_IN_PORT_INT:
258 return IN_PORT;
259 case OFPP_TABLE_INT:
260 return TABLE;
261 case OFPP_NORMAL_INT:
262 return NORMAL;
263 case OFPP_FLOOD_INT:
264 return FLOOD;
265 case OFPP_ALL_INT:
266 return ALL;
267 case OFPP_CONTROLLER_INT:
268 return CONTROLLER;
269 case OFPP_LOCAL_INT:
270 return LOCAL;
271 case OFPP_ANY_INT:
272 return ANY;
273 default:
274 // note: This means effectively : portNumber > OFPP_MAX_SHORT
275 // accounting for
276 // signedness of both portNumber and OFPP_MAX_INT(which is
277 // -256).
278 // Any unsigned integer value > OFPP_MAX_INT will be ]-256:0[
279 // when read signed
280 if (portNumber < 0 && portNumber > OFPP_MAX_INT)
281 throw new IllegalArgumentException("Unknown special port number: "
282 + portNumber);
283 return new OFPort(portNumber);
284 }
285 }
286
287 /** convenience function: delegates to ofInt */
288 public static OFPort of(final int portNumber) {
289 return ofInt(portNumber);
290 }
291
292 /**
293 * get an OFPort object corresponding to a raw signed 16-bit integer port
294 * number (OF1.0). Note that the port returned will have the corresponding
295 * 32-bit integer value allocated as its port number. NOTE: The port object
296 * may either be newly allocated or cached. Do not rely on either behavior.
297 *
298 * @param portNumber
299 * @return a corresponding OFPort
300 */
301 public static OFPort ofShort(final short portNumber) {
302 switch (portNumber) {
303 case 1:
304 return PrecachedPort.p1;
305 case 2:
306 return PrecachedPort.p2;
307 case 3:
308 return PrecachedPort.p3;
309 case 4:
310 return PrecachedPort.p4;
311 case 5:
312 return PrecachedPort.p5;
313 case 6:
314 return PrecachedPort.p6;
315 case 7:
316 return PrecachedPort.p7;
317 case 8:
318 return PrecachedPort.p8;
319 case 9:
320 return PrecachedPort.p9;
321 case 10:
322 return PrecachedPort.p10;
323 case 11:
324 return PrecachedPort.p11;
325 case 12:
326 return PrecachedPort.p12;
327 case 13:
328 return PrecachedPort.p13;
329 case 14:
330 return PrecachedPort.p14;
331 case 15:
332 return PrecachedPort.p15;
333 case 16:
334 return PrecachedPort.p16;
335 case 17:
336 return PrecachedPort.p17;
337 case 18:
338 return PrecachedPort.p18;
339 case 19:
340 return PrecachedPort.p19;
341 case 20:
342 return PrecachedPort.p20;
343 case 21:
344 return PrecachedPort.p21;
345 case 22:
346 return PrecachedPort.p22;
347 case 23:
348 return PrecachedPort.p23;
349 case 24:
350 return PrecachedPort.p24;
351 case 25:
352 return PrecachedPort.p25;
353 case 26:
354 return PrecachedPort.p26;
355 case 27:
356 return PrecachedPort.p27;
357 case 28:
358 return PrecachedPort.p28;
359 case 29:
360 return PrecachedPort.p29;
361 case 31:
362 return PrecachedPort.p31;
363 case 32:
364 return PrecachedPort.p32;
365 case 33:
366 return PrecachedPort.p33;
367 case 34:
368 return PrecachedPort.p34;
369 case 35:
370 return PrecachedPort.p35;
371 case 36:
372 return PrecachedPort.p36;
373 case 37:
374 return PrecachedPort.p37;
375 case 38:
376 return PrecachedPort.p38;
377 case 39:
378 return PrecachedPort.p39;
379 case 40:
380 return PrecachedPort.p40;
381 case 41:
382 return PrecachedPort.p41;
383 case 42:
384 return PrecachedPort.p42;
385 case 43:
386 return PrecachedPort.p43;
387 case 44:
388 return PrecachedPort.p44;
389 case 45:
390 return PrecachedPort.p45;
391 case 46:
392 return PrecachedPort.p46;
393 case 47:
394 return PrecachedPort.p47;
395 case 48:
396 return PrecachedPort.p48;
397 case OFPP_MAX_SHORT:
398 return MAX;
399 case OFPP_IN_PORT_SHORT:
400 return IN_PORT;
401 case OFPP_TABLE_SHORT:
402 return TABLE;
403 case OFPP_NORMAL_SHORT:
404 return NORMAL;
405 case OFPP_FLOOD_SHORT:
406 return FLOOD;
407 case OFPP_ALL_SHORT:
408 return ALL;
409 case OFPP_CONTROLLER_SHORT:
410 return CONTROLLER;
411 case OFPP_LOCAL_SHORT:
412 return LOCAL;
413 case OFPP_ANY_SHORT:
414 return ANY;
415 default:
416 // note: This means effectively : portNumber > OFPP_MAX_SHORT
417 // accounting for
418 // signedness of both portNumber and OFPP_MAX_SHORT (which is
419 // -256).
420 // Any unsigned integer value > OFPP_MAX_SHORT will be ]-256:0[
421 // when read signed
422 if (portNumber < 0 && portNumber > OFPP_MAX_SHORT)
423 throw new IllegalArgumentException("Unknown special port number: "
424 + portNumber);
425 return new OFPort(portNumber);
426 }
427 }
428
429 /** return the port number as a int32 */
430 public int getPortNumber() {
431 return portNumber;
432 }
433
434 /**
435 * return the port number as int16. Special ports as defined by the OpenFlow
436 * spec will be converted to their OpenFlow 1.0 equivalent. port numbers >=
437 * FF00 will cause a IllegalArgumentException to be thrown
438 *
439 * @throws IllegalArgumentException
440 * if a regular port number exceeds the maximum value in OF1.0
441 **/
442 public short getShortPortNumber() {
443
444 switch (portNumber) {
445 case OFPP_MAX_INT:
446 return OFPP_MAX_SHORT;
447 case OFPP_IN_PORT_INT:
448 return OFPP_IN_PORT_SHORT;
449 case OFPP_TABLE_INT:
450 return OFPP_TABLE_SHORT;
451 case OFPP_NORMAL_INT:
452 return OFPP_NORMAL_SHORT;
453 case OFPP_FLOOD_INT:
454 return OFPP_FLOOD_SHORT;
455 case OFPP_ALL_INT:
456 return OFPP_ALL_SHORT;
457 case OFPP_CONTROLLER_INT:
458 return OFPP_CONTROLLER_SHORT;
459 case OFPP_LOCAL_INT:
460 return OFPP_LOCAL_SHORT;
461 case OFPP_ANY_INT:
462 return OFPP_ANY_SHORT;
463
464 default:
465 if (portNumber >= OFPP_MAX_SHORT_UNSIGNED || portNumber < 0)
466 throw new IllegalArgumentException("32bit Port number "
467 + U32.f(portNumber)
468 + " cannot be represented as uint16 (OF1.0)");
469
470 return (short) portNumber;
471 }
472 }
473
474 @Override
475 public String toString() {
476 return Long.toString(U32.f(portNumber));
477 }
478
479 /** Extension of OFPort for named ports */
480 static class NamedPort extends OFPort {
481 private final String name;
482
483 NamedPort(final int portNo, final String name) {
484 super(portNo);
485 this.name = name;
486 }
487
488 public String getName() {
489 return name;
490 }
491
492 @Override
493 public String toString() {
494 return name;
495 }
496 }
497
498 @Override
499 public int getLength() {
500 return LENGTH;
501 }
Andreas Wundsamb75c4ad2013-09-23 14:45:35 -0700502
Yotam Harcholf3f11152013-09-05 16:47:16 -0700503 @Override
504 public boolean equals(Object obj) {
505 if (!(obj instanceof OFPort))
506 return false;
507 OFPort other = (OFPort)obj;
508 if (other.portNumber != this.portNumber)
509 return false;
510 return true;
511 }
512
513 @Override
514 public int hashCode() {
515 final int prime = 53;
516 int result = 1;
517 result = prime * result + portNumber;
518 return result;
519 }
520
521 public void write2Bytes(ChannelBuffer c) {
522 c.writeShort(this.portNumber);
523 }
524
525 public static OFPort read2Bytes(ChannelBuffer c) throws OFParseError {
526 return OFPort.ofShort(c.readShort());
527 }
528
529 public void write4Bytes(ChannelBuffer c) {
530 c.writeInt(this.portNumber);
531 }
532
533 public static OFPort read4Bytes(ChannelBuffer c) throws OFParseError {
534 return OFPort.of((int)(c.readUnsignedInt() & 0xFFFFFFFF));
535 }
536
537 @Override
538 public OFPort applyMask(OFPort mask) {
539 return OFPort.of(this.portNumber & mask.portNumber);
540 }
541}