X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FFlowConverter.java;h=2b8f6553d61cb6202f0576b92b4b5890bc30e7f5;hp=47ce283331c0bbe6b29fe6a231761656fdcb7728;hb=1ae37339c083b30bc564af4e608725c514b2e6b7;hpb=4a5b8b61c06c7091a7de5ed9df7456fa325dd909 diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java index 47ce283331..2b8f6553d6 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowConverter.java @@ -16,29 +16,6 @@ import java.util.List; import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6FlowMod; import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match; -import org.openflow.protocol.OFFlowMod; -import org.openflow.protocol.OFMatch; -import org.openflow.protocol.OFMessage; -import org.openflow.protocol.OFPacketOut; -import org.openflow.protocol.OFPort; -import org.openflow.protocol.OFVendor; -import org.openflow.protocol.action.OFAction; -import org.openflow.protocol.action.OFActionDataLayerDestination; -import org.openflow.protocol.action.OFActionDataLayerSource; -import org.openflow.protocol.action.OFActionNetworkLayerAddress; -import org.openflow.protocol.action.OFActionNetworkLayerDestination; -import org.openflow.protocol.action.OFActionNetworkLayerSource; -import org.openflow.protocol.action.OFActionNetworkTypeOfService; -import org.openflow.protocol.action.OFActionOutput; -import org.openflow.protocol.action.OFActionStripVirtualLan; -import org.openflow.protocol.action.OFActionTransportLayer; -import org.openflow.protocol.action.OFActionTransportLayerDestination; -import org.openflow.protocol.action.OFActionTransportLayerSource; -import org.openflow.protocol.action.OFActionVirtualLanIdentifier; -import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint; -import org.openflow.util.U16; -import org.openflow.util.U32; - import org.opendaylight.controller.sal.action.Action; import org.opendaylight.controller.sal.action.ActionType; import org.opendaylight.controller.sal.action.Controller; @@ -67,11 +44,45 @@ import org.opendaylight.controller.sal.match.MatchField; import org.opendaylight.controller.sal.match.MatchType; import org.opendaylight.controller.sal.utils.NetUtils; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; +import org.openflow.protocol.OFFlowMod; +import org.openflow.protocol.OFMatch; +import org.openflow.protocol.OFMessage; +import org.openflow.protocol.OFPacketOut; +import org.openflow.protocol.OFPort; +import org.openflow.protocol.OFVendor; +import org.openflow.protocol.action.OFAction; +import org.openflow.protocol.action.OFActionDataLayer; +import org.openflow.protocol.action.OFActionDataLayerDestination; +import org.openflow.protocol.action.OFActionDataLayerSource; +import org.openflow.protocol.action.OFActionNetworkLayerAddress; +import org.openflow.protocol.action.OFActionNetworkLayerDestination; +import org.openflow.protocol.action.OFActionNetworkLayerSource; +import org.openflow.protocol.action.OFActionNetworkTypeOfService; +import org.openflow.protocol.action.OFActionOutput; +import org.openflow.protocol.action.OFActionStripVirtualLan; +import org.openflow.protocol.action.OFActionTransportLayer; +import org.openflow.protocol.action.OFActionTransportLayerDestination; +import org.openflow.protocol.action.OFActionTransportLayerSource; +import org.openflow.protocol.action.OFActionVirtualLanIdentifier; +import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint; +import org.openflow.util.U16; +import org.openflow.util.U32; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Utility class for converting a SAL Flow into the OF flow and vice-versa */ public class FlowConverter { + protected static final Logger logger = LoggerFactory + .getLogger(FlowConverter.class); + + /* + * The value 0xffff (OFP_VLAN_NONE) is used to indicate + * that no VLAN ID is set for OF Flow. + */ + private static final short OFP_VLAN_NONE = (short) 0xffff; + private Flow flow; // SAL Flow private OFMatch ofMatch; // OF 1.0 match or OF 1.0 + IPv6 extension match private List actionsList; // OF 1.0 actions @@ -97,7 +108,7 @@ public class FlowConverter { /** * Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions * form (V6Match) - * + * * @return */ public OFMatch getOFMatch() { @@ -139,6 +150,9 @@ public class FlowConverter { if (match.isPresent(MatchType.DL_VLAN)) { short vlan = (Short) match.getField(MatchType.DL_VLAN) .getValue(); + if (vlan == MatchType.DL_VLAN_NONE) { + vlan = OFP_VLAN_NONE; + } if (!isIPv6) { ofMatch.setDataLayerVirtualLan(vlan); wildcards &= ~OFMatch.OFPFW_DL_VLAN; @@ -174,7 +188,7 @@ public class FlowConverter { * actually the DSCP field followed by a zero ECN */ byte tos = (Byte) match.getField(MatchType.NW_TOS).getValue(); - byte dscp = (byte) ((int) tos << 2); + byte dscp = (byte) (tos << 2); if (!isIPv6) { ofMatch.setNetworkTypeOfService(dscp); wildcards &= ~OFMatch.OFPFW_NW_TOS; @@ -193,35 +207,23 @@ public class FlowConverter { } } if (match.isPresent(MatchType.NW_SRC)) { - InetAddress address = (InetAddress) match.getField( - MatchType.NW_SRC).getValue(); - InetAddress mask = (InetAddress) match.getField( - MatchType.NW_SRC).getMask(); + InetAddress address = (InetAddress) match.getField(MatchType.NW_SRC).getValue(); + InetAddress mask = (InetAddress) match.getField(MatchType.NW_SRC).getMask(); if (!isIPv6) { - ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address - .getAddress())); - int maskLength = NetUtils - .getSubnetMaskLength((mask == null) ? null : mask - .getAddress()); - wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) - | (maskLength << OFMatch.OFPFW_NW_SRC_SHIFT); + ofMatch.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress())); + int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask); + wildcards = (wildcards & ~OFMatch.OFPFW_NW_SRC_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_SRC_SHIFT); } else { ((V6Match) ofMatch).setNetworkSource(address, mask); } } if (match.isPresent(MatchType.NW_DST)) { - InetAddress address = (InetAddress) match.getField( - MatchType.NW_DST).getValue(); - InetAddress mask = (InetAddress) match.getField( - MatchType.NW_DST).getMask(); + InetAddress address = (InetAddress) match.getField(MatchType.NW_DST).getValue(); + InetAddress mask = (InetAddress) match.getField(MatchType.NW_DST).getMask(); if (!isIPv6) { - ofMatch.setNetworkDestination(NetUtils - .byteArray4ToInt(address.getAddress())); - int maskLength = NetUtils - .getSubnetMaskLength((mask == null) ? null : mask - .getAddress()); - wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) - | (maskLength << OFMatch.OFPFW_NW_DST_SHIFT); + ofMatch.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress())); + int maskLength = (mask == null) ? 32 : NetUtils.getSubnetMaskLength(mask); + wildcards = (wildcards & ~OFMatch.OFPFW_NW_DST_MASK) | ((32 - maskLength) << OFMatch.OFPFW_NW_DST_SHIFT); } else { ((V6Match) ofMatch).setNetworkDestination(address, mask); } @@ -252,13 +254,14 @@ public class FlowConverter { ofMatch.setWildcards(U32.t(Long.valueOf(wildcards))); } } - + logger.trace("SAL Match: {} Openflow Match: {}", flow.getMatch(), + ofMatch); return ofMatch; } /** * Returns the list of actions in OF 1.0 form - * + * * @return */ public List getOFActions() { @@ -350,7 +353,7 @@ public class FlowConverter { OFActionDataLayerSource ofAction = new OFActionDataLayerSource(); ofAction.setDataLayerAddress(a.getDlAddress()); actionsList.add(ofAction); - actionsLength += OFActionDataLayerSource.MINIMUM_LENGTH; + actionsLength += OFActionDataLayer.MINIMUM_LENGTH; continue; } if (action.getType() == ActionType.SET_DL_DST) { @@ -358,7 +361,7 @@ public class FlowConverter { OFActionDataLayerDestination ofAction = new OFActionDataLayerDestination(); ofAction.setDataLayerAddress(a.getDlAddress()); actionsList.add(ofAction); - actionsLength += OFActionDataLayerDestination.MINIMUM_LENGTH; + actionsLength += OFActionDataLayer.MINIMUM_LENGTH; continue; } if (action.getType() == ActionType.SET_NW_SRC) { @@ -407,18 +410,20 @@ public class FlowConverter { continue; } if (action.getType() == ActionType.SET_NEXT_HOP) { - // TODO + logger.info("Unsupported action: {}", action); continue; } } } + logger.trace("SAL Actions: {} Openflow Actions: {}", flow.getActions(), + actionsList); return actionsList; } /** * Utility to convert a SAL flow to an OF 1.0 (OFFlowMod) or to an OF 1.0 + * IPv6 extension (V6FlowMod) Flow modifier Message - * + * * @param sw * @param command * @param port @@ -479,6 +484,9 @@ public class FlowConverter { } } } + logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch, + actionsList); + logger.trace("Openflow Mod Message: {}", fm); return fm; } @@ -493,10 +501,10 @@ public class FlowConverter { if (ofMatch != null) { if (!isIPv6) { // Compute OF1.0 Match - if (ofMatch.getInputPort() != 0) { + if (ofMatch.getInputPort() != 0 && ofMatch.getInputPort() != OFPort.OFPP_LOCAL.getValue()) { salMatch.setField(new MatchField(MatchType.IN_PORT, NodeConnectorCreator.createNodeConnector( - (Short) ofMatch.getInputPort(), node))); + ofMatch.getInputPort(), node))); } if (ofMatch.getDataLayerSource() != null && !NetUtils @@ -516,9 +524,13 @@ public class FlowConverter { salMatch.setField(new MatchField(MatchType.DL_TYPE, ofMatch.getDataLayerType())); } - if (ofMatch.getDataLayerVirtualLan() != 0) { + short vlan = ofMatch.getDataLayerVirtualLan(); + if (vlan != 0) { + if (vlan == OFP_VLAN_NONE) { + vlan = MatchType.DL_VLAN_NONE; + } salMatch.setField(new MatchField(MatchType.DL_VLAN, - ofMatch.getDataLayerVirtualLan())); + vlan)); } if (ofMatch.getDataLayerVirtualLanPriorityCodePoint() != 0) { salMatch.setField(MatchType.DL_VLAN_PR, ofMatch @@ -551,20 +563,20 @@ public class FlowConverter { } if (ofMatch.getTransportSource() != 0) { salMatch.setField(MatchType.TP_SRC, - ((Short) ofMatch.getTransportSource())); + ofMatch.getTransportSource()); } if (ofMatch.getTransportDestination() != 0) { salMatch.setField(MatchType.TP_DST, - ((Short) ofMatch.getTransportDestination())); + ofMatch.getTransportDestination()); } } else { // Compute OF1.0 + IPv6 extensions Match V6Match v6Match = (V6Match) ofMatch; - if (v6Match.getInputPort() != 0) { + if (v6Match.getInputPort() != 0 && v6Match.getInputPort() != OFPort.OFPP_LOCAL.getValue()) { // Mask on input port is not defined salMatch.setField(new MatchField(MatchType.IN_PORT, NodeConnectorCreator.createOFNodeConnector( - (Short) v6Match.getInputPort(), node))); + v6Match.getInputPort(), node))); } if (v6Match.getDataLayerSource() != null && !NetUtils @@ -584,23 +596,42 @@ public class FlowConverter { salMatch.setField(new MatchField(MatchType.DL_TYPE, v6Match.getDataLayerType())); } - if (v6Match.getDataLayerVirtualLan() != 0) { + short vlan = v6Match.getDataLayerVirtualLan(); + if (vlan != 0) { + if (vlan == OFP_VLAN_NONE) { + vlan = MatchType.DL_VLAN_NONE; + } salMatch.setField(new MatchField(MatchType.DL_VLAN, - v6Match.getDataLayerVirtualLan())); + vlan)); } if (v6Match.getDataLayerVirtualLanPriorityCodePoint() != 0) { salMatch.setField(MatchType.DL_VLAN_PR, v6Match .getDataLayerVirtualLanPriorityCodePoint()); } + // V6Match may carry IPv4 address if (v6Match.getNetworkSrc() != null) { salMatch.setField(MatchType.NW_SRC, v6Match.getNetworkSrc(), v6Match.getNetworkSourceMask()); + } else if (v6Match.getNetworkSource() != 0) { + salMatch.setField(MatchType.NW_SRC, NetUtils + .getInetAddress(v6Match.getNetworkSource()), + NetUtils.getInetNetworkMask( + v6Match.getNetworkSourceMaskLen(), + false)); } + // V6Match may carry IPv4 address if (v6Match.getNetworkDest() != null) { salMatch.setField(MatchType.NW_DST, v6Match.getNetworkDest(), v6Match.getNetworkDestinationMask()); + } else if (v6Match.getNetworkDestination() != 0) { + salMatch.setField(MatchType.NW_DST, + NetUtils.getInetAddress(v6Match + .getNetworkDestination()), + NetUtils.getInetNetworkMask( + v6Match.getNetworkDestinationMaskLen(), + false)); } if (v6Match.getNetworkTypeOfService() != 0) { int dscp = NetUtils.getUnsignedByte(v6Match @@ -614,11 +645,11 @@ public class FlowConverter { } if (v6Match.getTransportSource() != 0) { salMatch.setField(MatchType.TP_SRC, - ((Short) v6Match.getTransportSource())); + (v6Match.getTransportSource())); } if (v6Match.getTransportDestination() != 0) { salMatch.setField(MatchType.TP_DST, - ((Short) v6Match.getTransportDestination())); + (v6Match.getTransportDestination())); } } } @@ -680,7 +711,7 @@ public class FlowConverter { try { ip = InetAddress.getByAddress(addr); } catch (UnknownHostException e) { - e.printStackTrace(); + logger.error("", e); } salAction = new SetNwSrc(ip); } else if (ofAction instanceof OFActionNetworkLayerDestination) { @@ -691,7 +722,7 @@ public class FlowConverter { try { ip = InetAddress.getByAddress(addr); } catch (UnknownHostException e) { - e.printStackTrace(); + logger.error("", e); } salAction = new SetNwDst(ip); } else if (ofAction instanceof OFActionNetworkTypeOfService) { @@ -715,7 +746,10 @@ public class FlowConverter { // Create Flow flow = new Flow(salMatch, salActionList); } + logger.trace("Openflow Match: {} Openflow Actions: {}", ofMatch, + actionsList); + logger.trace("SAL Flow: {}", flow); return flow; } -} \ No newline at end of file +}