Merge "added initial waiting for mdsal in tableMissEnforcer"
[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.openflowplugin.api.openflow.md.util.OpenflowVersion;
6 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortNumberUni;
7 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
8 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumberValues;
9 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumberValuesV10;
10
11 /**
12  * Class which integrates the port constants defined and used by MDSAL and the ports defined in openflow java
13  * This class is responsible for converting MDSAL given logical names to port numbers and back.
14  * Any newer version of openflow can have a similar mapping or can/should be extended.
15  *
16  * @author Kamal Rameshan on 5/2/14.
17  */
18 public class OpenflowPortsUtil {
19
20     static ImmutableBiMap<OpenflowVersion, ImmutableBiMap<String, Long>> versionPortMap;
21
22     static final String MAX = "MAX";
23
24     // the init gets called from MDController at the start
25     public static void init() {
26
27         // v1.0 ports
28         final ImmutableBiMap<String, Long> OFv10 = new ImmutableBiMap.Builder<String, Long>()
29                 .put(OutputPortValues.MAX.toString(), Long.valueOf(PortNumberValuesV10.MAX.getIntValue())) //0xff00
30                 .put(OutputPortValues.INPORT.toString(), Long.valueOf(PortNumberValuesV10.INPORT.getIntValue())) //0xfff8
31                 .put(OutputPortValues.TABLE.toString(), Long.valueOf(PortNumberValuesV10.TABLE.getIntValue())) //0xfff9
32                 .put(OutputPortValues.NORMAL.toString(), Long.valueOf(PortNumberValuesV10.NORMAL.getIntValue())) //0xfffa
33                 .put(OutputPortValues.FLOOD.toString(), Long.valueOf(PortNumberValuesV10.FLOOD.getIntValue())) //0xfffb
34                 .put(OutputPortValues.ALL.toString(), Long.valueOf(PortNumberValuesV10.ALL.getIntValue())) //0xfffc
35                 .put(OutputPortValues.CONTROLLER.toString(), Long.valueOf(PortNumberValuesV10.CONTROLLER.getIntValue())) //0xfffd
36                 .put(OutputPortValues.LOCAL.toString(), Long.valueOf(PortNumberValuesV10.LOCAL.getIntValue())) //0xfffe
37                 .put(OutputPortValues.NONE.toString(), Long.valueOf(PortNumberValuesV10.NONE.getIntValue())) //0xfffe
38                 .build();
39
40         // openflow 1.3 reserved ports.
41         // PortNumberValues are defined in OFJava yang. And yang maps an int to all enums. Hence we need to create longs from (-ve) ints
42         // TODO: do we need to define these ports in yang?
43         final ImmutableBiMap<String, Long> OFv13 = new ImmutableBiMap.Builder<String, Long>()
44                 .put(OutputPortValues.MAX.toString(), BinContent.intToUnsignedLong(PortNumberValues.MAX.getIntValue())) //0xffffff00
45                 .put(OutputPortValues.INPORT.toString(), BinContent.intToUnsignedLong(PortNumberValues.INPORT.getIntValue())) //0xfffffff8
46                 .put(OutputPortValues.TABLE.toString(), BinContent.intToUnsignedLong(PortNumberValues.TABLE.getIntValue())) //0xfffffff9
47                 .put(OutputPortValues.NORMAL.toString(), BinContent.intToUnsignedLong(PortNumberValues.NORMAL.getIntValue())) //0xfffffffa
48                 .put(OutputPortValues.FLOOD.toString(), BinContent.intToUnsignedLong(PortNumberValues.FLOOD.getIntValue())) //0xfffffffb
49                 .put(OutputPortValues.ALL.toString(), BinContent.intToUnsignedLong(PortNumberValues.ALL.getIntValue())) //0xfffffffc
50                 .put(OutputPortValues.CONTROLLER.toString(), BinContent.intToUnsignedLong(PortNumberValues.CONTROLLER.getIntValue())) //0xfffffffd
51                 .put(OutputPortValues.LOCAL.toString(), BinContent.intToUnsignedLong(PortNumberValues.LOCAL.getIntValue())) //0xfffffffe
52                 .put(OutputPortValues.ANY.toString(), BinContent.intToUnsignedLong(PortNumberValues.ANY.getIntValue())) //0xffffffff
53                 .build();
54
55         versionPortMap = new ImmutableBiMap.Builder<OpenflowVersion, ImmutableBiMap<String, Long>>()
56                 .put(OpenflowVersion.OF10, OFv10)
57                 .put(OpenflowVersion.OF13, OFv13)
58                 .build();
59
60     }
61
62     public static void close() {
63         versionPortMap = null;
64     }
65
66     public static String getPortLogicalName(final short ofVersion, final long portNumber) {
67         return versionPortMap.get(OpenflowVersion.get(ofVersion)).inverse().get(portNumber);
68     }
69
70     public static String getPortLogicalName(final OpenflowVersion ofVersion, final Long portNumber) {
71         if (ofVersion.equals(OpenflowVersion.UNSUPPORTED)) {
72             return null;
73         }
74         return versionPortMap.get(ofVersion).inverse().get(portNumber);
75     }
76
77     public static Long getPortFromLogicalName(final OpenflowVersion ofVersion, final String logicalNameOrPort) {
78         Long port = versionPortMap.get(ofVersion).get(logicalNameOrPort);
79         if (port == null) {
80             try {
81                 port = Long.decode(logicalNameOrPort);
82             } catch (final NumberFormatException ne) {
83                 //ignore, sent null back.
84                 if (logicalNameOrPort.contains(":")) {
85                     port = Long.parseLong(logicalNameOrPort.substring(logicalNameOrPort.lastIndexOf(":") + 1));
86                 }
87             }
88         }
89         return port;
90     }
91
92     public static PortNumberUni getProtocolAgnosticPort(final OpenflowVersion ofVersion, final Long portNumber) {
93         final String reservedPortLogicalName = getPortLogicalName(ofVersion, portNumber);
94         return (reservedPortLogicalName == null ? new PortNumberUni(portNumber) :
95                 new PortNumberUni(reservedPortLogicalName));
96     }
97
98     public static Long getProtocolPortNumber(final OpenflowVersion ofVersion, final PortNumberUni port) {
99         final String portLogicalName = port.getString();
100
101         if (portLogicalName != null) {
102             return versionPortMap.get(ofVersion).get(portLogicalName);
103         } else {
104             return port.getUint32();
105         }
106     }
107
108     public static Long getMaxPortForVersion(final OpenflowVersion ofVersion) {
109         return getPortFromLogicalName(ofVersion, MAX);
110     }
111
112     public static boolean isPortReserved(final OpenflowVersion ofVersion, final Long portNumber) {
113         return versionPortMap.get(ofVersion).inverse().containsKey(portNumber);
114     }
115
116     /**
117      * @param ofVersion
118      * @param portNumber
119      * @return true if port number is valid for given protocol version
120      */
121     public static boolean checkPortValidity(final OpenflowVersion ofVersion, final Long portNumber) {
122         boolean portIsValid = true;
123         if (portNumber == null) {
124             portIsValid = false;
125         } else if (portNumber < 0) {
126             portIsValid = false;
127         } else if (portNumber > OpenflowPortsUtil.getMaxPortForVersion(ofVersion)) {
128             if (!OpenflowPortsUtil.isPortReserved(ofVersion, portNumber)) {
129                 portIsValid = false;
130             }
131         }
132         return portIsValid;
133     }
134
135     /**
136      * @param portNumber
137      * @return string containing number or logical name
138      */
139     public static String portNumberToString(final PortNumberUni portNumber) {
140         String result = null;
141         if (portNumber.getUint32() != null) {
142             result = String.valueOf(portNumber.getUint32());
143         } else if (portNumber.getString() != null) {
144             result = portNumber.getString();
145         }
146         return result;
147     }
148 }