package org.opendaylight.openflowplugin.applications.statistics.manager.impl.helper;
import com.google.common.net.InetAddresses;
+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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.primitives.UnsignedBytes;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+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.model.match.types.rev131026.MacAddressFilter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
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.Ipv6Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask;
/**
* @author joe
+ * @author sai.marapareddy@gmail.com
*
*/
public class MatchComparatorHelper {
+ private static final Logger LOG = LoggerFactory.getLogger(MatchComparatorHelper.class);
private static final int DEFAULT_SUBNET = 32;
private static final int IPV4_MASK_LENGTH = 32;
private static final int SHIFT_OCTET_1 = 24;
private static final int POSITION_OCTET_2 = 1;
private static final int POSITION_OCTET_3 = 2;
private static final int POSITION_OCTET_4 = 3;
+ private static final String DEFAULT_ARBITRARY_BIT_MASK = "255.255.255.255";
+ private static final String PREFIX_SEPARATOR = "/";
+ private static final int IPV4_ADDRESS_LENGTH = 32;
/*
* Custom EthernetMatch is required because mac address string provided by user in EthernetMatch can be in any case
verdict = MatchComparatorHelper.compareIpv6PrefixNullSafe(statsIpv6Match.getIpv6Source(),
storedIpv6Match.getIpv6Source());
}
- }else {
+ } else if(statsLayer3Match instanceof Ipv4MatchArbitraryBitMask && storedLayer3Match instanceof Ipv4MatchArbitraryBitMask) {
+ // At this moment storedIpv4MatchArbitraryBitMask & statsIpv4MatchArbitraryBitMask will always have non null arbitrary masks.
+ // In case of no / null arbitrary mask, statsLayer3Match will be an instance of Ipv4Match.
+ // Eg:- stats -> 1.0.1.0/255.0.255.0 stored -> 1.1.1.0/255.0.255.0
+ final Ipv4MatchArbitraryBitMask statsIpv4MatchArbitraryBitMask= (Ipv4MatchArbitraryBitMask) statsLayer3Match;
+ final Ipv4MatchArbitraryBitMask storedIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) storedLayer3Match;
+ if((storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null |
+ storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null)) {
+ if(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
+ String storedIpAddress = extractIpv4Address(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(),
+ storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
+ if(MatchComparatorHelper.compareStringNullSafe(storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask().getValue(),
+ statsIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask().getValue())) {
+ verdict = MatchComparatorHelper.compareStringNullSafe(storedIpAddress,
+ statsIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask().getValue());
+ }
+ else {
+ verdict = false;
+ return verdict;
+ }
+ }
+ if(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
+ String storedIpAddress = extractIpv4Address(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask()
+ ,storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
+ if(MatchComparatorHelper.compareStringNullSafe(storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask().getValue(),
+ statsIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask().getValue())) {
+ verdict = MatchComparatorHelper.compareStringNullSafe(storedIpAddress,
+ statsIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask().getValue());
+ }
+ else {
+ verdict = false;
+ }
+ }
+ }
+ else {
+ final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
+ if (nullCheckOut != null) {
+ verdict = nullCheckOut;
+ } else {
+ verdict = storedLayer3Match.equals(statsLayer3Match);
+ }
+ }
+ }
+ else if (statsLayer3Match instanceof Ipv4Match && storedLayer3Match instanceof Ipv4MatchArbitraryBitMask) {
+ // Here stored netmask is an instance of Ipv4MatchArbitraryBitMask, when it is pushed in to switch
+ // it automatically converts it in to cidr format in case of certain subnet masks ( consecutive ones or zeroes)
+ // Eg:- stats src/dest -> 1.1.1.0/24 stored src/dest -> 1.1.1.0/255.255.255.0
+ final Ipv4Match statsIpv4Match = (Ipv4Match) statsLayer3Match;
+ final Ipv4MatchArbitraryBitMask storedIpv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) storedLayer3Match;
+ if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask() != null) {
+ Ipv4Prefix ipv4PrefixDestination;
+ if (storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask() != null) {
+ byte[] destByteMask = convertArbitraryMaskToByteArray(storedIpv4MatchArbitraryBitMask.getIpv4DestinationArbitraryBitmask());
+ ipv4PrefixDestination = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask(), destByteMask);
+ }
+ else{
+ ipv4PrefixDestination = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask());
+ }
+ verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixDestination, statsIpv4Match.getIpv4Destination());
+ if(verdict == false) {
+ return verdict;
+ }
+ }
+ if (storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask() != null) {
+ Ipv4Prefix ipv4PrefixSource;
+ if (storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask() != null) {
+ byte[] srcByteMask = convertArbitraryMaskToByteArray(storedIpv4MatchArbitraryBitMask.getIpv4SourceArbitraryBitmask());
+ ipv4PrefixSource = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask(), srcByteMask);
+ }
+ else {
+ ipv4PrefixSource = createPrefix(storedIpv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask());
+ }
+ verdict = MatchComparatorHelper.compareIpv4PrefixNullSafe(ipv4PrefixSource, statsIpv4Match.getIpv4Source());
+ }
+ } else {
final Boolean nullCheckOut = checkNullValues(storedLayer3Match, statsLayer3Match);
if (nullCheckOut != null) {
verdict = nullCheckOut;
verdict = storedLayer3Match.equals(statsLayer3Match);
}
}
-
return verdict;
}
} else if (!IpAddressEquals(statsIpv4, storedIpv4)) {
verdict = false;
}
+ return verdict;
+ }
+ static boolean compareStringNullSafe(final String stringA, final String stringB) {
+ boolean verdict = true;
+ final Boolean checkDestNullValuesOut = checkNullValues(stringA,stringB);
+ if (checkDestNullValuesOut != null) {
+ verdict = checkDestNullValuesOut;
+ }else if (!stringA.equals(stringB)) {
+ verdict = false;
+ }
return verdict;
}
return integerIpAddress;
}
+ static boolean isArbitraryBitMask(byte[] byteMask) {
+ if (byteMask == null) {
+ return false;
+ }
+ else {
+ ArrayList<Integer> integerMaskArrayList = new ArrayList<Integer>();
+ String maskInBits;
+ // converting byte array to bits
+ maskInBits = new BigInteger(1, byteMask).toString(2);
+ ArrayList<String> stringMaskArrayList = new ArrayList<String>(Arrays.asList(maskInBits.split("(?!^)")));
+ for(String string:stringMaskArrayList){
+ integerMaskArrayList.add(Integer.parseInt(string));
+ }
+ return checkArbitraryBitMask(integerMaskArrayList);
+ }
+ }
+
+ static boolean checkArbitraryBitMask(ArrayList<Integer> arrayList) {
+ // checks 0*1* case - Leading zeros in arrayList are truncated
+ if(arrayList.size()>0 && arrayList.size()<32) {
+ return true;
+ }
+ //checks 1*0*1 case
+ else {
+ for(int i=0; i<arrayList.size()-1;i++) {
+ if(arrayList.get(i) ==0 && arrayList.get(i+1) == 1) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ static final byte[] convertArbitraryMaskToByteArray(DottedQuad mask) {
+ String maskValue;
+ if(mask.getValue() != null && mask != null){
+ maskValue = mask.getValue();
+ }
+ else maskValue = DEFAULT_ARBITRARY_BIT_MASK;
+ InetAddress maskInIpFormat = null;
+ try {
+ maskInIpFormat = InetAddress.getByName(maskValue);
+ } catch (UnknownHostException e) {
+ LOG.error("Failed to recognize the host while converting mask ", e);
+ }
+ byte[] bytes = maskInIpFormat.getAddress();
+ return bytes;
+ }
+
+
+ static String extractIpv4Address(Ipv4Address ipAddress, DottedQuad netMask) {
+ String actualIpAddress="";
+ String[] netMaskParts = netMask.getValue().split("\\.");
+ String[] ipAddressParts = ipAddress.getValue().split("\\.");
+
+ for(int i=0; i<ipAddressParts.length;i++) {
+ int integerFormatIpAddress=Integer.parseInt(ipAddressParts[i]);
+ int integerFormatNetMask=Integer.parseInt(netMaskParts[i]);
+ int ipAddressPart=(integerFormatIpAddress) & (integerFormatNetMask);
+ actualIpAddress += ipAddressPart;
+ if(i != ipAddressParts.length -1 ) {
+ actualIpAddress = actualIpAddress+".";
+ }
+ }
+ return actualIpAddress;
+ }
+
+ static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final byte [] bytemask){
+ return createPrefix(ipv4Address, String.valueOf(countBits(bytemask)));
+ }
+
+ static int countBits(final byte[] mask) {
+ int netmask = 0;
+ for (byte b : mask) {
+ netmask += Integer.bitCount(UnsignedBytes.toInt(b));
+ }
+ return netmask;
+ }
+
+ static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address){
+ return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
+ }
+
+ static Ipv4Prefix createPrefix(final Ipv4Address ipv4Address, final String mask){
+ /*
+ * Ipv4Address has already validated the address part of the prefix,
+ * It is mandated to comply to the same regexp as the address
+ * There is absolutely no point rerunning additional checks vs this
+ * Note - there is no canonical form check here!!!
+ */
+ if (null != mask && !mask.isEmpty()) {
+ return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + mask);
+ } else {
+ return new Ipv4Prefix(ipv4Address.getValue() + PREFIX_SEPARATOR + IPV4_ADDRESS_LENGTH);
+ }
+ }
}
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+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.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMaskBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
import org.junit.Test;
+/**
+ * @author sai.marapareddy@gmail.com (arbitrary masks)
+ */
+
/**
* test of {@link MatchComparatorHelper}
*/
new Ipv4Prefix("191.168.1.1/31")));
}
+ @Test
+ public void compareStringNullSafeTest() {
+ assertEquals(true, MatchComparatorHelper.compareStringNullSafe(null,null));
+ assertEquals(true, MatchComparatorHelper.compareStringNullSafe("Hello", "Hello"));
+ assertEquals(false, MatchComparatorHelper.compareStringNullSafe("Hello", "hello"));
+ }
+
private static final int ip_192_168_1_1 = 0xC0A80101;
private static final int ip_192_168_1_4 = 0xC0A80104;
public void layer3MatchEqualsTest() {
final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
final Ipv4MatchBuilder storedBuilder = new Ipv4MatchBuilder();
-
assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/30"));
storedBuilder.setIpv4Destination(new Ipv4Prefix("191.168.1.1/30"));
assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
-
assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
assertEquals(true,
MatchComparatorHelper.layer3MatchEquals(new ArpMatchBuilder().build(), new ArpMatchBuilder().build()));
}
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryMaskTest(){
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/24"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
+ storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.255.0"));
+ statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/24"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1"));
+ storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.255.255.0"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryMaskRandomTest() {
+ final Ipv4MatchArbitraryBitMaskBuilder statsBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1"));
+ statsBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
+ storedBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("255.255.0.255"));
+ statsBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.0.0.1"));
+ statsBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.7.1.1"));
+ storedBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("255.0.0.255"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryMaskEqualsNullTest() {
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.0.1/32"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.0.1"));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.1.0.0/32"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.1.0.0"));
+ assertEquals(false, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void layer3MatchEqualsIpv4ArbitraryEmptyBitMaskTest(){
+ final Ipv4MatchBuilder statsBuilder = new Ipv4MatchBuilder();
+ final Ipv4MatchArbitraryBitMaskBuilder storedBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
+ assertEquals(true,MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(),storedBuilder.build()));
+ statsBuilder.setIpv4Destination(new Ipv4Prefix("192.168.1.1/32"));
+ storedBuilder.setIpv4DestinationAddressNoMask(new Ipv4Address("192.168.1.1"));
+ statsBuilder.setIpv4Source(new Ipv4Prefix("192.168.1.1/32"));
+ storedBuilder.setIpv4SourceAddressNoMask(new Ipv4Address("192.168.1.1"));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(statsBuilder.build(), storedBuilder.build()));
+ assertEquals(true, MatchComparatorHelper.layer3MatchEquals(null, null));
+ }
+
+ @Test
+ public void extractIpv4AddressTest() {
+ Ipv4Address ipAddress = new Ipv4Address("1.1.1.1");
+ DottedQuad netMask = new DottedQuad("255.255.255.0");
+ String extractedIpAddress;
+ extractedIpAddress = MatchComparatorHelper.extractIpv4Address(ipAddress,netMask);
+ assertEquals(extractedIpAddress,"1.1.1.0");
+ }
+
+ @Test
+ public void convertArbitraryMaskToByteArrayTest() {
+ int value = 0xffffffff;
+ byte[] bytes = new byte[]{
+ (byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) };
+ byte[] maskBytes;
+ maskBytes = MatchComparatorHelper.convertArbitraryMaskToByteArray(new DottedQuad("255.255.255.255"));
+ for(int i=0; i<bytes.length;i++){
+ int mask = maskBytes[i];
+ assertEquals(bytes[i],mask);
+ }
+ }
+
+ @Test
+ public void isArbitraryBitMaskTest() {
+ boolean arbitraryBitMask;
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {1,1,1,1});
+ assertEquals(arbitraryBitMask,true);
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,-1,-1});
+ assertEquals(arbitraryBitMask,false);
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(new byte[] {-1,-1,0,-1});
+ assertEquals(arbitraryBitMask,true);
+ arbitraryBitMask = MatchComparatorHelper.isArbitraryBitMask(null);
+ assertEquals(arbitraryBitMask,false);
+ }
+
+ @Test
+ public void createPrefixTest() {
+ Ipv4Address ipv4Address = new Ipv4Address("1.1.1.1");
+ byte [] byteMask = new byte[] {-1,-1,-1,-1};
+ Ipv4Prefix ipv4Prefix = MatchComparatorHelper.createPrefix(ipv4Address,byteMask);
+ assertEquals(ipv4Prefix,new Ipv4Prefix("1.1.1.1/32"));
+ String nullMask = "";
+ Ipv4Prefix ipv4PrefixNullMask = MatchComparatorHelper.createPrefix(ipv4Address,nullMask);
+ assertEquals(ipv4PrefixNullMask,new Ipv4Prefix("1.1.1.1/32"));
+ Ipv4Prefix ipv4PrefixNoMask = MatchComparatorHelper.createPrefix(ipv4Address);
+ assertEquals(ipv4PrefixNoMask,new Ipv4Prefix("1.1.1.1/32"));
+ }
}
--- /dev/null
+module opendaylight-arbitrary-bitmask-fields {
+ namespace "urn:opendaylight:arbitrary:bitmask:fields";
+ prefix "mask";
+
+ import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
+ import ietf-yang-types {prefix yang; revision-date "2013-07-15";}
+
+ revision "2016-01-30" {
+ description "Initial revision of match types";
+ }
+
+ grouping "ipv4-match-arbitrary-bitmask-fields" {
+
+ leaf ipv4-source-address-no-mask {
+ description "IPv4 source address with no mask .";
+ type inet:ipv4-address;
+ }
+
+ leaf ipv4-destination-address-no-mask {
+ description "IPv4 destination address with no mask.";
+ type inet:ipv4-address;
+ }
+
+ leaf ipv4-source-arbitrary-bitmask {
+ description "IPv4 source address with no mask .";
+ type yang:dotted-quad;
+ }
+
+ leaf ipv4-destination-arbitrary-bitmask {
+ description "IPv4 destination address with no mask.";
+ type yang:dotted-quad;
+ }
+ }
+}
import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
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";}
revision "2013-10-26" {
description "Initial revision of match types";
case "ipv4-match" {
uses "ipv4-match-fields";
}
+ case "ipv4-match-arbitrary-bit-mask"{
+ uses "mask:ipv4-match-arbitrary-bitmask-fields";
+ }
case "ipv6-match" {
uses "ipv6-match-fields";
}
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>ietf-yang-types</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-yang-types-20130715</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.mdsal.model</groupId>
<artifactId>yang-ext</artifactId>
private static final Logger LOG = LoggerFactory.getLogger(HandshakeListenerImpl.class);
- private ConnectionContext connectionContext;
- private DeviceConnectedHandler deviceConnectedHandler;
+ private final ConnectionContext connectionContext;
+ private final DeviceConnectedHandler deviceConnectedHandler;
private HandshakeContext handshakeContext;
/**
* @param connectionContext
* @param deviceConnectedHandler
*/
- public HandshakeListenerImpl(ConnectionContext connectionContext, DeviceConnectedHandler deviceConnectedHandler) {
+ public HandshakeListenerImpl(final ConnectionContext connectionContext, final DeviceConnectedHandler deviceConnectedHandler) {
this.connectionContext = connectionContext;
this.deviceConnectedHandler = deviceConnectedHandler;
}
@Override
- public void onHandshakeSuccessfull(GetFeaturesOutput featureOutput, Short version) {
+ public void onHandshakeSuccessfull(final GetFeaturesOutput featureOutput, final Short version) {
LOG.debug("handshake succeeded: {}", connectionContext.getConnectionAdapter().getRemoteAddress());
closeHandshakeContext();
connectionContext.changeStateToWorking();
deviceConnectedHandler.deviceConnected(connectionContext);
SessionStatistics.countEvent(connectionContext.getNodeId().toString(),
SessionStatistics.ConnectionStatus.CONNECTION_CREATED);
- } catch (Exception e) {
+ } catch (final Exception e) {
LOG.info("ConnectionContext initial processing failed: {}", e.getMessage());
SessionStatistics.countEvent(connectionContext.getNodeId().toString(),
SessionStatistics.ConnectionStatus.CONNECTION_DISCONNECTED_BY_OFP);
- connectionContext.closeConnection(false);
+ connectionContext.closeConnection(true);
}
}
private void closeHandshakeContext() {
try {
handshakeContext.close();
- } catch (Exception e) {
+ } catch (final Exception e) {
LOG.warn("Closing handshake context failed: {}", e.getMessage());
LOG.debug("Detail in hanshake context close:", e);
}
}
@Override
- public void setHandshakeContext(HandshakeContext handshakeContext) {
+ public void setHandshakeContext(final HandshakeContext handshakeContext) {
this.handshakeContext = handshakeContext;
}
}
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.FutureFallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import io.netty.util.HashedWheelTimer;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
return Futures.immediateFuture(null);
}
if (OfpRole.BECOMEMASTER.equals(role)) {
+ MdSalRegistratorUtils.registerMasterServices(getRpcContext(), DeviceContextImpl.this, role);
+ getRpcContext().registerStatCompatibilityServices();
if (!deviceState.deviceSynchronized()) {
//TODO: no necessary code for yet - it needs for initialization phase only
LOG.debug("Setup Empty TxManager {} for initialization phase", getDeviceState().getNodeId());
return Futures.immediateCheckedFuture(null);
}
/* Relevant for no initial Slave-to-Master scenario in cluster */
- return asyncClusterRoleChange(role);
+ final ListenableFuture<Void> deviceInitialization = asyncClusterRoleChange();
+ Futures.addCallback(deviceInitialization, new FutureCallback<Void>() {
+
+ @Override
+ public void onSuccess(@Nullable Void aVoid) {
+ //No operation
+ }
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ LOG.debug("Device {} init unexpected fail. Unregister RPCs", getDeviceState().getNodeId());
+ MdSalRegistratorUtils.unregisterServices(getRpcContext());
+ }
+
+ });
+
+ return deviceInitialization;
} else if (OfpRole.BECOMESLAVE.equals(role)) {
if (null != rpcContext) {
* check all NodeInformation for statistics otherwise statistics will not contains
* all possible MultipartTypes for polling in StatTypeList
*/
- private ListenableFuture<Void> asyncClusterRoleChange(final OfpRole role) {
+ private ListenableFuture<Void> asyncClusterRoleChange() {
if (statCtx == null) {
- final String errMsg = String.format("DeviceCtx {} is up but we are missing StatisticsContext", deviceState.getNodeId());
+ final String errMsg = String.format("DeviceCtx %s is up but we are missing StatisticsContext", deviceState.getNodeId());
LOG.warn(errMsg);
return Futures.immediateFailedFuture(new IllegalStateException(errMsg));
}
if (rpcContext == null) {
- final String errMsg = String.format("DeviceCtx {} is up but we are missing RpcContext", deviceState.getNodeId());
+ final String errMsg = String.format("DeviceCtx %s is up but we are missing RpcContext", deviceState.getNodeId());
LOG.warn(errMsg);
return Futures.immediateFailedFuture(new IllegalStateException(errMsg));
}
@Override
public Void apply(final Boolean input) {
if (ConnectionContext.CONNECTION_STATE.RIP.equals(getPrimaryConnectionContext().getConnectionState())) {
- final String errMsg = String.format("We lost connection for Device {}, context has to be closed.",
+ final String errMsg = String.format("We lost connection for Device %s, context has to be closed.",
getDeviceState().getNodeId());
LOG.warn(errMsg);
transactionChainManager.clearUnsubmittedTransaction();
throw new IllegalStateException(errMsg);
}
if (!input.booleanValue()) {
- final String errMsg = String.format("Get Initial Device {} information fails",
+ final String errMsg = String.format("Get Initial Device %s information fails",
getDeviceState().getNodeId());
LOG.warn(errMsg);
transactionChainManager.clearUnsubmittedTransaction();
LOG.debug("Get Initial Device {} information is successful", getDeviceState().getNodeId());
getDeviceState().setDeviceSynchronized(true);
transactionChainManager.activateTransactionManager();
- MdSalRegistratorUtils.registerMasterServices(getRpcContext(), DeviceContextImpl.this, role);
- getRpcContext().registerStatCompatibilityServices();
initialSubmitTransaction();
getDeviceState().setStatisticsPollingEnabledProp(true);
return null;
}
@Override
- public void close() {
+ public synchronized void close() {
LOG.debug("closing deviceContext: {}, nodeId:{}",
getPrimaryConnectionContext().getConnectionAdapter().getRemoteAddress(),
getDeviceState().getNodeId());
- tearDown();
-
- primaryConnectionContext.closeConnection(false);
+ if (deviceState.isValid()) {
+ primaryConnectionContext.closeConnection(false);
+ tearDown();
+ }
}
private synchronized void tearDown() {
}
}
- protected void tearDownClean() {
+ private void tearDownClean() {
LOG.info("Closing transaction chain manager without cleaning inventory operational");
- Preconditions.checkState(!deviceState.isValid());
transactionChainManager.close();
final LinkedList<DeviceContextClosedHandler> reversedCloseHandlers = new LinkedList<>(closeHandlers);
public class MdSalRegistratorUtils {
+ //TODO: Make one register and one unregister method for all services
+
private static final TypeToken<Delegator<OpendaylightFlowStatisticsService>> COMPOSITE_SERVICE_TYPE_TOKEN =
new TypeToken<Delegator<OpendaylightFlowStatisticsService>>() {
//NOBODY
deviceContext.addAuxiliaryConenctionContext(mockedAuxiliaryConnectionContext);
DeviceContextClosedHandler mockedDeviceContextClosedHandler = mock(DeviceContextClosedHandler.class);
deviceContext.addDeviceContextClosedHandler(mockedDeviceContextClosedHandler);
+ when(deviceState.isValid()).thenReturn(true);
deviceContext.close();
- verify(connectionContext).closeConnection(eq(false));
-// verify(deviceState).setValid(eq(false));
-// verify(mockedAuxiliaryConnectionContext).closeConnection(eq(false));
+ verify(connectionContext).closeConnection(false);
}
@Test
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.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.Iterator;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IetfInetUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+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;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;
/**
* Created by Martin Bobak <mbobak@cisco.com> on 5.3.2015.
* v6 routines added by Anton Ivanov on 14.6.2015
+ * Arbitrary masks by sai.marapareddy@gmail.com
*/
public final class IpConversionUtil {
+ private static final Logger LOG = LoggerFactory.getLogger(IpConversionUtil.class);
public static final String PREFIX_SEPARATOR = "/";
public static final Splitter PREFIX_SPLITTER = Splitter.on('/');
private static final int INADDR4SZ = 4;
private static final int INT16SZ = 2;
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";
/*
* Prefix bytearray lookup table. We concatenate the prefixes
return IetfInetUtil.INSTANCE.ipv4PrefixFor(ipv4Address, countBits(bytemask));
}
+ public static DottedQuad createArbitraryBitMask(final byte [] bytemask) {
+ DottedQuad dottedQuad = new DottedQuad(DEFAULT_ARBITRARY_BIT_MASK);
+ try {
+ dottedQuad = new DottedQuad(InetAddress.getByAddress(bytemask).getHostAddress());
+ } catch (UnknownHostException e) {
+ LOG.error("Failed to create the dottedQuad notation for the given mask ", e);
+ }
+ return dottedQuad;
+ }
+
public static Ipv6Prefix createPrefix(final Ipv6Address ipv6Address){
return IetfInetUtil.INSTANCE.ipv6PrefixFor(ipv6Address);
}
}
return netmask;
}
+
+ public static final byte[] convertArbitraryMaskToByteArray(DottedQuad mask) {
+ String maskValue;
+ if (mask != null && mask.getValue() != null){
+ maskValue = mask.getValue();
+ }
+ else {
+ maskValue = DEFAULT_ARBITRARY_BIT_MASK;
+ }
+ InetAddress maskInIpFormat = null;
+ try {
+ maskInIpFormat = InetAddress.getByName(maskValue);
+ } catch (UnknownHostException e) {
+ LOG.error ("Failed to resolve the ip address of the mask",e);
+ }
+ byte[] bytes = maskInIpFormat.getAddress();
+ return bytes;
+ }
+
+ public static boolean isArbitraryBitMask(byte[] byteMask) {
+ if (byteMask == null) {
+ return false;
+ }
+ else {
+ ArrayList<Integer> integerMaskArrayList = new ArrayList<Integer>();
+ String maskInBits;
+ // converting byte array to bits
+ maskInBits = new BigInteger(1, byteMask).toString(2);
+ ArrayList<String> stringMaskArrayList = new ArrayList<String>(Arrays.asList(maskInBits.split("(?!^)")));
+ for(String string:stringMaskArrayList){
+ integerMaskArrayList.add(Integer.parseInt(string));
+ }
+ return checkArbitraryBitMask(integerMaskArrayList);
+ }
+ }
+
+ private static boolean checkArbitraryBitMask(ArrayList<Integer> arrayList) {
+ // checks 0*1* case - Leading zeros in arrayList are truncated
+ if(arrayList.size()>0 && arrayList.size()<32) {
+ return true;
+ }
+ //checks 1*0*1 case
+ else {
+ for(int i=0; i<arrayList.size()-1;i++) {
+ if(arrayList.get(i) ==0 && arrayList.get(i+1) == 1) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+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.action.types.rev131112.action.action.set.field._case.SetField;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
-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.Ipv4MatchBuilder;
-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.Ipv6MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.*;
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.SctpMatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
private static void layer3Match(final List<MatchEntry> matchEntryList, final Layer3Match layer3Match) {
if (layer3Match != null) {
- if (layer3Match instanceof Ipv4Match) {
+ if(layer3Match instanceof Ipv4MatchArbitraryBitMask) {
+ Ipv4MatchArbitraryBitMask ipv4MatchArbitraryBitMaskFields = (Ipv4MatchArbitraryBitMask) layer3Match;
+ if (ipv4MatchArbitraryBitMaskFields.getIpv4SourceAddressNoMask() != null) {
+ MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
+ matchEntryBuilder.setOxmClass(OpenflowBasicClass.class);
+ matchEntryBuilder.setOxmMatchField(Ipv4Src.class);
+
+ Ipv4SrcCaseBuilder ipv4SrcCaseBuilder = new Ipv4SrcCaseBuilder();
+ Ipv4SrcBuilder ipv4SrcBuilder = new Ipv4SrcBuilder();
+
+ ipv4SrcBuilder.setIpv4Address(ipv4MatchArbitraryBitMaskFields.getIpv4SourceAddressNoMask());
+ DottedQuad sourceArbitrarySubNetMask = ipv4MatchArbitraryBitMaskFields.getIpv4SourceArbitraryBitmask();
+
+ boolean hasMask = false;
+ if (sourceArbitrarySubNetMask != null) {
+ byte[] maskByteArray = IpConversionUtil.convertArbitraryMaskToByteArray(sourceArbitrarySubNetMask);
+ if (maskByteArray != null) {
+ ipv4SrcBuilder.setMask(maskByteArray);
+ hasMask = true;
+ }
+ }
+ matchEntryBuilder.setHasMask(hasMask);
+ ipv4SrcCaseBuilder.setIpv4Src(ipv4SrcBuilder.build());
+ matchEntryBuilder.setMatchEntryValue(ipv4SrcCaseBuilder.build());
+ matchEntryList.add(matchEntryBuilder.build());
+ }
+ if (ipv4MatchArbitraryBitMaskFields.getIpv4DestinationAddressNoMask() != null) {
+ MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
+ matchEntryBuilder.setOxmClass(OpenflowBasicClass.class);
+ matchEntryBuilder.setOxmMatchField(Ipv4Dst.class);
+
+ Ipv4DstCaseBuilder ipv4DstCaseBuilder = new Ipv4DstCaseBuilder();
+ Ipv4DstBuilder ipv4DstBuilder = new Ipv4DstBuilder();
+
+ ipv4DstBuilder.setIpv4Address(ipv4MatchArbitraryBitMaskFields.getIpv4DestinationAddressNoMask());
+ DottedQuad destArbitrarySubNetMask = ipv4MatchArbitraryBitMaskFields.getIpv4DestinationArbitraryBitmask();
+
+ boolean hasMask = false;
+ if (destArbitrarySubNetMask != null) {
+ byte[] maskByteArray = IpConversionUtil.convertArbitraryMaskToByteArray(destArbitrarySubNetMask);
+ if (maskByteArray != null) {
+ ipv4DstBuilder.setMask(maskByteArray);
+ hasMask = true;
+ }
+ }
+ matchEntryBuilder.setHasMask(hasMask);
+ ipv4DstCaseBuilder.setIpv4Dst(ipv4DstBuilder.build());
+ matchEntryBuilder.setMatchEntryValue(ipv4DstCaseBuilder.build());
+ matchEntryList.add(matchEntryBuilder.build());
+ }
+ }
+ if(layer3Match instanceof Ipv4Match){
Ipv4Match ipv4Match = (Ipv4Match) layer3Match;
if (ipv4Match.getIpv4Source() != null) {
Ipv4Prefix ipv4Prefix = ipv4Match.getIpv4Source();
Icmpv4MatchBuilder icmpv4MatchBuilder = new Icmpv4MatchBuilder();
Icmpv6MatchBuilder icmpv6MatchBuilder = new Icmpv6MatchBuilder();
Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder();
+ Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder = new Ipv4MatchArbitraryBitMaskBuilder();
ArpMatchBuilder arpMatchBuilder = new ArpMatchBuilder();
Ipv6MatchBuilder ipv6MatchBuilder = new Ipv6MatchBuilder();
ProtocolMatchFieldsBuilder protocolMatchFieldsBuilder = new ProtocolMatchFieldsBuilder();
org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.src._case.Ipv4Src ipv4Address = ((Ipv4SrcCase) ofMatch.getMatchEntryValue()).getIpv4Src();
if (ipv4Address != null) {
byte[] mask = ipv4Address.getMask();
- String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
- setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
- matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ if (mask != null && IpConversionUtil.isArbitraryBitMask(mask)) {
+ DottedQuad dottedQuadMask = IpConversionUtil.createArbitraryBitMask(mask);
+ String Ipv4Address = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder, ofMatch, dottedQuadMask, Ipv4Address);
+ matchBuilder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());
+ }
+ else {
+ String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
+ matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ }
}
} else if (ofMatch.getOxmMatchField().equals(Ipv4Dst.class)) {
org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.dst._case.Ipv4Dst ipv4Address = ((Ipv4DstCase) ofMatch.getMatchEntryValue()).getIpv4Dst();
if (ipv4Address != null) {
byte[] mask = ipv4Address.getMask();
- String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
- setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
- matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ if(mask != null && IpConversionUtil.isArbitraryBitMask(mask)) {
+ DottedQuad dottedQuadMask = IpConversionUtil.createArbitraryBitMask(mask);
+ String Ipv4Address = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchArbitraryBitMaskBuilderFields(ipv4MatchArbitraryBitMaskBuilder, ofMatch, dottedQuadMask, Ipv4Address);
+ matchBuilder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());
+ }
+ else {
+ String ipv4PrefixStr = ipv4Address.getIpv4Address().getValue();
+ setIpv4MatchBuilderFields(ipv4MatchBuilder, ofMatch, mask, ipv4PrefixStr);
+ matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
+ }
}
} else if (ofMatch.getOxmMatchField().equals(TunnelIpv4Dst.class)
|| ofMatch.getOxmMatchField().equals(TunnelIpv4Src.class)) {
}
}
+ private static void setIpv4MatchArbitraryBitMaskBuilderFields(final Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder, final MatchEntry ofMatch, final DottedQuad mask, final String ipv4AddressStr) {
+ Ipv4Address ipv4Address;
+ DottedQuad dottedQuad;
+ if (mask != null) {
+ dottedQuad = mask;
+ if (ofMatch.getOxmMatchField().equals(Ipv4Src.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceArbitraryBitmask(dottedQuad);
+ }
+ if (ofMatch.getOxmMatchField().equals(Ipv4Dst.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationArbitraryBitmask(dottedQuad);
+ }
+ }
+ ipv4Address = new Ipv4Address(ipv4AddressStr);
+ if (ofMatch.getOxmMatchField().equals(Ipv4Src.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceAddressNoMask(ipv4Address);
+ }
+ if (ofMatch.getOxmMatchField().equals(Ipv4Dst.class)) {
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationAddressNoMask(ipv4Address);
+ }
+ }
+
private static MatchEntry toOfMplsPbb(final Pbb pbb) {
MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
return setField.build();
}
-
}
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchConvertorUtil;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
/**\r
* @author Anton Ivanov aivanov@brocade.com\r
+ * @author Sai MarapaReddy sai.marapareddy@gmail.com\r
*\r
*/\r
public class IpConversionUtilTest {\r
Assert.assertEquals(maskOutputs[i], mask);\r
}\r
}\r
+\r
+ @Test\r
+ public void convertArbitraryMaskToByteArrayTest() {\r
+ int value = 0xffffffff;\r
+ byte[] bytes = new byte[]{\r
+ (byte)(value >>> 24), (byte)(value >> 16 & 0xff), (byte)(value >> 8 & 0xff), (byte)(value & 0xff) };\r
+ byte[] maskBytes;\r
+ maskBytes = IpConversionUtil.convertArbitraryMaskToByteArray(new DottedQuad("255.255.255.255"));\r
+ for(int i=0; i<bytes.length;i++){\r
+ int mask = maskBytes[i];\r
+ Assert.assertEquals(bytes[i],mask);\r
+ }\r
+ }\r
+\r
+ @Test\r
+ public void isArbitraryBitMaskTest() {\r
+ boolean arbitraryBitMask;\r
+ arbitraryBitMask = IpConversionUtil.isArbitraryBitMask(new byte[] {1,1,1,1});\r
+ Assert.assertEquals(arbitraryBitMask,true);\r
+ arbitraryBitMask = IpConversionUtil.isArbitraryBitMask(new byte[] {-1,-1,-1,-1});\r
+ Assert.assertEquals(arbitraryBitMask,false);\r
+ arbitraryBitMask = IpConversionUtil.isArbitraryBitMask(new byte[] {-1,-1,0,-1});\r
+ Assert.assertEquals(arbitraryBitMask,true);\r
+ arbitraryBitMask = IpConversionUtil.isArbitraryBitMask(null);\r
+ Assert.assertEquals(arbitraryBitMask,false);\r
+ }\r
}\r
import org.junit.Before;\r
import org.junit.Test;\r
import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;\r
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.*;\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DottedQuad;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMaskBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder;\r
Assert.assertEquals("Wrong hasMask", hasMask, entry.isHasMask());\r
}\r
\r
+ /**\r
+ * Test {@link MatchConvertorImpl#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match, java.math.BigInteger)}\r
+ */\r
+ @Test\r
+ public void testIpv4MatchArbitraryBitMaskwithNoMask(){\r
+ MatchBuilder builder = new MatchBuilder();\r
+ Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder= new Ipv4MatchArbitraryBitMaskBuilder();\r
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceAddressNoMask( new Ipv4Address("10.2.2.2"));\r
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationAddressNoMask( new Ipv4Address("10.1.1.1"));\r
+ builder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());\r
+ Match match = builder.build();\r
+\r
+ List<MatchEntry> entries = convertor.convert(match, new BigInteger("42"));\r
+ Assert.assertEquals("Wrong entries size", 2, entries.size());\r
+\r
+ MatchEntry entry = entries.get(0);\r
+ checkEntryHeader(entry,Ipv4Src.class,false);\r
+ Assert.assertEquals("wrong Ipv4Address source", "10.2.2.2",((Ipv4SrcCase) entry.getMatchEntryValue()).getIpv4Src().getIpv4Address().getValue());\r
+ entry = entries.get(1);\r
+ checkEntryHeader(entry,Ipv4Dst.class,false);\r
+ Assert.assertEquals("wrong Ipv4Address destination", "10.1.1.1",((Ipv4DstCase) entry.getMatchEntryValue()).getIpv4Dst().getIpv4Address().getValue());\r
+ }\r
+\r
+ /**\r
+ * Test {@link MatchConvertorImpl#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match, BigInteger)}\r
+ */\r
+ @Test\r
+ public void testIpv4MatchArbitraryBitMaskwithMask(){\r
+ MatchBuilder builder = new MatchBuilder();\r
+ Ipv4MatchArbitraryBitMaskBuilder ipv4MatchArbitraryBitMaskBuilder= new Ipv4MatchArbitraryBitMaskBuilder();\r
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceAddressNoMask( new Ipv4Address("10.2.2.2"));\r
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4SourceArbitraryBitmask(new DottedQuad("0.0.255.0"));\r
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationAddressNoMask( new Ipv4Address("10.1.1.1"));\r
+ ipv4MatchArbitraryBitMaskBuilder.setIpv4DestinationArbitraryBitmask(new DottedQuad("0.240.0.0"));\r
+ builder.setLayer3Match(ipv4MatchArbitraryBitMaskBuilder.build());\r
+ Match match = builder.build();\r
+\r
+ List<MatchEntry> entries = convertor.convert(match, new BigInteger("42"));\r
+ Assert.assertEquals("Wrong entries size", 2, entries.size());\r
+\r
+ MatchEntry entry = entries.get(0);\r
+ checkEntryHeader(entry,Ipv4Src.class,true);\r
+ Assert.assertEquals("wrong Ipv4Address source", "10.2.2.2",((Ipv4SrcCase) entry.getMatchEntryValue()).getIpv4Src().getIpv4Address().getValue());\r
+ entry = entries.get(1);\r
+ checkEntryHeader(entry,Ipv4Dst.class,true);\r
+ Assert.assertEquals("wrong Ipv4Adress destination", "10.1.1.1",((Ipv4DstCase) entry.getMatchEntryValue()).getIpv4Dst().getIpv4Address().getValue());\r
+ }\r
+\r
/**\r
* Test {@link MatchConvertorImpl#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match, java.math.BigInteger)}\r
*/\r
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchArbitraryBitMask;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;\r
builtMatch.getTunnel().getTunnelId());\r
}\r
\r
+ /**\r
+ * 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)}\r
+ */\r
+ @Test\r
+ public void testWithMatchEntryWithArbitraryMasks() {\r
+ final MatchBuilder builder = new MatchBuilder();\r
+ builder.setType(OxmMatchType.class);\r
+ final List<MatchEntry> entries = new ArrayList<>();\r
+ MatchEntryBuilder entriesBuilder = new MatchEntryBuilder();\r
+ entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
+ entriesBuilder.setOxmMatchField(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata.class);\r
+ entriesBuilder.setHasMask(true);\r
+\r
+ entriesBuilder = new MatchEntryBuilder();\r
+ entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
+ entriesBuilder.setOxmMatchField(Ipv4Src.class);\r
+ entriesBuilder.setHasMask(true);\r
+ final Ipv4SrcCaseBuilder ipv4SrcCaseBuilder = new Ipv4SrcCaseBuilder();\r
+ final Ipv4SrcBuilder ipv4SrcBuilder = new Ipv4SrcBuilder();\r
+ ipv4SrcBuilder.setIpv4Address(new Ipv4Address("10.1.1.1"));\r
+ ipv4SrcBuilder.setMask(new byte[]{(byte) 255, 0, (byte) 255, 0});\r
+ ipv4SrcCaseBuilder.setIpv4Src(ipv4SrcBuilder.build());\r
+ entriesBuilder.setMatchEntryValue(ipv4SrcCaseBuilder.build());\r
+ entries.add(entriesBuilder.build());\r
+\r
+ entriesBuilder = new MatchEntryBuilder();\r
+ entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
+ entriesBuilder.setOxmMatchField(Ipv4Dst.class);\r
+ entriesBuilder.setHasMask(true);\r
+ final Ipv4DstCaseBuilder ipv4DstCaseBuilder = new Ipv4DstCaseBuilder();\r
+ final Ipv4DstBuilder ipv4AddressBuilder = new Ipv4DstBuilder();\r
+ ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.1.1"));\r
+ ipv4AddressBuilder.setMask(new byte[]{(byte) 255, 0, (byte) 240, 0});\r
+ ipv4DstCaseBuilder.setIpv4Dst(ipv4AddressBuilder.build());\r
+ entriesBuilder.setMatchEntryValue(ipv4DstCaseBuilder.build());\r
+ entries.add(entriesBuilder.build());\r
+\r
+ builder.setMatchEntry(entries);\r
+ final Match match = builder.build();\r
+\r
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
+ .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF10);\r
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build();\r
+\r
+ final Ipv4MatchArbitraryBitMask ipv4MatchArbitraryBitMask = (Ipv4MatchArbitraryBitMask) builtMatch.getLayer3Match();\r
+ Assert.assertEquals("Wrong ipv4 src address", "10.1.1.1", ipv4MatchArbitraryBitMask.getIpv4SourceAddressNoMask().getValue());\r
+ Assert.assertEquals("Wrong ipv4 dst address", "10.0.1.1", ipv4MatchArbitraryBitMask.getIpv4DestinationAddressNoMask().getValue());\r
+ }\r
+\r
/**\r
* 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)}\r
*/\r