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