From f2635f621083f3d124c690bda3614960ccf35227 Mon Sep 17 00:00:00 2001 From: Sai MarapaReddy Date: Mon, 11 Jul 2016 17:20:08 -0700 Subject: [PATCH] Bug 5390 - Adding Ipv6 L3ArbitraryBitMask feature support. New yang file is created to accomodate the introduction of ipv6 L3ArbitraryBitMask feature. It includes unit test coverage. Sample Payload Input: 2070:2070:2001:2001:2001:0471:0471:0471 FFFF::0471 2001:2001:2001:2001:2001:0471:0471:0471 FFFF:FFFF::FFFF Change-Id: I901bd17b716fafbb44a5e0a1d7237764b14fd23c Signed-off-by: Sai MarapaReddy Author: Eleftherios Koxias Author: Sai MarapaReddy --- ...aylight-ipv6-arbitrary-bitmask-fields.yang | 50 ++++ .../main/yang/opendaylight-match-types.yang | 4 + .../core/sal/convertor/IpConversionUtil.java | 122 +++++++- .../convertor/match/MatchConvertorImpl.java | 191 ++++++++++-- .../sal/convertor/IpConversionUtilTest.java | 78 +++++ .../match/MatchConvertorImpl2Test.java | 29 ++ .../match/MatchConvertorImplV13Test.java | 277 +++++++++++++++++- 7 files changed, 715 insertions(+), 36 deletions(-) create mode 100644 model/model-flow-base/src/main/yang/opendaylight-ipv6-arbitrary-bitmask-fields.yang diff --git a/model/model-flow-base/src/main/yang/opendaylight-ipv6-arbitrary-bitmask-fields.yang b/model/model-flow-base/src/main/yang/opendaylight-ipv6-arbitrary-bitmask-fields.yang new file mode 100644 index 0000000000..a2f1820736 --- /dev/null +++ b/model/model-flow-base/src/main/yang/opendaylight-ipv6-arbitrary-bitmask-fields.yang @@ -0,0 +1,50 @@ +module opendaylight-ipv6-arbitrary-bitmask-fields { + namespace "urn:opendaylight:opendaylight-ipv6-arbitrary-bitmask-fields"; + prefix "ipv6-arbitrary-bitmask"; + + import ietf-inet-types {prefix inet; revision-date "2013-07-15";} + + + revision 2016-02-24 { + description "Initial revision"; + } + + typedef ipv6-arbitrary-mask { + type string { + pattern + '(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:))'; + } + } + + grouping "ipv6-match-arbitrary-bitmask-fields" { + + leaf ipv6-source-address-no-mask { + description "IPv6 source address with no mask."; + type inet:ipv6-address; + } + + leaf ipv6-source-arbitrary-bitmask { + description "Arbitrary bit mask of IPv6 source address."; + type ipv6-arbitrary-mask; + } + + leaf ipv6-destination-address-no-mask { + description "IPv6 destination address with no mask."; + type inet:ipv6-address; + } + + leaf ipv6-destination-arbitrary-bitmask { + description "Arbitrary bit mask of IPv6 destination address."; + type ipv6-arbitrary-mask; + } + } + +} \ No newline at end of file diff --git a/model/model-flow-base/src/main/yang/opendaylight-match-types.yang b/model/model-flow-base/src/main/yang/opendaylight-match-types.yang index 1c7f62d673..7414eb977b 100644 --- a/model/model-flow-base/src/main/yang/opendaylight-match-types.yang +++ b/model/model-flow-base/src/main/yang/opendaylight-match-types.yang @@ -7,6 +7,7 @@ module opendaylight-match-types { import opendaylight-l2-types {prefix l2t;revision-date "2013-08-27";} import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} import opendaylight-arbitrary-bitmask-fields {prefix mask; revision-date "2016-01-30";} + import opendaylight-ipv6-arbitrary-bitmask-fields {prefix ipv6-arbitrary-mask; revision-date "2016-02-24";} revision "2013-10-26" { description "Initial revision of match types"; @@ -333,6 +334,9 @@ module opendaylight-match-types { case "ipv6-match" { uses "ipv6-match-fields"; } + case "ipv6-match-arbitrary-bit-mask"{ + uses ipv6-arbitrary-mask:ipv6-match-arbitrary-bitmask-fields; + } case "arp-match" { uses "arp-match-fields"; } diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java index d88d9cab7e..fe4ad06c9f 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtil.java @@ -8,32 +8,33 @@ package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor; +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.net.InetAddresses; +import com.google.common.primitives.UnsignedBytes; import java.math.BigInteger; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; import java.util.Iterator; import java.util.List; -import com.google.common.collect.Lists; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; +import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Iterators; -import com.google.common.net.InetAddresses; -import com.google.common.primitives.UnsignedBytes; - /** * Created by Martin Bobak <mbobak@cisco.com> on 5.3.2015. @@ -51,6 +52,7 @@ public final class IpConversionUtil { private static final int IPV4_ADDRESS_LENGTH = 32; private static final int IPV6_ADDRESS_LENGTH = 128; private static final String DEFAULT_ARBITRARY_BIT_MASK = "255.255.255.255"; + private static final String DEFAULT_IPV6_ARBITRARY_BITMASK = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"; /* * Prefix bytearray lookup table. We concatenate the prefixes @@ -132,13 +134,13 @@ public final class IpConversionUtil { return IetfInetUtil.INSTANCE.ipv4PrefixFor(ipv4Address, countBits(bytemask)); } - public static DottedQuad createArbitraryBitMask(final byte [] bytemask) { + public static DottedQuad createArbitraryBitMask(final byte [] bitmask) { DottedQuad dottedQuad = null; - if (bytemask == null ) { + if (bitmask == null ) { dottedQuad = new DottedQuad(DEFAULT_ARBITRARY_BIT_MASK); } else { try { - dottedQuad = new DottedQuad(InetAddress.getByAddress(bytemask).getHostAddress()); + dottedQuad = new DottedQuad(InetAddress.getByAddress(bitmask).getHostAddress()); } catch (UnknownHostException e) { LOG.error("Failed to create the dottedQuad notation for the given mask ", e); } @@ -146,6 +148,20 @@ public final class IpConversionUtil { return dottedQuad; } + public static Ipv6ArbitraryMask createIpv6ArbitraryBitMask(final byte [] bitmask) { + Ipv6ArbitraryMask ipv6ArbitraryMask = null; + if (bitmask == null ) { + ipv6ArbitraryMask = new Ipv6ArbitraryMask(DEFAULT_IPV6_ARBITRARY_BITMASK); + } else { + try { + ipv6ArbitraryMask = new Ipv6ArbitraryMask(InetAddress.getByAddress(bitmask).getHostAddress()); + } catch (UnknownHostException e) { + LOG.error("Failed to create the Ipv6ArbitraryMask notation for the given mask ", e); + } + } + return ipv6ArbitraryMask; + } + public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address){ return IetfInetUtil.INSTANCE.ipv6PrefixFor(ipv6Address); } @@ -386,7 +402,7 @@ public final class IpConversionUtil { List partsV6Prefix = Lists.newArrayList(splittedV6Prefix.iterator()); boolean valid = true; - + try { mask = Integer.parseInt(partsV6Prefix.get(1)); if (mask > 128) { @@ -618,6 +634,27 @@ public final class IpConversionUtil { return netMask; } + public static Ipv6ArbitraryMask extractIpv6AddressMask(final Ipv6Prefix ipv6Prefix) { + Iterator addressParts = PREFIX_SPLITTER.split(ipv6Prefix.getValue()).iterator(); + addressParts.next(); + int maskLength = 0; + if (addressParts.hasNext()) { + maskLength = Integer.parseInt(addressParts.next()); + } + BitSet ipmask = new BitSet(128); + ipmask.set(0,maskLength,true); + ipmask.set(maskLength+1,128,false); + byte[] finalmask = new byte[16]; + System.arraycopy(ipmask.toByteArray(),0,finalmask,0,ipmask.toByteArray().length); + InetAddress inetAddress = null; + try { + inetAddress = InetAddress.getByAddress(finalmask); + } catch (UnknownHostException e) { + LOG.error("Failed to convert the Ipv6 subnetmask from integer to mask value ", e); + } + return new Ipv6ArbitraryMask(inetAddress.getHostAddress()); + } + public static Integer extractIpv6Prefix(final Ipv6Prefix ipv6Prefix) { return IetfInetUtil.INSTANCE.splitIpv6Prefix(ipv6Prefix).getValue(); } @@ -641,7 +678,7 @@ public final class IpConversionUtil { try { maskInIpFormat = InetAddress.getByName(maskValue); } catch (UnknownHostException e) { - LOG.error ("Failed to resolve the ip address of the mask",e); + LOG.error ("Failed to resolve the ip address of the mask ",e); } byte[] bytes = maskInIpFormat.getAddress(); return bytes; @@ -655,7 +692,6 @@ public final class IpConversionUtil { String maskInBits; // converting byte array to bits maskInBits = new BigInteger(1, byteMask).toString(2); - ArrayList stringMaskArrayList = new ArrayList(Arrays.asList(maskInBits.split("(?!^)"))); for (String string:stringMaskArrayList) { integerMaskArrayList.add(Integer.parseInt(string)); @@ -678,4 +714,62 @@ public final class IpConversionUtil { } return false; } + + public static final byte[] convertIpv6ArbitraryMaskToByteArray(final Ipv6ArbitraryMask mask) { + String maskValue; + if (mask.getValue() != null) { + maskValue = mask.getValue(); + } else { + maskValue = DEFAULT_IPV6_ARBITRARY_BITMASK; + } + InetAddress maskInIpFormat = null; + try { + maskInIpFormat = InetAddress.getByName(maskValue); + } catch (UnknownHostException e) { + LOG.error ("Failed to convert mask string to ipv6 format mask ",e); + } + return maskInIpFormat.getAddress(); + } + + public static boolean isIpv6ArbitraryBitMask(final byte[] byteMask) { + if (byteMask == null) { + return false; + } else { + ArrayList integerMaskArrayList = new ArrayList(); + String maskInBits; + // converting byte array to bits + maskInBits = new BigInteger(1, byteMask).toString(2); + ArrayList stringMaskArrayList = new ArrayList(Arrays.asList(maskInBits.split("(?!^)"))); + for (String string:stringMaskArrayList) { + integerMaskArrayList.add(Integer.parseInt(string)); + } + return checkIpv6ArbitraryBitMask(integerMaskArrayList); + } + } + + private static boolean checkIpv6ArbitraryBitMask(final ArrayList arrayList) { + // checks 0*1* case - Leading zeros in arrayList are truncated + if (arrayList.size() > 0 && arrayList.size() < IPV6_ADDRESS_LENGTH) { + return true; + } else { + //checks 1*0*1 case + for (int i=0; i> { private static void layer3Match(final List matchEntryList, final Layer3Match layer3Match) { if (layer3Match != null) { + if(layer3Match instanceof Ipv6MatchArbitraryBitMask){ + Ipv6MatchArbitraryBitMask Ipv6ArbitraryMaskMatchFields = (Ipv6MatchArbitraryBitMask) layer3Match; + if (Ipv6ArbitraryMaskMatchFields.getIpv6SourceAddressNoMask() != null) { + MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder(); + matchEntryBuilder.setOxmClass(OpenflowBasicClass.class); + matchEntryBuilder.setOxmMatchField(Ipv6Src.class); + + Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(Ipv6ArbitraryMaskMatchFields.getIpv6SourceAddressNoMask()); + Ipv6ArbitraryMask sourceArbitrarySubNetMask = Ipv6ArbitraryMaskMatchFields.getIpv6SourceArbitraryBitmask(); + boolean hasMask = false; + if (sourceArbitrarySubNetMask != null) { + byte[] maskByteArray = IpConversionUtil.convertIpv6ArbitraryMaskToByteArray(sourceArbitrarySubNetMask); + if (maskByteArray != null) { + ipv6SrcBuilder.setMask(maskByteArray); + hasMask = true; + } + } + matchEntryBuilder.setHasMask(hasMask); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + matchEntryBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + matchEntryList.add(matchEntryBuilder.build()); + } + if (Ipv6ArbitraryMaskMatchFields.getIpv6DestinationAddressNoMask() != null) { + MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder(); + matchEntryBuilder.setOxmClass(OpenflowBasicClass.class); + matchEntryBuilder.setOxmMatchField(Ipv6Dst.class); + + Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + Ipv6DstBuilder ipv6DstBuilder = new Ipv6DstBuilder(); + + ipv6DstBuilder.setIpv6Address(Ipv6ArbitraryMaskMatchFields.getIpv6DestinationAddressNoMask()); + Ipv6ArbitraryMask destinationArbitrarySubNetMask = Ipv6ArbitraryMaskMatchFields.getIpv6DestinationArbitraryBitmask(); + + boolean hasMask = false; + if (destinationArbitrarySubNetMask != null) { + byte[] maskByteArray = IpConversionUtil.convertIpv6ArbitraryMaskToByteArray(destinationArbitrarySubNetMask); + if (maskByteArray != null) { + ipv6DstBuilder.setMask(maskByteArray); + hasMask = true; + } + } + matchEntryBuilder.setHasMask(hasMask); + ipv6DstCaseBuilder.setIpv6Dst(ipv6DstBuilder.build()); + matchEntryBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + matchEntryList.add(matchEntryBuilder.build()); + } + } if(layer3Match instanceof Ipv4MatchArbitraryBitMask) { Ipv4MatchArbitraryBitMask ipv4MatchArbitraryBitMaskFields = (Ipv4MatchArbitraryBitMask) layer3Match; if (ipv4MatchArbitraryBitMaskFields.getIpv4SourceAddressNoMask() != null) { @@ -1160,6 +1209,7 @@ public class MatchConvertorImpl implements MatchConvertor> { Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder = new Ipv4MatchArbitraryBitMaskBuilder(); ArpMatchBuilder arpMatchBuilder = new ArpMatchBuilder(); Ipv6MatchBuilder ipv6MatchBuilder = new Ipv6MatchBuilder(); + Ipv6MatchArbitraryBitMaskBuilder ipv6MatchArbitraryBitMaskBuilder = new Ipv6MatchArbitraryBitMaskBuilder(); ProtocolMatchFieldsBuilder protocolMatchFieldsBuilder = new ProtocolMatchFieldsBuilder(); TunnelIpv4MatchBuilder tunnelIpv4MatchBuilder = new TunnelIpv4MatchBuilder(); @@ -1498,22 +1548,104 @@ public class MatchConvertorImpl implements MatchConvertor> { } } } else if (ofMatch.getOxmMatchField().equals(Ipv6Src.class)) { - org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.src._case.Ipv6Src ipv6Src = ((Ipv6SrcCase) ofMatch.getMatchEntryValue()).getIpv6Src(); - - if (ipv6Src != null) { - String ipv6PrefixStr = ipv6Src.getIpv6Address().getValue(); - byte[] mask = ipv6Src.getMask(); - setIpv6MatchBuilderFields(ipv6MatchBuilder, ofMatch, ipv6PrefixStr, mask); - matchBuilder.setLayer3Match(ipv6MatchBuilder.build()); + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.src._case.Ipv6Src ipv6Address = ((Ipv6SrcCase) ofMatch.getMatchEntryValue()).getIpv6Src(); + if (ipv6Address != null) { + byte[] mask = ipv6Address.getMask(); + if (mask != null && IpConversionUtil.isIpv6ArbitraryBitMask(mask)) { + // case where ipv6dst is of type ipv6MatchBuilder and ipv6src is of type ipv6MatchArbitrary. + // Need to convert ipv6dst to ipv6MatchArbitrary. + + if (ipv6MatchBuilder.getIpv6Destination() != null) { + Ipv6Prefix ipv6PrefixDestinationAddress = ipv6MatchBuilder.getIpv6Destination(); + Ipv6Address ipv6DstAddress = IpConversionUtil.extractIpv6Address(ipv6PrefixDestinationAddress); + Ipv6ArbitraryMask dstIpv6ArbitraryMask = IpConversionUtil.compressedIpv6MaskFormat( + IpConversionUtil.extractIpv6AddressMask(ipv6PrefixDestinationAddress)); + setDstIpv6MatchArbitraryBitMaskBuilderFields(ipv6MatchArbitraryBitMaskBuilder, ofMatch, + dstIpv6ArbitraryMask, IpConversionUtil.compressedIpv6Format(ipv6DstAddress.getValue())); + } + Ipv6ArbitraryMask srcIpv6ArbitraryMask = IpConversionUtil.compressedIpv6MaskFormat( + IpConversionUtil.createIpv6ArbitraryBitMask(mask)); + String stringIpv6SrcAddress = IpConversionUtil.compressedIpv6Format(ipv6Address.getIpv6Address().getValue()); + setSrcIpv6MatchArbitraryBitMaskBuilderFields(ipv6MatchArbitraryBitMaskBuilder, ofMatch, + srcIpv6ArbitraryMask, stringIpv6SrcAddress); + matchBuilder.setLayer3Match(ipv6MatchArbitraryBitMaskBuilder.build()); + } else if (ipv6MatchArbitraryBitMaskBuilder.getIpv6DestinationAddressNoMask() != null) { + /* + TODO Change comments + Case where destination is of type ipv6MatchArbitraryBitMask already exists in Layer3Match, + source which of type ipv6Match needs to be converted to ipv4MatchArbitraryBitMask. + We convert 1::/32 to 1::/FFFF:FFFF:: + example:- + 1::/32 + 1::1 + FFFF::0001 + after conversion output example:- + 1:: + FFFF:FFFF:: + 1::1 + FFFF::0001 + */ + Ipv6ArbitraryMask srcIpv6ArbitraryMask = IpConversionUtil.compressedIpv6MaskFormat( + IpConversionUtil.createIpv6ArbitraryBitMask(mask)); + String stringIpv6SrcAddress = IpConversionUtil.compressedIpv6Format(ipv6Address.getIpv6Address().getValue()); + setSrcIpv6MatchArbitraryBitMaskBuilderFields(ipv6MatchArbitraryBitMaskBuilder, ofMatch, + srcIpv6ArbitraryMask, stringIpv6SrcAddress); + matchBuilder.setLayer3Match(ipv6MatchArbitraryBitMaskBuilder.build()); + } else { + String stringIpv6SrcAddress = IpConversionUtil.compressedIpv6Format(ipv6Address.getIpv6Address().getValue()); + setIpv6MatchBuilderFields(ipv6MatchBuilder, ofMatch, mask, stringIpv6SrcAddress); + matchBuilder.setLayer3Match(ipv6MatchBuilder.build()); + } } } else if (ofMatch.getOxmMatchField().equals(Ipv6Dst.class)) { - org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.dst._case.Ipv6Dst ipv6Dst = ((Ipv6DstCase) ofMatch.getMatchEntryValue()).getIpv6Dst(); - - if (ipv6Dst != null) { - String ipv6PrefixStr = ipv6Dst.getIpv6Address().getValue(); - byte[] mask = ipv6Dst.getMask(); - setIpv6MatchBuilderFields(ipv6MatchBuilder, ofMatch, ipv6PrefixStr, mask); - matchBuilder.setLayer3Match(ipv6MatchBuilder.build()); + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.dst._case.Ipv6Dst ipv6Address = ((Ipv6DstCase) ofMatch.getMatchEntryValue()).getIpv6Dst(); + if (ipv6Address != null) { + byte[] mask = ipv6Address.getMask(); + if (mask != null && IpConversionUtil.isIpv6ArbitraryBitMask(mask)) { + // case where ipv6src is of type ipv6MatchBuilder and ipv6dst is of type ipv6MatchArbitrary. + // Need to convert ipv6src to ipv6MatchArbitrary. + + if (ipv6MatchBuilder.getIpv6Source() != null) { + Ipv6Prefix ipv6PrefixSourceAddress = ipv6MatchBuilder.getIpv6Source(); + Ipv6Address ipv6SrcAddress = IpConversionUtil.extractIpv6Address(ipv6PrefixSourceAddress); + Ipv6ArbitraryMask srcIpv6Arbitrary = IpConversionUtil.compressedIpv6MaskFormat( + IpConversionUtil.extractIpv6AddressMask(ipv6PrefixSourceAddress)); + setSrcIpv6MatchArbitraryBitMaskBuilderFields(ipv6MatchArbitraryBitMaskBuilder, ofMatch, + srcIpv6Arbitrary, IpConversionUtil.compressedIpv6Format(ipv6SrcAddress.getValue())); + } + Ipv6ArbitraryMask dstIpv6ArbitraryMask = IpConversionUtil.compressedIpv6MaskFormat( + IpConversionUtil.createIpv6ArbitraryBitMask(mask)); + String stringIpv6DstAddress = IpConversionUtil.compressedIpv6Format(ipv6Address.getIpv6Address().getValue()); + setDstIpv6MatchArbitraryBitMaskBuilderFields(ipv6MatchArbitraryBitMaskBuilder, ofMatch, + dstIpv6ArbitraryMask, stringIpv6DstAddress); + matchBuilder.setLayer3Match(ipv6MatchArbitraryBitMaskBuilder.build()); + } else if (ipv6MatchArbitraryBitMaskBuilder.getIpv6SourceAddressNoMask() != null) { + /* + TODO Change comments + Case where source is of type ipv4MatchArbitraryBitMask already exists in Layer3Match, + source which of type ipv6Match needs to be converted to ipv6MatchArbitraryBitMask. + We convert 1::/32 to 1::/FFFF:FFFF:: + example:- + 1::/32 + 1::1 + FFFF::0001 + after conversion output example:- + 1:: + FFFF:FFFF:: + 1::1 + FFFF::0001 + */ + Ipv6ArbitraryMask dstIpv6ArbitraryMask = IpConversionUtil.compressedIpv6MaskFormat( + IpConversionUtil.createIpv6ArbitraryBitMask(mask)); + String stringIpv6DstAddress = IpConversionUtil.compressedIpv6Format(ipv6Address.getIpv6Address().getValue()); + setDstIpv6MatchArbitraryBitMaskBuilderFields(ipv6MatchArbitraryBitMaskBuilder, ofMatch, + dstIpv6ArbitraryMask, stringIpv6DstAddress); + matchBuilder.setLayer3Match(ipv6MatchArbitraryBitMaskBuilder.build()); + } else { + String stringIpv6DstAddress = IpConversionUtil.compressedIpv6Format(ipv6Address.getIpv6Address().getValue()); + setIpv6MatchBuilderFields(ipv6MatchBuilder, ofMatch, mask, stringIpv6DstAddress); + matchBuilder.setLayer3Match(ipv6MatchBuilder.build()); + } } } else if (ofMatch.getOxmMatchField().equals(Ipv6Flabel.class)) { org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.flabel._case.Ipv6Flabel ipv6Flabel = ((Ipv6FlabelCase) ofMatch.getMatchEntryValue()).getIpv6Flabel(); @@ -1608,7 +1740,7 @@ public class MatchConvertorImpl implements MatchConvertor> { return matchBuilder; } - private static void setIpv6MatchBuilderFields(final Ipv6MatchBuilder ipv6MatchBuilder, final MatchEntry ofMatch, final String ipv6PrefixStr, final byte[] mask) { + private static void setIpv6MatchBuilderFields(final Ipv6MatchBuilder ipv6MatchBuilder, final MatchEntry ofMatch, final byte[] mask, final String ipv6PrefixStr) { Ipv6Prefix ipv6Prefix; if (mask != null) { @@ -1666,6 +1798,27 @@ public class MatchConvertorImpl implements MatchConvertor> { ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationAddressNoMask(ipv4Address); } + private static void setSrcIpv6MatchArbitraryBitMaskBuilderFields( + final Ipv6MatchArbitraryBitMaskBuilder ipv6MatchArbitraryBitMaskBuilder, + final MatchEntry ofMatch, final Ipv6ArbitraryMask mask, final String ipv6AddressStr) { + Ipv6Address ipv6Address; + if (mask != null) { + ipv6MatchArbitraryBitMaskBuilder.setIpv6SourceArbitraryBitmask(mask); + } + ipv6Address = new Ipv6Address(ipv6AddressStr); + ipv6MatchArbitraryBitMaskBuilder.setIpv6SourceAddressNoMask(ipv6Address); + } + + private static void setDstIpv6MatchArbitraryBitMaskBuilderFields( + final Ipv6MatchArbitraryBitMaskBuilder ipv6MatchArbitraryBitMaskBuilder, + final MatchEntry ofMatch, final Ipv6ArbitraryMask mask, final String ipv6AddressStr) { + Ipv6Address ipv6Address; + if (mask != null) { + ipv6MatchArbitraryBitMaskBuilder.setIpv6DestinationArbitraryBitmask(mask); + } + ipv6Address = new Ipv6Address(ipv6AddressStr); + ipv6MatchArbitraryBitMaskBuilder.setIpv6DestinationAddressNoMask(ipv6Address); + } private static MatchEntry toOfMplsPbb(final Pbb pbb) { MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder(); diff --git a/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtilTest.java b/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtilTest.java index 74dc0d79ee..d99abfc13a 100644 --- a/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtilTest.java +++ b/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/IpConversionUtilTest.java @@ -17,6 +17,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.opendaylight.ipv6.arbitrary.bitmask.fields.rev160224.Ipv6ArbitraryMask; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -149,4 +150,81 @@ public class IpConversionUtilTest { dottedQuad = IpConversionUtil.extractIpv4AddressMask(new Ipv4Prefix("1.1.1.1/24")); Assert.assertEquals(dottedQuad.getValue(),"255.255.255.0"); } + + @Test + public void convertipv6ArbitraryMaskToByteArrayTest() { + byte[] bytes = {-5,-96,-1,-74,-1,-16,-1,-16, -1,-16,-1,-16,-1,-16,-91,85}; + byte[] maskBytes = IpConversionUtil.convertIpv6ArbitraryMaskToByteArray(new Ipv6ArbitraryMask("fbA0:FFB6:FFF0:FFF0:FFF0:FFF0:FFF0:A555")); + for(int i=0; i entries = convertor.convert(match, new BigInteger("42")); + Assert.assertEquals("Wrong entries size", 2, entries.size()); + + MatchEntry entry = entries.get(0); + checkEntryHeader(entry,Ipv6Src.class,true); + Assert.assertEquals("wrong Ipv6Adress source", "fbA0:FFB6:FFF0:FFF0:FFF0:FFF0:FFF0:AFF0",((Ipv6SrcCase) entry.getMatchEntryValue()).getIpv6Src().getIpv6Address().getValue()); + entry = entries.get(1); + checkEntryHeader(entry,Ipv6Dst.class,true); + Assert.assertEquals("wrong Ipv6Adress destination", "fbA0:FFB6:FFF0:FFF0:FFF0:FFF0:FFF0:AFF0",((Ipv6DstCase) entry.getMatchEntryValue()).getIpv6Dst().getIpv6Address().getValue()); + } } diff --git a/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchConvertorImplV13Test.java b/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchConvertorImplV13Test.java index 56cf237243..d5adffe739 100644 --- a/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchConvertorImplV13Test.java +++ b/openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchConvertorImplV13Test.java @@ -11,7 +11,6 @@ package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; - import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -26,6 +25,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchArbitraryBitMask; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch; @@ -1118,9 +1118,9 @@ public class MatchConvertorImplV13Test { final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatchBuilder.build(); final Ipv6Match ipv6Match = (Ipv6Match) builtMatch.getLayer3Match(); - Assert.assertEquals("Wrong ipv6 src address", "2001:cdba:0000:0000:0000:0000:3257:9657/128", + Assert.assertEquals("Wrong ipv6 src address", "2001:cdba::3257:9657/128", ipv6Match.getIpv6Source().getValue()); - Assert.assertEquals("Wrong ipv6 dst address", "2001:cdba:0000:0000:0000:0000:3257:9658/128", + Assert.assertEquals("Wrong ipv6 dst address", "2001:cdba::3257:9658/128", ipv6Match.getIpv6Destination().getValue()); Assert.assertEquals("Wrong ipv6 nd target", "2001:cdba:0000:0000:0000:0000:3257:9659", ipv6Match.getIpv6NdTarget().getValue()); @@ -1312,4 +1312,275 @@ public class MatchConvertorImplV13Test { Assert.assertEquals("Wrong arp tha", "00:00:00:00:00:04", arpMatch.getArpTargetHardwareAddress().getAddress().getValue()); Assert.assertEquals("Wrong arp tha mask", "01:01:01:02:02:02", arpMatch.getArpTargetHardwareAddress().getMask().getValue()); } + + /** + * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch( + * org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match, java.math.BigInteger, + * org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion)} + */ + @Test + public void testWithMatchEntryWithIpv6ArbitraryMasks() { + final MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + final List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata.class); + entriesBuilder.setHasMask(true); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(true); + final Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + final Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("1001:1001:1001:1001:1001:1001:1001:1001")); + ipv6SrcBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte) 255}); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(true); + final Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + final Ipv6DstBuilder ipv6AddressBuilder = new Ipv6DstBuilder(); + ipv6AddressBuilder.setIpv6Address(new Ipv6Address("2002:2002:2002:2002:2002:2002:2002:2002")); + ipv6AddressBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte) 255}); + ipv6DstCaseBuilder.setIpv6Dst(ipv6AddressBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + builder.setMatchEntry(entries); + final Match match = builder.build(); + + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow + .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF13); + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build(); + + final Ipv6MatchArbitraryBitMask ipv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) builtMatch.getLayer3Match(); + Assert.assertEquals("Wrong ipv6 src address", "1001:1001:1001:1001:1001:1001:1001:1001", + ipv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask().getValue()); + Assert.assertEquals("Wrong ipv6 dst address", "2002:2002:2002:2002:2002:2002:2002:2002", + ipv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask().getValue()); + } + + /** + * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch( + * org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match, java.math.BigInteger, + * org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion)} + */ + @Test + public void testWithMatchEntryWithIpv6SrcCidrlMaskAndDstArbitraryBitMask() { + final MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + final List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata.class); + entriesBuilder.setHasMask(true); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(true); + final Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + final Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("1001:1001:1001:1001:1001:1001:1001:1001")); + ipv6SrcBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(true); + final Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + final Ipv6DstBuilder ipv6AddressBuilder = new Ipv6DstBuilder(); + ipv6AddressBuilder.setIpv6Address(new Ipv6Address("2002:2002:2002:2002:2002:2002:2002:2002")); + ipv6AddressBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte) 255}); + ipv6DstCaseBuilder.setIpv6Dst(ipv6AddressBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + builder.setMatchEntry(entries); + final Match match = builder.build(); + + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow + .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF13); + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build(); + + final Ipv6MatchArbitraryBitMask ipv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) builtMatch.getLayer3Match(); + Assert.assertEquals("Wrong ipv6 src address", "1001:1001:1001:1001:1001:1001:1001:1001", + ipv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask().getValue()); + Assert.assertEquals("Wrong ipv6 dst address", "2002:2002:2002:2002:2002:2002:2002:2002", + ipv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask().getValue()); + } + + /** + * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch( + * org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match, java.math.BigInteger, + * org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion)} + */ + @Test + public void testWithMatchEntryWithIpv6SrcArbitraryBitMaskAndDstCidrMask() { + final MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + final List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata.class); + entriesBuilder.setHasMask(true); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(true); + final Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + final Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("1001:1001:1001:1001:1001:1001:1001:1001")); + ipv6SrcBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte) 255}); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(true); + final Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + final Ipv6DstBuilder ipv6AddressBuilder = new Ipv6DstBuilder(); + ipv6AddressBuilder.setIpv6Address(new Ipv6Address("2002:2002:2002:2002:2002:2002:2002:2002")); + ipv6AddressBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); + ipv6DstCaseBuilder.setIpv6Dst(ipv6AddressBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + builder.setMatchEntry(entries); + final Match match = builder.build(); + + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow + .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF13); + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build(); + + final Ipv6MatchArbitraryBitMask ipv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) builtMatch.getLayer3Match(); + Assert.assertEquals("Wrong ipv6 src address", "1001:1001:1001:1001:1001:1001:1001:1001", + ipv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask().getValue()); + Assert.assertEquals("Wrong ipv6 dst address", "2002:2002:2002:2002:2002:2002:2002:2002", + ipv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask().getValue()); + } + + + /** + * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch( + * org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match, java.math.BigInteger, + * org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion)} + */ + + @Test + public void testWithMatchEntryWithIpv6DstArbitraryBitMaskAndSrcCidrMask() { + final MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + final List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata.class); + entriesBuilder.setHasMask(true); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(true); + final Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + final Ipv6DstBuilder ipv6AddressBuilder = new Ipv6DstBuilder(); + ipv6AddressBuilder.setIpv6Address(new Ipv6Address("1001:1001:1001:1001:1001:1001:1001:1001")); + ipv6AddressBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte) 255}); + ipv6DstCaseBuilder.setIpv6Dst(ipv6AddressBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(true); + final Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + final Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("2002:2002:2002:2002:2002:2002:2002:2002")); + ipv6SrcBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + builder.setMatchEntry(entries); + final Match match = builder.build(); + + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow + .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF13); + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build(); + + final Ipv6MatchArbitraryBitMask ipv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) builtMatch.getLayer3Match(); + Assert.assertEquals("Wrong ipv6 src address", "2002:2002:2002:2002:2002:2002:2002:2002", + ipv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask().getValue()); + Assert.assertEquals("Wrong ipv6 dst address", "1001:1001:1001:1001:1001:1001:1001:1001", + ipv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask().getValue()); + } + + + /** + * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch( + * org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match, java.math.BigInteger, + * org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion)} + */ + + @Test + public void testWithMatchEntryWithIpv6DstCidrMaskAndSrcArbitraryBitMask() { + final MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + final List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata.class); + entriesBuilder.setHasMask(true); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(true); + final Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + final Ipv6DstBuilder ipv6AddressBuilder = new Ipv6DstBuilder(); + ipv6AddressBuilder.setIpv6Address(new Ipv6Address("1001:1001:1001:1001:1001:1001:1001:1001")); + ipv6AddressBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}); + ipv6DstCaseBuilder.setIpv6Dst(ipv6AddressBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(true); + final Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + final Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("2002:2002:2002:2002:2002:2002:2002:2002")); + ipv6SrcBuilder.setMask(new byte[]{(byte) 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte) 255}); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + + builder.setMatchEntry(entries); + final Match match = builder.build(); + + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow + .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF13); + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build(); + + final Ipv6MatchArbitraryBitMask ipv6MatchArbitraryBitMask = (Ipv6MatchArbitraryBitMask) builtMatch.getLayer3Match(); + Assert.assertEquals("Wrong ipv6 src address", "2002:2002:2002:2002:2002:2002:2002:2002", + ipv6MatchArbitraryBitMask.getIpv6SourceAddressNoMask().getValue()); + Assert.assertEquals("Wrong ipv6 dst address", "1001:1001:1001:1001:1001:1001:1001:1001", + ipv6MatchArbitraryBitMask.getIpv6DestinationAddressNoMask().getValue()); + } + + } -- 2.36.6