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