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;
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<OFAction> actionsList; // OF 1.0 actions
/**
* Returns the match in OF 1.0 (OFMatch) form or OF 1.0 + IPv6 extensions
* form (V6Match)
- *
+ *
* @return
*/
public OFMatch getOFMatch() {
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;
* 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;
}
}
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);
}
/**
* Returns the list of actions in OF 1.0 form
- *
+ *
* @return
*/
public List<OFAction> getOFActions() {
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) {
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) {
continue;
}
if (action.getType() == ActionType.SET_NEXT_HOP) {
- // TODO
+ logger.info("Unsupported action: {}", action);
continue;
}
}
/**
* 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
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
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
}
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
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
}
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()));
}
}
}