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