1 package org.opendaylight.openflowplugin.openflow.md.util;
3 import org.opendaylight.openflowjava.protocol.api.util.BinContent;
4 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
5 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortNumberUni;
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;
10 import com.google.common.collect.ImmutableBiMap;
13 * Class which integrates the port constants defined and used by MDSAL and the ports defined in openflow java
15 * This class is responsible for converting MDSAL given logical names to port numbers and back.
17 * Any newer version of openflow can have a similar mapping or can/should be extended.
19 * @author Kamal Rameshan on 5/2/14.
21 public class OpenflowPortsUtil {
23 static ImmutableBiMap<OpenflowVersion, ImmutableBiMap<String, Long>> versionPortMap;
25 static final String MAX = "MAX";
27 // the init gets called from MDController at the start
28 public static void init() {
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
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
58 versionPortMap = new ImmutableBiMap.Builder<OpenflowVersion, ImmutableBiMap<String, Long>>()
59 .put(OpenflowVersion.OF10, OFv10)
60 .put(OpenflowVersion.OF13, OFv13)
65 public static void close() {
66 versionPortMap = null;
69 public static String getPortLogicalName(OpenflowVersion ofVersion, Long portNumber) {
70 if (ofVersion.equals(OpenflowVersion.UNSUPPORTED)){
73 return versionPortMap.get(ofVersion).inverse().get(portNumber);
76 public static Long getPortFromLogicalName(OpenflowVersion ofVersion, String logicalNameOrPort) {
77 Long port = versionPortMap.get(ofVersion).get(logicalNameOrPort);
80 port = Long.decode(logicalNameOrPort);
81 } catch(NumberFormatException ne) {
82 //ignore, sent null back.
88 public static PortNumberUni getProtocolAgnosticPort(OpenflowVersion ofVersion, Long portNumber) {
89 String reservedPortLogicalName = getPortLogicalName(ofVersion, portNumber);
90 return (reservedPortLogicalName == null ? new PortNumberUni(portNumber) :
91 new PortNumberUni(reservedPortLogicalName));
94 public static Long getProtocolPortNumber(OpenflowVersion ofVersion, PortNumberUni port) {
95 String portLogicalName = port.getString();
97 if (portLogicalName != null) {
98 return versionPortMap.get(ofVersion).get(portLogicalName);
100 return port.getUint32();
104 public static Long getMaxPortForVersion(OpenflowVersion ofVersion) {
105 return getPortFromLogicalName (ofVersion, MAX);
108 public static boolean isPortReserved(OpenflowVersion ofVersion, Long portNumber) {
109 return versionPortMap.get(ofVersion).inverse().containsKey(portNumber);
115 * @return true if port number is valid for given protocol version
117 public static boolean checkPortValidity(OpenflowVersion ofVersion, Long portNumber) {
118 boolean portIsValid = true;
119 if (portNumber == null) {
121 } else if (portNumber < 0) {
123 } else if (portNumber > OpenflowPortsUtil.getMaxPortForVersion(ofVersion)) {
124 if (!OpenflowPortsUtil.isPortReserved(ofVersion, portNumber)) {
133 * @return string containing number or logical name
135 public static String portNumberToString(PortNumberUni 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();