Bug-835 - Reserve Ports should be logical ports
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / util / OpenflowPortsUtil.java
1 package org.opendaylight.openflowplugin.openflow.md.util;
2
3 import com.google.common.collect.ImmutableBiMap;
4 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
5 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.CommonPort;
6 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
7 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumberValues;
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumberValuesV10;
9
10 /**
11  * Class which integrates the port constants defined and used by MDSAL and the ports defined in openflow java
12  *
13  * This class is responsible for converting MDSAL given logical names to port numbers and back.
14  *
15  * Any newer version of openflow can have a similar mapping or can/should be extended.
16  *
17  * @author Kamal Rameshan on 5/2/14.
18  */
19 public class OpenflowPortsUtil {
20
21     static ImmutableBiMap<OpenflowVersion, ImmutableBiMap<String, Long>> versionPortMap;
22
23     static final String MAX  = "MAX";
24
25     // the init gets called from MDController at the start
26     public static void init() {
27
28         // v1.0 ports
29         ImmutableBiMap<String, Long> OFv10 = new ImmutableBiMap.Builder<String, Long>()
30                 .put(OutputPortValues.MAX.toString(), new Long(PortNumberValuesV10.MAX.getIntValue())) //0xff00
31                 .put(OutputPortValues.INPORT.toString(), new Long(PortNumberValuesV10.INPORT.getIntValue())) //0xfff8
32                 .put(OutputPortValues.TABLE.toString(), new Long(PortNumberValuesV10.TABLE.getIntValue())) //0xfff9
33                 .put(OutputPortValues.NORMAL.toString(), new Long(PortNumberValuesV10.NORMAL.getIntValue())) //0xfffa
34                 .put(OutputPortValues.FLOOD.toString(), new Long(PortNumberValuesV10.FLOOD.getIntValue())) //0xfffb
35                 .put(OutputPortValues.ALL.toString(), new Long(PortNumberValuesV10.ALL.getIntValue())) //0xfffc
36                 .put(OutputPortValues.CONTROLLER.toString(), new Long(PortNumberValuesV10.CONTROLLER.getIntValue())) //0xfffd
37                 .put(OutputPortValues.LOCAL.toString(), new Long(PortNumberValuesV10.LOCAL.getIntValue())) //0xfffe
38                 .put(OutputPortValues.NONE.toString(), new Long(PortNumberValuesV10.NONE.getIntValue())) //0xfffe
39                 .build();
40
41         // openflow 1.3 reserved ports.
42         // PortNumberValues are defined in OFJava yang. And yang maps an int to all enums. Hence we need to create longs from (-ve) ints
43         // TODO: do we need to define these ports in yang?
44         ImmutableBiMap<String, Long> OFv13 = new ImmutableBiMap.Builder<String, Long>()
45                 .put(OutputPortValues.MAX.toString(), BinContent.intToUnsignedLong(PortNumberValues.MAX.getIntValue())) //0xffffff00
46                 .put(OutputPortValues.INPORT.toString(), BinContent.intToUnsignedLong(PortNumberValues.INPORT.getIntValue())) //0xfffffff8
47                 .put(OutputPortValues.TABLE.toString(), BinContent.intToUnsignedLong(PortNumberValues.TABLE.getIntValue())) //0xfffffff9
48                 .put(OutputPortValues.NORMAL.toString(), BinContent.intToUnsignedLong(PortNumberValues.NORMAL.getIntValue())) //0xfffffffa
49                 .put(OutputPortValues.FLOOD.toString(), BinContent.intToUnsignedLong(PortNumberValues.FLOOD.getIntValue())) //0xfffffffb
50                 .put(OutputPortValues.ALL.toString(), BinContent.intToUnsignedLong(PortNumberValues.ALL.getIntValue())) //0xfffffffc
51                 .put(OutputPortValues.CONTROLLER.toString(), BinContent.intToUnsignedLong(PortNumberValues.CONTROLLER.getIntValue())) //0xfffffffd
52                 .put(OutputPortValues.LOCAL.toString(), BinContent.intToUnsignedLong(PortNumberValues.LOCAL.getIntValue())) //0xfffffffe
53                 .put(OutputPortValues.ANY.toString(), BinContent.intToUnsignedLong(PortNumberValues.ANY.getIntValue())) //0xffffffff
54                 .build();
55
56         versionPortMap =  new ImmutableBiMap.Builder<OpenflowVersion, ImmutableBiMap<String, Long>>()
57                 .put(OpenflowVersion.OF10, OFv10)
58                 .put(OpenflowVersion.OF13, OFv13)
59                 .build();
60
61     }
62
63     public static void close() {
64         versionPortMap = null;
65     }
66
67     public static String getPortLogicalName(OpenflowVersion ofVersion, Long portNumber) {
68        return versionPortMap.get(ofVersion).inverse().get(portNumber);
69     }
70
71     public static Long getPortFromLogicalName(OpenflowVersion ofVersion, String logicalNameOrPort) {
72         Long port = versionPortMap.get(ofVersion).get(logicalNameOrPort);
73         if (port == null) {
74             try {
75                 port = Long.decode(logicalNameOrPort);
76             } catch(NumberFormatException ne) {
77                 //ignore, sent null back.
78             }
79         }
80         return port;
81     }
82
83     public static CommonPort.PortNumber getProtocolAgnosticPort(OpenflowVersion ofVersion, Long portNumber) {
84         String reservedPortLogicalName = getPortLogicalName(ofVersion, portNumber);
85         return (reservedPortLogicalName == null ? new CommonPort.PortNumber(portNumber) :
86                 new CommonPort.PortNumber(reservedPortLogicalName));
87     }
88
89     public static Long getProtocolPortNumber(OpenflowVersion ofVersion, CommonPort.PortNumber port) {
90         String portLogicalName = port.getString();
91
92         if (portLogicalName != null) {
93             return versionPortMap.get(ofVersion).get(portLogicalName);
94         } else {
95             return port.getUint32();
96         }
97     }
98
99     public static Long getMaxPortForVersion(OpenflowVersion ofVersion) {
100         return getPortFromLogicalName (ofVersion, MAX);
101     }
102
103     public static boolean isPortReserved(OpenflowVersion ofVersion, Long portNumber) {
104         return versionPortMap.get(ofVersion).inverse().containsKey(portNumber);
105     }
106 }