From: Alessandro Boch Date: Mon, 22 Jul 2013 21:29:03 +0000 (-0700) Subject: Fix IPv6 + subnet flow installation X-Git-Tag: releasepom-0.1.0~264^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=910fa09609cdbf45e06d4b631079795113af59b3 Fix IPv6 + subnet flow installation ISSUE: Flows matching on IPv6 packets are not installed when a mask is specified CHANGE: - Set the proper field in V6Match for subnets - Cleanup V6Match to make use of parent OFMatch fields for IPv4 matches - Fix subnet methods in NetUtils - Fix MatchType and MatchField to consider the network prefix address when checking equality and building hashcode for a Match on NW_SRC and NW_DST Signed-off-by: Alessandro Boch --- 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 8d3a1be203..756a6895dc 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 @@ -51,6 +51,7 @@ 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; @@ -196,35 +197,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); } @@ -354,7 +343,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) { @@ -362,7 +351,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) { @@ -502,7 +491,7 @@ 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( ofMatch.getInputPort(), node))); @@ -569,7 +558,7 @@ public class FlowConverter { } 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( @@ -601,15 +590,30 @@ public class FlowConverter { 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 diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java index c7439edc2e..6c26af2dc7 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java @@ -39,8 +39,8 @@ import org.slf4j.LoggerFactory; public class V6Match extends OFMatch implements Cloneable { private static final Logger logger = LoggerFactory.getLogger(V6Match.class); private static final long serialVersionUID = 1L; - protected InetAddress nwSrc; - protected InetAddress nwDst; + protected Inet6Address nwSrc; + protected Inet6Address nwDst; protected short inputPortMask; protected byte[] dataLayerSourceMask; protected byte[] dataLayerDestinationMask; @@ -49,8 +49,6 @@ public class V6Match extends OFMatch implements Cloneable { protected short dataLayerTypeMask; protected byte networkTypeOfServiceMask; protected byte networkProtocolMask; - protected InetAddress networkSourceMask; - protected InetAddress networkDestinationMask; protected short transportSourceMask; protected short transportDestinationMask; protected short srcIPv6SubnetMaskbits; @@ -135,8 +133,6 @@ public class V6Match extends OFMatch implements Cloneable { this.dataLayerTypeMask = 0; this.dataLayerVirtualLanMask = 0; this.dataLayerVirtualLanPriorityCodePointMask = 0; - this.networkDestinationMask = null; - this.networkSourceMask = null; this.networkTypeOfServiceMask = 0; this.networkProtocolMask = 0; this.transportSourceMask = 0; @@ -163,33 +159,19 @@ public class V6Match extends OFMatch implements Cloneable { this.match_len = 0; this.pad_size = 0; - this.networkSourceMask = null; if (match.getNetworkSource() != 0) { - InetAddress address = null; - try { - address = InetAddress.getByAddress(ByteBuffer.allocate(4) - .putInt(match.getNetworkSource()).array()); - } catch (UnknownHostException e) { - logger.error("",e); - } - this.setNetworkSource(address, null); + InetAddress address = NetUtils.getInetAddress(match.getNetworkSource()); + InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false); + this.setNetworkDestination(address, mask); } else { - this.nwSrc = null; this.nwSrcState = MatchFieldState.MATCH_ABSENT; } - this.networkDestinationMask = null; if (match.getNetworkDestination() != 0) { - InetAddress address = null; - try { - address = InetAddress.getByAddress(ByteBuffer.allocate(4) - .putInt(match.getNetworkDestination()).array()); - } catch (UnknownHostException e) { - logger.error("",e); - } - this.setNetworkDestination(address, null); + InetAddress address = NetUtils.getInetAddress(match.getNetworkDestination()); + InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkDestinationMaskLen(), false); + this.setNetworkDestination(address, mask); } else { - this.nwDst = null; this.nwDstState = MatchFieldState.MATCH_ABSENT; } @@ -475,20 +457,23 @@ public class V6Match extends OFMatch implements Cloneable { @Override public void fromString(String match) throws IllegalArgumentException { if (match.equals("") || match.equalsIgnoreCase("any") - || match.equalsIgnoreCase("all") || match.equals("[]")) + || match.equalsIgnoreCase("all") || match.equals("[]")) { match = "OFMatch[]"; + } String[] tokens = match.split("[\\[,\\]]"); String[] values; int initArg = 0; - if (tokens[0].equals("OFMatch")) + if (tokens[0].equals("OFMatch")) { initArg = 1; + } this.wildcards = OFPFW_ALL; int i; for (i = initArg; i < tokens.length; i++) { values = tokens[i].split("="); - if (values.length != 2) + if (values.length != 2) { throw new IllegalArgumentException("Token " + tokens[i] + " does not have form 'key=value' parsing " + match); + } values[0] = values[0].toLowerCase(); // try to make this case insens if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) { this.inputPort = U16.t(Integer.valueOf(values[1])); @@ -508,11 +493,12 @@ public class V6Match extends OFMatch implements Cloneable { this.wildcards &= ~OFPFW_DL_SRC; } else if (values[0].equals(STR_DL_TYPE) || values[0].equals("eth_type")) { - if (values[1].startsWith("0x")) + if (values[1].startsWith("0x")) { this.dataLayerType = U16.t(Integer.valueOf(values[1] .replaceFirst("0x", ""), 16)); - else + } else { this.dataLayerType = U16.t(Integer.valueOf(values[1])); + } ethTypeState = MatchFieldState.MATCH_FIELD_ONLY; match_len += 6; } else if (values[0].equals(STR_DL_VLAN)) { @@ -526,36 +512,34 @@ public class V6Match extends OFMatch implements Cloneable { } else if (values[0].equals(STR_NW_DST) || values[0].equals("ip_dst")) { try { + InetAddress address = null; + InetAddress mask = null; if (values[1].contains("/")) { - String ipv6addr_wmask[] = values[1].split("/"); - this.nwDst = InetAddress.getByName(ipv6addr_wmask[0]); - this.dstIPv6SubnetMaskbits = Short - .valueOf(ipv6addr_wmask[1]); - nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK; - match_len += 36; + String addressString[] = values[1].split("/"); + address = InetAddress.getByName(addressString[0]); + int masklen = Integer.valueOf(addressString[1]); + mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address); } else { - this.nwDst = InetAddress.getByName(values[1]); - nwDstState = MatchFieldState.MATCH_FIELD_ONLY; - match_len += 20; + address = InetAddress.getByName(values[1]); } + this.setNetworkDestination(address, mask); } catch (UnknownHostException e) { logger.error("",e); } } else if (values[0].equals(STR_NW_SRC) || values[0].equals("ip_src")) { try { + InetAddress address = null; + InetAddress mask = null; if (values[1].contains("/")) { - String ipv6addr_wmask[] = values[1].split("/"); - this.nwSrc = InetAddress.getByName(ipv6addr_wmask[0]); - this.srcIPv6SubnetMaskbits = Short - .valueOf(ipv6addr_wmask[1]); - nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK; - match_len += 36; + String addressString[] = values[1].split("/"); + address = InetAddress.getByName(addressString[0]); + int masklen = Integer.valueOf(addressString[1]); + mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address); } else { - this.nwSrc = InetAddress.getByName(values[1]); - nwSrcState = MatchFieldState.MATCH_FIELD_ONLY; - match_len += 20; + address = InetAddress.getByName(values[1]); } + this.setNetworkSource(address, mask); } catch (UnknownHostException e) { logger.error("",e); } @@ -580,9 +564,10 @@ public class V6Match extends OFMatch implements Cloneable { this.transportSource = U16.t(Integer.valueOf(values[1])); tpSrcState = MatchFieldState.MATCH_FIELD_ONLY; match_len += 6; - } else + } else { throw new IllegalArgumentException("unknown token " + tokens[i] + " parsing " + match); + } } /* @@ -675,11 +660,12 @@ public class V6Match extends OFMatch implements Cloneable { } private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) { - if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) + if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) { /* * mask is not allowed for inport port */ return; + } super.setInputPort(data.getShort()); this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY; this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match @@ -689,9 +675,9 @@ public class V6Match extends OFMatch implements Cloneable { private void readDataLinkDestination(ByteBuffer data, int nxmLen, boolean hasMask) { if (hasMask) { - if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) + if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) { return; - else { + } else { byte[] bytes = new byte[6]; data.get(bytes); super.setDataLayerDestination(bytes); @@ -701,9 +687,9 @@ public class V6Match extends OFMatch implements Cloneable { this.match_len += 16; } } else { - if ((nxmLen != 6) || (data.remaining() < 6)) + if ((nxmLen != 6) || (data.remaining() < 6)) { return; - else { + } else { byte[] bytes = new byte[6]; data.get(bytes); super.setDataLayerDestination(bytes); @@ -718,8 +704,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in data link source */ - if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) + if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) { return; + } byte[] bytes = new byte[6]; data.get(bytes); super.setDataLayerSource(bytes); @@ -732,8 +719,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in ethertype */ - if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) + if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) { return; + } super.setDataLayerType(data.getShort()); this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY; this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match @@ -743,9 +731,9 @@ public class V6Match extends OFMatch implements Cloneable { private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) { short vlan_mask = 0xfff; if (hasMask) { - if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) + if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) { return; - else { + } else { short vlan = data.getShort(); vlan &= vlan_mask; super.setDataLayerVirtualLan(vlan); @@ -755,9 +743,9 @@ public class V6Match extends OFMatch implements Cloneable { this.wildcards ^= (1 << 20); } } else { - if ((nxmLen != 2) || (data.remaining() < 2)) + if ((nxmLen != 2) || (data.remaining() < 2)) { return; - else { + } else { short vlan = data.getShort(); vlan &= vlan_mask; super.setDataLayerVirtualLan(vlan); @@ -773,8 +761,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in IP TOS */ - if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) + if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) { return; + } super.setNetworkTypeOfService(data.get()); this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 5; @@ -785,8 +774,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in IP protocol */ - if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) + if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) { return; + } super.setNetworkProtocol(data.get()); this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 5; @@ -795,41 +785,31 @@ public class V6Match extends OFMatch implements Cloneable { private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) { if (hasMask) { - if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) + if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) { return; - else { + } else { byte[] sbytes = new byte[4]; data.get(sbytes); - try { - this.nwSrc = InetAddress.getByAddress(sbytes); - } catch (UnknownHostException e) { - return; - } + // For compatibility, let's set the IPv4 in the parent OFMatch + int address = NetUtils.byteArray4ToInt(sbytes); + super.setNetworkSource(address); byte[] mbytes = new byte[4]; data.get(mbytes); - try { - this.networkSourceMask = InetAddress.getByAddress(mbytes); - } catch (UnknownHostException e) { - return; - } this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK; this.match_len += 12; int prefixlen = getNetworkMaskPrefixLength(mbytes); this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match - } } else { - if ((nxmLen != 4) || (data.remaining() < 4)) + if ((nxmLen != 4) || (data.remaining() < 4)) { return; - else { + } else { byte[] sbytes = new byte[4]; data.get(sbytes); - try { - this.nwSrc = InetAddress.getByAddress(sbytes); - } catch (UnknownHostException e) { - return; - } + // For compatibility, let's also set the IPv4 in the parent OFMatch + int address = NetUtils.byteArray4ToInt(sbytes); + super.setNetworkSource(address); this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 8; this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match @@ -839,24 +819,16 @@ public class V6Match extends OFMatch implements Cloneable { private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) { if (hasMask) { - if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) + if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) { return; - else { + } else { byte[] dbytes = new byte[4]; data.get(dbytes); - try { - this.nwDst = InetAddress.getByAddress(dbytes); - } catch (UnknownHostException e) { - return; - } + // For compatibility, let's also set the IPv4 in the parent OFMatch + int address = NetUtils.byteArray4ToInt(dbytes); + super.setNetworkDestination(address); byte[] mbytes = new byte[4]; data.get(mbytes); - try { - this.networkDestinationMask = InetAddress - .getByAddress(mbytes); - } catch (UnknownHostException e) { - return; - } this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK; this.match_len += 12; int prefixlen = getNetworkMaskPrefixLength(mbytes); @@ -864,16 +836,13 @@ public class V6Match extends OFMatch implements Cloneable { this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match } } else { - if ((nxmLen != 4) || (data.remaining() < 4)) + if ((nxmLen != 4) || (data.remaining() < 4)) { return; - else { + } else { byte[] dbytes = new byte[4]; data.get(dbytes); - try { - this.nwDst = InetAddress.getByAddress(dbytes); - } catch (UnknownHostException e) { - return; - } + int address = NetUtils.byteArray4ToInt(dbytes); + super.setNetworkDestination(address); this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY; this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match this.match_len += 8; @@ -885,8 +854,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in TCP SRC */ - if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) + if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) { return; + } super.setTransportSource(data.getShort()); this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 6; @@ -897,8 +867,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in TCP DST */ - if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) + if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) { return; + } super.setTransportDestination(data.getShort()); this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 6; @@ -909,8 +880,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in UDP SRC */ - if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) + if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) { return; + } super.setTransportSource(data.getShort()); this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 6; @@ -921,8 +893,9 @@ public class V6Match extends OFMatch implements Cloneable { /* * mask is not allowed in UDP DST */ - if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) + if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) { return; + } super.setTransportDestination(data.getShort()); this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY; this.match_len += 6; @@ -931,34 +904,30 @@ public class V6Match extends OFMatch implements Cloneable { private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) { if (hasMask) { - if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) + if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) { return; - else { + } else { byte[] sbytes = new byte[16]; data.get(sbytes); try { - this.nwSrc = InetAddress.getByAddress(sbytes); + this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes); } catch (UnknownHostException e) { return; } byte[] mbytes = new byte[16]; data.get(mbytes); - try { - this.networkSourceMask = InetAddress.getByAddress(mbytes); - } catch (UnknownHostException e) { - return; - } + this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes); this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK; this.match_len += 36; } } else { - if ((nxmLen != 16) || (data.remaining() < 16)) + if ((nxmLen != 16) || (data.remaining() < 16)) { return; - else { + } else { byte[] sbytes = new byte[16]; data.get(sbytes); try { - this.nwSrc = InetAddress.getByAddress(sbytes); + this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes); } catch (UnknownHostException e) { return; } @@ -970,35 +939,30 @@ public class V6Match extends OFMatch implements Cloneable { private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) { if (hasMask) { - if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) + if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) { return; - else { + } else { byte[] dbytes = new byte[16]; data.get(dbytes); try { - this.nwDst = InetAddress.getByAddress(dbytes); + this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes); } catch (UnknownHostException e) { return; } byte[] mbytes = new byte[16]; data.get(mbytes); - try { - this.networkDestinationMask = InetAddress - .getByAddress(mbytes); - } catch (UnknownHostException e) { - return; - } + this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes); this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK; this.match_len += 36; } } else { - if ((nxmLen != 16) || (data.remaining() < 16)) + if ((nxmLen != 16) || (data.remaining() < 16)) { return; - else { + } else { byte[] dbytes = new byte[16]; data.get(dbytes); try { - this.nwDst = InetAddress.getByAddress(dbytes); + this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes); } catch (UnknownHostException e) { return; } @@ -1021,8 +985,6 @@ public class V6Match extends OFMatch implements Cloneable { + ", dataLayerTypeMask=" + dataLayerTypeMask + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask + ", networkProtocolMask=" + networkProtocolMask - + ", networkSourceMask=" + networkSourceMask - + ", networkDestinationMask=" + networkDestinationMask + ", transportSourceMask=" + transportSourceMask + ", transportDestinationMask=" + transportDestinationMask + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits @@ -1151,10 +1113,10 @@ public class V6Match extends OFMatch implements Cloneable { V6Match ret = (V6Match) super.clone(); try { if (this.nwSrc != null) { - ret.nwSrc = InetAddress.getByAddress(this.nwSrc.getAddress()); + ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress()); } if (this.nwDst != null) { - ret.nwDst = InetAddress.getByAddress(this.nwDst.getAddress()); + ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress()); } return ret; } catch (UnknownHostException e) { @@ -1168,37 +1130,17 @@ public class V6Match extends OFMatch implements Cloneable { * @return */ - public InetAddress getNetworkDest() { + public Inet6Address getNetworkDest() { return this.nwDst; } - /** - * Get nw_src - * - * @return - */ - - public void setNetworkSrc(InetAddress address) { - nwSrc = address; - } - - /** - * Set nw_dst - * - * @return - */ - - public void setNetworkDest(InetAddress address) { - nwDst = address; - } - /** * Set nw_src * * @return */ - public InetAddress getNetworkSrc() { + public Inet6Address getNetworkSrc() { return this.nwSrc; } @@ -1303,35 +1245,63 @@ public class V6Match extends OFMatch implements Cloneable { this.match_len += 5; } - public InetAddress getNetworkSourceMask() { - return networkSourceMask; + public Inet6Address getNetworkSourceMask() { + return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask( + this.srcIPv6SubnetMaskbits, true) : null; } public void setNetworkSource(InetAddress address, InetAddress mask) { - this.nwSrc = address; - if (mask == null) { - this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY; - this.match_len += (address instanceof Inet6Address) ? 20 : 8; + if (address instanceof Inet6Address) { + this.nwSrc = (Inet6Address) address; + if (mask == null) { + this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY; + this.match_len += (address instanceof Inet6Address) ? 20 : 8; + } else { + this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask); + this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK; + this.match_len += (address instanceof Inet6Address) ? 36 : 12; + } } else { - this.networkSourceMask = mask; - this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK; - this.match_len += (address instanceof Inet6Address) ? 36 : 12; + super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress())); + this.wildcards ^= (((1 << 6) - 1) << 8); + if (mask == null) { + this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY; + this.match_len += 8; + } else { + this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK; + this.match_len += 12; + this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8); + } } } - public InetAddress getNetworkDestinationMask() { - return networkDestinationMask; + public Inet6Address getNetworkDestinationMask() { + return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask( + this.dstIPv6SubnetMaskbits, true) : null; } public void setNetworkDestination(InetAddress address, InetAddress mask) { - this.nwDst = address; - if (mask == null) { - this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY; - this.match_len += (address instanceof Inet6Address) ? 20 : 8; + if (address instanceof Inet6Address) { + this.nwDst = (Inet6Address) address; + if (mask == null) { + this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY; + this.match_len += (address instanceof Inet6Address) ? 20 : 8; + } else { + this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask); + this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK; + this.match_len += (address instanceof Inet6Address) ? 36 : 12; + } } else { - this.networkDestinationMask = mask; - this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK; - this.match_len += (address instanceof Inet6Address) ? 36 : 12; + this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress())); + this.wildcards ^= (((1 << 6) - 1) << 14); + if (mask == null) { + this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY; + this.match_len += 8; + } else { + this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK; + this.match_len += 12; + this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14); + } } } @@ -1387,9 +1357,7 @@ public class V6Match extends OFMatch implements Cloneable { result = prime * result + inputPortMask; result = prime * result + ((inputPortState == null) ? 0 : inputPortState.hashCode()); result = prime * result + match_len; - result = prime * result + ((networkDestinationMask == null) ? 0 : networkDestinationMask.hashCode()); result = prime * result + networkProtocolMask; - result = prime * result + ((networkSourceMask == null) ? 0 : networkSourceMask.hashCode()); result = prime * result + networkTypeOfServiceMask; result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode()); result = prime * result + ((nwDstState == null) ? 0 : nwDstState.hashCode()); @@ -1408,83 +1376,105 @@ public class V6Match extends OFMatch implements Cloneable { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj) { return true; - if (!super.equals(obj)) + } + if (!super.equals(obj)) { return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()) { return false; + } V6Match other = (V6Match) obj; - if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) + if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) { return false; - if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) - return false; - if (dataLayerTypeMask != other.dataLayerTypeMask) - return false; - if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) + } + if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) { return false; - if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) + } + if (dataLayerTypeMask != other.dataLayerTypeMask) { return false; - if (dlDestState != other.dlDestState) + } + if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) { return false; - if (dlSourceState != other.dlSourceState) + } + if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) { return false; - if (dlVlanState != other.dlVlanState) + } + if (dlDestState != other.dlDestState) { return false; - if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) + } + if (dlSourceState != other.dlSourceState) { return false; - if (ethTypeState != other.ethTypeState) + } + if (dlVlanState != other.dlVlanState) { return false; - if (inputPortMask != other.inputPortMask) + } + if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) { return false; - if (inputPortState != other.inputPortState) + } + if (ethTypeState != other.ethTypeState) { return false; - if (match_len != other.match_len) + } + if (inputPortMask != other.inputPortMask) { return false; - if (networkDestinationMask == null) { - if (other.networkDestinationMask != null) - return false; - } else if (!networkDestinationMask.equals(other.networkDestinationMask)) + } + if (inputPortState != other.inputPortState) { return false; - if (networkProtocolMask != other.networkProtocolMask) + } + if (match_len != other.match_len) { return false; - if (networkSourceMask == null) { - if (other.networkSourceMask != null) - return false; - } else if (!networkSourceMask.equals(other.networkSourceMask)) + } + if (networkProtocolMask != other.networkProtocolMask) { return false; - if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) + } + if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) { return false; + } if (nwDst == null) { - if (other.nwDst != null) + if (other.nwDst != null) { return false; - } else if (!nwDst.equals(other.nwDst)) + } + } else if (!nwDst.equals(other.nwDst)) { return false; - if (nwDstState != other.nwDstState) + } + if (nwDstState != other.nwDstState) { return false; - if (nwProtoState != other.nwProtoState) + } + if (nwProtoState != other.nwProtoState) { return false; + } if (nwSrc == null) { - if (other.nwSrc != null) + if (other.nwSrc != null) { return false; - } else if (!nwSrc.equals(other.nwSrc)) + } + } else if (!nwSrc.equals(other.nwSrc)) { return false; - if (nwSrcState != other.nwSrcState) + } + if (nwSrcState != other.nwSrcState) { return false; - if (nwTosState != other.nwTosState) + } + if (nwTosState != other.nwTosState) { return false; - if (pad_size != other.pad_size) + } + if (pad_size != other.pad_size) { return false; - if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) + } + if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) { return false; - if (tpDstState != other.tpDstState) + } + if (tpDstState != other.tpDstState) { return false; - if (tpSrcState != other.tpSrcState) + } + if (tpSrcState != other.tpSrcState) { return false; - if (transportDestinationMask != other.transportDestinationMask) + } + if (transportDestinationMask != other.transportDestinationMask) { return false; - if (transportSourceMask != other.transportSourceMask) + } + if (transportSourceMask != other.transportSourceMask) { return false; + } return true; } } diff --git a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java index 75f6a83a32..6afaf5f675 100644 --- a/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java +++ b/opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java @@ -89,9 +89,10 @@ public class V6ExtensionTest { match3.getDataLayerSource())); Assert.assertTrue(Arrays.equals(match.getDataLayerDestination(), match3.getDataLayerDestination())); - Assert.assertTrue(match.getNetworkSrc().equals(match3.getNetworkSrc())); - Assert.assertTrue(match.getNetworkDest() - .equals(match3.getNetworkDest())); + Assert.assertNull(match.getNetworkSrc()); + Assert.assertNull(match3.getNetworkSrc()); + Assert.assertNull(match.getNetworkDest()); + Assert.assertNull(match3.getNetworkDest()); Assert.assertTrue(match.getDataLayerVirtualLan() == match3 .getDataLayerVirtualLan()); Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match3 diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java index 4f3cbbd54b..3b8a295216 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchField.java @@ -9,7 +9,6 @@ package org.opendaylight.controller.sal.match; import java.io.Serializable; - import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -208,6 +207,6 @@ public class MatchField implements Cloneable, Serializable { if (type != other.type) { return false; } - return (type.equalValues(this.value, other.value) && type.equalMasks(this.mask, other.mask)); + return type.equals(this.value, other.value, this.mask, other.mask); } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java index bb5e0079b7..85e505671e 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java @@ -8,7 +8,7 @@ package org.opendaylight.controller.sal.match; -import java.net.Inet6Address; +import java.net.Inet4Address; import java.net.InetAddress; import java.util.Arrays; @@ -242,8 +242,12 @@ public enum MatchType { break; case NW_SRC: case NW_DST: - result = prime * result + ((v == null)? 0 : v.hashCode()); - result = prime * result + ((m == null)? NetUtils.gethighestIP(v instanceof Inet6Address).hashCode() : m.hashCode()); + // Hash code has to take into account only prefix address + InetAddress ip = (InetAddress) v; + int maskLen = (m == null) ? ((ip instanceof Inet4Address) ? 32 : 128) : NetUtils + .getSubnetMaskLength((InetAddress) m); + InetAddress prefix = NetUtils.getSubnetPrefix(ip, maskLen); + result = prime * result + ((v == null)? 0 : prefix.hashCode()); break; default: result = prime * result + ((v == null)? 0 : v.hashCode()); @@ -278,14 +282,10 @@ public enum MatchType { * For network address mask, network node may return full mask for * flows the controller generated with a null mask object */ - byte maskBytes[] = null; - if (a == null) { - maskBytes = ((InetAddress) b).getAddress(); - } else if (b == null) { - maskBytes = ((InetAddress) a).getAddress(); - } - if (maskBytes != null) { - return (NetUtils.getSubnetMaskLength(maskBytes) == 0); + if (a == null || b == null) { + InetAddress mask = (a == null) ? (InetAddress) b : (InetAddress) a; + int maxLength = (mask instanceof Inet4Address) ? 32 : 128; + return (NetUtils.getSubnetMaskLength(mask) == maxLength); } default: if (a == null) { @@ -294,4 +294,23 @@ public enum MatchType { return a.equals(b); } } + + public boolean equals(Object value1, Object value2, Object mask1, Object mask2) { + switch (this) { + case NW_SRC: + case NW_DST: + // Equality to be checked against prefix addresses + InetAddress thisIP = (InetAddress) value1; + int thisMaskLen = (mask1 == null) ? ((thisIP instanceof Inet4Address) ? 32 : 128) : NetUtils + .getSubnetMaskLength((InetAddress) mask1); + InetAddress otherIP = (InetAddress) value2; + int otherMaskLen = (mask2 == null) ? ((otherIP instanceof Inet4Address) ? 32 : 128) : NetUtils + .getSubnetMaskLength((InetAddress) mask2); + + return NetUtils.getSubnetPrefix(thisIP, thisMaskLen) + .equals(NetUtils.getSubnetPrefix(otherIP, otherMaskLen)); + default: + return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2)); + } + } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java index 4b42cb7669..6a3a42fbb9 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.sal.utils; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; @@ -41,7 +42,7 @@ public abstract class NetUtils { /** * Constant holding the broadcast MAC address */ - public static byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1}; + private static final byte[] BroadcastMACAddr = {-1, -1, -1, -1, -1, -1}; /** * Converts a 4 bytes array into an integer number @@ -144,46 +145,44 @@ public abstract class NetUtils { } /** - * Returns the number of contiguous bits belonging to the subnet, that have - * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will - * give a subnet mask length of 8, while ff.00.00.00 will return a subnet - * mask length of 24. If the passed prefixMask object is null, 0 is returned + * Returns the prefix size in bits of the specified subnet mask. Example: + * For the subnet mask ff.ff.ff.e0 it returns 25 while for ff.00.00.00 it + * returns 8. If the passed subnetMask array is null, 0 is returned. * - * @param prefixMask - * the prefix mask as byte array - * @return the length of the prefix network mask + * @param subnetMask + * the subnet mask as byte array + * @return the prefix length as number of bits */ - public static int getSubnetMaskLength(byte[] prefixMask) { + public static int getSubnetMaskLength(byte[] subnetMask) { int maskLength = 0; - if (prefixMask != null) { - // Create bit mask - int intMask = 0; - int numBytes = prefixMask.length; - for (int i = 0; i < numBytes; i++) { - intMask |= (prefixMask[i] & 0xff) << (8 * (numBytes - 1 - i)); + if (subnetMask != null && (subnetMask.length == 4 || subnetMask.length == 16)) { + int index = 0; + while (index < subnetMask.length && subnetMask[index] == (byte) 0xFF) { + maskLength += NetUtils.NumBitsInAByte; + index++; } - - int bit = 1; - while (((intMask & bit) == 0) && (maskLength <= (numBytes * 8))) { - maskLength += 1; - bit = bit << 1; + if (index != subnetMask.length) { + int bits = NetUtils.NumBitsInAByte - 1; + while (bits >= 0 && (subnetMask[index] & 1 << bits) != 0) { + bits--; + maskLength++; + } } } return maskLength; } /** - * Returns the number of contiguous bits belonging to the subnet, that have - * to be masked out Example: A prefix network byte mask of ff.ff.ff.00 will - * give a subnet mask length of 8, while ff.00.00.00 will return a subnet - * mask length of 24 If the passed prefixMask object is null, 0 is returned + * Returns the prefix size in bits of the specified subnet mask. Example: + * For the subnet mask 255.255.255.128 it returns 25 while for 255.0.0.0 it + * returns 8. If the passed subnetMask object is null, 0 is returned * - * @param prefixMask - * the prefix mask as InetAddress - * @return the length of the prefix network mask + * @param subnetMask + * the subnet mask as InetAddress + * @return the prefix length as number of bits */ - public static int getSubnetMaskLength(InetAddress prefixMask) { - return (prefixMask == null) ? 0 : NetUtils.getSubnetMaskLength(prefixMask.getAddress()); + public static int getSubnetMaskLength(InetAddress subnetMask) { + return subnetMask == null ? 0 : NetUtils.getSubnetMaskLength(subnetMask.getAddress()); } /** @@ -247,20 +246,18 @@ public abstract class NetUtils { return false; } - int testMaskLen = (testMask != null) ? NetUtils.getSubnetMaskLength(testMask.getAddress()) : 0; - int filterMaskLen = (filterMask != null) ? NetUtils.getSubnetMaskLength(filterMask.getAddress()) : 0; - - int testPrefixLen = (testAddress instanceof Inet6Address) ? (128 - testMaskLen) : (32 - testMaskLen); - int filterPrefixLen = (filterAddress instanceof Inet6Address) ? (128 - filterMaskLen) : (32 - filterMaskLen); + int testMaskLen = (testMask == null) ? ((testAddress instanceof Inet4Address) ? 32 : 128) : NetUtils + .getSubnetMaskLength(testMask); + int filterMaskLen = NetUtils.getSubnetMaskLength(filterMask); // Mask length check. Test mask has to be more specific than filter one - if (testPrefixLen < filterPrefixLen) { + if (testMaskLen < filterMaskLen) { return true; } // Subnet Prefix on filter mask length must be the same - InetAddress prefix1 = getSubnetPrefix(testAddress, filterPrefixLen); - InetAddress prefix2 = getSubnetPrefix(filterAddress, filterPrefixLen); + InetAddress prefix1 = getSubnetPrefix(testAddress, filterMaskLen); + InetAddress prefix2 = getSubnetPrefix(filterAddress, filterMaskLen); return (!prefix1.equals(prefix2)); } diff --git a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java index 599f97448a..0c7e5bb2e5 100644 --- a/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java +++ b/opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java @@ -200,16 +200,46 @@ public class NetUtilsTest { public void testGetSubnetLen() { byte address[] = { (byte) 128, (byte) 0, (byte) 0, 0 }; - Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 31); + Assert.assertTrue(NetUtils.getSubnetMaskLength(address) == 1); byte address1[] = { (byte) 255, 0, 0, 0 }; - Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 24); + Assert.assertTrue(NetUtils.getSubnetMaskLength(address1) == 8); byte address2[] = { (byte) 255, (byte) 255, (byte) 248, 0 }; - Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 11); + Assert.assertTrue(NetUtils.getSubnetMaskLength(address2) == 21); byte address4[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 254 }; - Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 1); + Assert.assertTrue(NetUtils.getSubnetMaskLength(address4) == 31); + + byte address5[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, + (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, + (byte) 255 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address5) == 128); + + byte address6[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, + (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, + (byte) 254 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address6) == 127); + + byte address7[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, + (byte) 255, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address7) == 64); + + byte address8[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, + (byte) 254, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address8) == 63); + + byte address9[] = { (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 128, + (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address9) == 49); + + byte address10[] = { (byte) 128, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, + (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address10) == 1); + + byte address11[] = { (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, + (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }; + Assert.assertTrue(NetUtils.getSubnetMaskLength(address11) == 0); } @Test