fixing loxi output
upgrade to 0.3.8
agrregate pom for of-lib
Change-Id: Ie75d75b708c30934bbca235e68c50de656d84ad4
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java b/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
index f103230..78e6075 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchField.java
@@ -232,6 +232,9 @@
public final static MatchField<U16> BSN_TCP_FLAGS =
new MatchField<U16>("bsn_tcp_flags", MatchFields.BSN_TCP_FLAGS);
+ public final static MatchField<ClassId> BSN_VLAN_XLATE_PORT_GROUP_ID =
+ new MatchField<ClassId>("bsn_vlan_xlate_port_group_id", MatchFields.BSN_VLAN_XLATE_PORT_GROUP_ID);
+
public String getName() {
return name;
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java b/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
index 354a528..863634e 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/protocol/match/MatchFields.java
@@ -56,4 +56,5 @@
BSN_UDF6,
BSN_UDF7,
BSN_TCP_FLAGS,
+ BSN_VLAN_XLATE_PORT_GROUP_ID,
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/HashValue.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
index 1dd55d5..3030e3e 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
@@ -17,6 +17,23 @@
*/
int prefixBits(int numBits);
+ /** perform an arithmetic addition of this value and other. Wraps around on
+ * overflow of the defined word size.
+ *
+ * @param other
+ * @return this + other
+ */
+ H add(H other);
+
+ /**
+ * arithmetically substract the given 'other' value from this value.
+ * around on overflow.
+ *
+ * @param other
+ * @return this - other
+ */
+ H subtract(H other);
+
/** @return the bitwise inverse of this value */
H inverse();
@@ -29,26 +46,57 @@
/** xor this value with another value value of the same type */
H xor(H other);
- /** calculate a combined hash value of this hash value (the <b>Key</b>) and the hash value
- * specified as a parameter (the <b>Value</b>).
- * <p>
- * The value is constructed as follows:
- * <ul>
- * <li>the first keyBits bits are taken only from the Key
- * <li>the other bits are taken from key xor value.
- * </ul>
- * The overall result looks like this:
- * <pre>
- * MSB LSB
- * +---------+--------------+
- * | key | key ^ value |
- * +---------+--------------+
- * |-keyBits-|
- * </pre>
+ /** create and return a builder */
+ Builder<H> builder();
+
+ /** a mutator for HashValues. Allows perfomring a series of
+ * operations on a hashv value without the associated cost of object
+ * reallocation.
*
- * @param value - hash value to be compared with this value (the key)
- * @param keyBits number of prefix bits that are just taken from key
- * @return the combined value.
+ * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
+ *
+ * @param <H> - the hashvalue
*/
- H combineWithValue(H value, int keyBits);
+ public interface Builder<H> {
+ /** perform an arithmetic addition of this value and other. Wraps around on
+ * overflow of the defined word size.
+ *
+ * @param other
+ * @return this mutator
+ */
+ Builder<H> add(H other);
+
+ /**
+ * arithmetically substract the given 'other' value from the value stored in this mutator.
+ * around on overflow.
+ *
+ * @param other
+ * @return this mutator
+ */
+ Builder<H> subtract(H other);
+
+ /** bitwise invert the value stored in this mutator
+ *
+ * @return this mutator
+ */
+ Builder<H> invert();
+
+ /** or the value stored in this mutator with another value value of the same type
+ * @return this mutator
+ */
+ Builder<H> or(H other);
+
+ /** and the value stored in this mutator with another value value of the same type
+ * @return this mutator
+ */
+ Builder<H> and(H other);
+
+ /** xor the value stored in this mutator with another value value of the same type
+ * @return this mutator
+ */
+ Builder<H> xor(H other);
+
+ /** @return the hash value */
+ public H build();
+ }
}
\ No newline at end of file
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
index 5e4e818..cee9ad1 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
@@ -10,6 +10,11 @@
public abstract class IPAddress<F extends IPAddress<F>> implements OFValueType<F> {
+ /**
+ * Returns the Internet Protocol (IP) version of this object
+ *
+ * @return the Internet Protocol (IP) version of this object
+ */
public abstract IPVersion getIpVersion();
/**
@@ -55,6 +60,52 @@
*/
public abstract F not();
+ /**
+ * Returns an {@code IPAddressWithMask<F>} object that represents this
+ * IP address masked by the given IP address mask.
+ *
+ * @param mask the {@code F} object that represents the mask
+ * @return an {@code IPAddressWithMask<F>} object that represents this
+ * IP address masked by the given mask
+ * @throws NullPointerException if the given mask was {@code null}
+ */
+ @Nonnull
+ public abstract IPAddressWithMask<F> withMask(@Nonnull final F mask);
+
+ /**
+ * Returns an {@code IPAddressWithMask<F>} object that represents this
+ * IP address masked by the CIDR subnet mask of the given prefix length.
+ *
+ * @param cidrMaskLength the prefix length of the CIDR subnet mask
+ * (i.e. the number of leading one-bits),
+ * where <code>
+ * 0 <= cidrMaskLength <= (F.getLength() * 8)
+ * </code>
+ * @return an {@code IPAddressWithMask<F>} object that
+ * represents this IP address masked by the CIDR
+ * subnet mask of the given prefix length
+ * @throws IllegalArgumentException if the given prefix length was invalid
+ * @see #ofCidrMaskLength(int)
+ */
+ @Nonnull
+ public abstract IPAddressWithMask<F> withMaskOfLength(
+ final int cidrMaskLength);
+
+ /**
+ * Returns the raw IP address of this {@code IPAddress} object. The result
+ * is in network byte order: the highest order byte of the address is in
+ * {@code getBytes()[0]}.
+ * <p>
+ * Similar to {@link InetAddress#getAddress()}
+ *
+ * @return the raw IP address of this object
+ * @see InetAddress#getAddress()
+ */
+ public abstract byte[] getBytes();
+
+ @Override
+ public abstract String toString();
+
@Override
public abstract boolean equals(Object other);
@@ -88,14 +139,26 @@
* @throws NullPointerException if address is null
*/
@Nonnull
- public static IPAddress<?> fromInetAddress(@Nonnull InetAddress address) {
+ public static IPAddress<?> of(@Nonnull InetAddress address) {
Preconditions.checkNotNull(address, "address must not be null");
- byte [] bytes = address.getAddress();
if(address instanceof Inet4Address)
- return IPv4Address.of(bytes);
+ return IPv4Address.of((Inet4Address) address);
else if (address instanceof Inet6Address)
- return IPv6Address.of(bytes);
+ return IPv6Address.of((Inet6Address) address);
else
return IPAddress.of(address.getHostAddress());
}
+
+ /**
+ * Factory function for InetAddress values.
+ * @param address the InetAddress you wish to parse into an IPAddress object.
+ * @return the IPAddress object.
+ * @throws NullPointerException if address is null
+ * @deprecated replaced by {@link #of(InetAddress)}
+ */
+ @Deprecated
+ @Nonnull
+ public static IPAddress<?> fromInetAddress(@Nonnull InetAddress address) {
+ return of(address);
+ }
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
index ba7eb93..7cd8099 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
@@ -1,5 +1,7 @@
package org.projectfloodlight.openflow.types;
+import com.google.common.base.Preconditions;
+
public abstract class IPAddressWithMask<F extends IPAddress<F>> extends Masked<F> {
@@ -8,6 +10,8 @@
}
public abstract IPVersion getIpVersion();
+
+ public abstract boolean contains(IPAddress<?> ip);
public F getSubnetBroadcastAddress() {
if (!mask.isCidrMask()) {
@@ -22,9 +26,8 @@
}
public static IPAddressWithMask<?> of(String ip) {
- if (ip == null) {
- throw new NullPointerException("String ip must not be null");
- }
+ Preconditions.checkNotNull(ip, "string ip must not be null");
+
if (ip.indexOf('.') != -1)
return IPv4AddressWithMask.of(ip);
else if (ip.indexOf(':') != -1)
@@ -49,5 +52,4 @@
return res.toString();
}
-
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
index 865fb79..3a1b15e 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
@@ -1,11 +1,14 @@
package org.projectfloodlight.openflow.types;
+import java.net.Inet4Address;
+import java.net.InetAddress;
import java.util.Arrays;
import javax.annotation.Nonnull;
import org.jboss.netty.buffer.ChannelBuffer;
+import com.google.common.base.Preconditions;
import com.google.common.hash.PrimitiveSink;
import com.google.common.primitives.UnsignedInts;
@@ -78,19 +81,17 @@
@Override
public IPv4Address and(IPv4Address other) {
- if (other == null) {
- throw new NullPointerException("Other IP Address must not be null");
- }
- IPv4Address otherIp = (IPv4Address) other;
+ Preconditions.checkNotNull(other, "other must not be null");
+
+ IPv4Address otherIp = other;
return IPv4Address.of(rawValue & otherIp.rawValue);
}
@Override
public IPv4Address or(IPv4Address other) {
- if (other == null) {
- throw new NullPointerException("Other IP Address must not be null");
- }
- IPv4Address otherIp = (IPv4Address) other;
+ Preconditions.checkNotNull(other, "other must not be null");
+
+ IPv4Address otherIp = other;
return IPv4Address.of(rawValue | otherIp.rawValue);
}
@@ -99,13 +100,30 @@
return IPv4Address.of(~rawValue);
}
- public static IPv4Address of(final byte[] address) {
- if (address == null) {
- throw new NullPointerException("Address must not be null");
- }
+ /**
+ * Returns an {@code IPv4Address} object that represents the given
+ * IP address. The argument is in network byte order: the highest
+ * order byte of the address is in {@code address[0]}.
+ * <p>
+ * The address byte array must be 4 bytes long (32 bits long).
+ * <p>
+ * Similar to {@link InetAddress#getByAddress(byte[])}.
+ *
+ * @param address the raw IP address in network byte order
+ * @return an {@code IPv4Address} object that represents the given
+ * raw IP address
+ * @throws NullPointerException if the given address was {@code null}
+ * @throws IllegalArgumentException if the given address was of an invalid
+ * byte array length
+ * @see InetAddress#getByAddress(byte[])
+ */
+ @Nonnull
+ public static IPv4Address of(@Nonnull final byte[] address) {
+ Preconditions.checkNotNull(address, "address must not be null");
+
if (address.length != LENGTH) {
throw new IllegalArgumentException(
- "Invalid byte array length for IPv4Address address: " + address.length);
+ "Invalid byte array length for IPv4 address: " + address.length);
}
int raw =
@@ -114,30 +132,37 @@
return IPv4Address.of(raw);
}
- /** construct an IPv4Address from a 32-bit integer value.
+ /**
+ * Returns an {@code IPv4Address} object that represents the given
+ * IP address.
*
- * @param raw the IPAdress represented as a 32-bit integer
- * @return the constructed IPv4Address
+ * @param raw the raw IP address represented as a 32-bit integer
+ * @return an {@code IPv4Address} object that represents the given
+ * raw IP address
*/
+ @Nonnull
public static IPv4Address of(final int raw) {
if(raw == NONE_VAL)
return NONE;
return new IPv4Address(raw);
}
- /** parse an IPv4Address from the canonical dotted-quad representation
- * (1.2.3.4).
+ /**
+ * Returns an {@code IPv4Address} object that represents the given
+ * IP address. The argument is in the canonical quad-dotted notation.
+ * For example, {@code 1.2.3.4}.
*
- * @param string an IPv4 address in dotted-quad representation
- * @return the parsed IPv4 address
- * @throws NullPointerException if string is null
- * @throws IllegalArgumentException if string is not a valid IPv4Address
+ * @param string the IP address in the canonical quad-dotted notation
+ * @return an {@code IPv4Address} object that represents the given
+ * IP address
+ * @throws NullPointerException if the given string was {@code null}
+ * @throws IllegalArgumentException if the given string was not a valid
+ * IPv4 address
*/
@Nonnull
public static IPv4Address of(@Nonnull final String string) throws IllegalArgumentException {
- if (string == null) {
- throw new NullPointerException("String must not be null");
- }
+ Preconditions.checkNotNull(string, "string must not be null");
+
int start = 0;
int shift = 24;
@@ -161,12 +186,90 @@
return IPv4Address.of(raw);
}
+ /**
+ * Returns an {@code IPv4Address} object that represents the given
+ * IP address. The argument is given as an {@code Inet4Address} object.
+ *
+ * @param address the IP address as an {@code Inet4Address} object
+ * @return an {@code IPv4Address} object that represents the
+ * given IP address
+ * @throws NullPointerException if the given {@code Inet4Address} was
+ * {@code null}
+ */
+ @Nonnull
+ public static IPv4Address of(@Nonnull final Inet4Address address) {
+ Preconditions.checkNotNull(address, "address must not be null");
+ return IPv4Address.of(address.getAddress());
+ }
+
+ /**
+ * Returns an {@code IPv4Address} object that represents the
+ * CIDR subnet mask of the given prefix length.
+ *
+ * @param cidrMaskLength the prefix length of the CIDR subnet mask
+ * (i.e. the number of leading one-bits),
+ * where {@code 0 <= cidrMaskLength <= 32}
+ * @return an {@code IPv4Address} object that represents the
+ * CIDR subnet mask of the given prefix length
+ * @throws IllegalArgumentException if the given prefix length was invalid
+ */
+ @Nonnull
+ public static IPv4Address ofCidrMaskLength(final int cidrMaskLength) {
+ Preconditions.checkArgument(
+ cidrMaskLength >= 0 && cidrMaskLength <= 32,
+ "Invalid IPv4 CIDR mask length: %s", cidrMaskLength);
+
+ if (cidrMaskLength == 32) {
+ return IPv4Address.NO_MASK;
+ } else if (cidrMaskLength == 0) {
+ return IPv4Address.FULL_MASK;
+ } else {
+ int mask = (-1) << (32 - cidrMaskLength);
+ return IPv4Address.of(mask);
+ }
+ }
+
+ /**
+ * Returns an {@code IPv4AddressWithMask} object that represents this
+ * IP address masked by the given IP address mask.
+ *
+ * @param mask the {@code IPv4Address} object that represents the mask
+ * @return an {@code IPv4AddressWithMask} object that represents this
+ * IP address masked by the given mask
+ * @throws NullPointerException if the given mask was {@code null}
+ */
+ @Nonnull
+ @Override
+ public IPv4AddressWithMask withMask(@Nonnull final IPv4Address mask) {
+ return IPv4AddressWithMask.of(this, mask);
+ }
+
+ /**
+ * Returns an {@code IPv4AddressWithMask} object that represents this
+ * IP address masked by the CIDR subnet mask of the given prefix length.
+ *
+ * @param cidrMaskLength the prefix length of the CIDR subnet mask
+ * (i.e. the number of leading one-bits),
+ * where {@code 0 <= cidrMaskLength <= 32}
+ * @return an {@code IPv4AddressWithMask} object that
+ * represents this IP address masked by the CIDR
+ * subnet mask of the given prefix length
+ * @throws IllegalArgumentException if the given prefix length was invalid
+ * @see #ofCidrMaskLength(int)
+ */
+ @Nonnull
+ @Override
+ public IPv4AddressWithMask withMaskOfLength(final int cidrMaskLength) {
+ return this.withMask(IPv4Address.ofCidrMaskLength(cidrMaskLength));
+ }
+
public int getInt() {
return rawValue;
}
private volatile byte[] bytesCache = null;
+ @Override
public byte[] getBytes() {
if (bytesCache == null) {
synchronized (this) {
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
index 9b60c6a..b6dc1b9 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv4AddressWithMask.java
@@ -1,5 +1,9 @@
package org.projectfloodlight.openflow.types;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Preconditions;
+
public class IPv4AddressWithMask extends IPAddressWithMask<IPv4Address> {
public final static IPv4AddressWithMask NONE = of(IPv4Address.NONE, IPv4Address.NONE);
@@ -17,27 +21,77 @@
return IPVersion.IPv4;
}
- public static IPv4AddressWithMask of(int rawValue, int rawMask) {
+ /**
+ * Returns an {@code IPv4AddressWithMask} object that represents the given
+ * raw IP address masked by the given raw IP address mask.
+ *
+ * @param rawValue the raw IP address to be masked
+ * @param rawMask the raw IP address mask
+ * @return an {@code IPv4AddressWithMask} object that represents
+ * the given raw IP address masked by the given raw IP
+ * address mask
+ * @deprecated replaced by {@link IPv4Address#of(int)} and
+ * {@link IPv4Address#withMask(IPv4Address), e.g. <code>
+ * IPv4Address.of(int).withMask(IPv4Address.of(int))
+ * </code>
+ */
+ @Nonnull
+ @Deprecated
+ public static IPv4AddressWithMask of(final int rawValue, final int rawMask) {
return new IPv4AddressWithMask(rawValue, rawMask);
}
- public static IPv4AddressWithMask of(IPv4Address value, IPv4Address mask) {
- if (value == null) {
- throw new NullPointerException("Value must not be null");
- }
- if (mask == null) {
- throw new NullPointerException("Mask must not be null");
- }
+ /**
+ * Returns an {@code IPv4AddressWithMask} object that represents the given
+ * IP address masked by the given IP address mask. Both arguments are given
+ * as {@code IPv4Address} objects.
+ *
+ * @param value the IP address to be masked
+ * @param mask the IP address mask
+ * @return an {@code IPv4AddressWithMask} object that represents
+ * the given IP address masked by the given IP address mask
+ * @throws NullPointerException if any of the given {@code IPv4Address}
+ * objects were {@code null}
+ */
+ @Nonnull
+ public static IPv4AddressWithMask of(
+ @Nonnull final IPv4Address value,
+ @Nonnull final IPv4Address mask) {
+ Preconditions.checkNotNull(value, "value must not be null");
+ Preconditions.checkNotNull(mask, "mask must not be null");
+
return new IPv4AddressWithMask(value, mask);
}
- public static IPv4AddressWithMask of(final String string) {
- if (string == null) {
- throw new NullPointerException("String must not be null");
- }
+ /**
+ * Returns an {@code IPv4AddressWithMask} object that corresponds to
+ * the given string in CIDR notation or other acceptable notations.
+ * <p>
+ * The following notations are accepted.
+ * <table><tr>
+ * <th>Notation</th><th>Example</th><th>Notes</th>
+ * </tr><tr>
+ * <td>IPv4 address only</td><td>{@code 1.2.3.4}</td><td>The subnet mask of
+ * prefix length 32 (i.e. {@code 255.255.255.255}) is assumed.</td>
+ * </tr><tr>
+ * <td>IPv4 address/mask</td><td>{@code 1.2.3.4/255.255.255.0}</td>
+ * </tr><tr>
+ * <td>CIDR notation</td><td>{@code 1.2.3.4/24}</td>
+ * </tr></table>
+ *
+ * @param string the string in acceptable notations
+ * @return an {@code IPv4AddressWithMask} object that corresponds to
+ * the given string in acceptable notations
+ * @throws NullPointerException if the given string was {@code null}
+ * @throws IllegalArgumentException if the given string was malformed
+ */
+ @Nonnull
+ public static IPv4AddressWithMask of(@Nonnull final String string) {
+ Preconditions.checkNotNull(string, "string must not be null");
+
int slashPos;
String ip = string;
- int maskBits = 32;
+ int cidrMaskLength = 32;
IPv4Address maskAddress = null;
// Read mask suffix
@@ -52,14 +106,11 @@
maskAddress = IPv4Address.of(suffix);
} else {
// CIDR Suffix
- maskBits = Integer.parseInt(suffix);
+ cidrMaskLength = Integer.parseInt(suffix);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("IP Address not well formed: " + string);
}
- if (maskBits < 0 || maskBits > 32) {
- throw new IllegalArgumentException("IP Address not well formed: " + string);
- }
}
// Read IP
@@ -68,17 +119,21 @@
if (maskAddress != null) {
// Full address mask
return IPv4AddressWithMask.of(ipv4, maskAddress);
- } else if (maskBits == 32) {
- // No mask
- return IPv4AddressWithMask.of(ipv4, IPv4Address.NO_MASK);
- } else if (maskBits == 0) {
- // No mask
- return IPv4AddressWithMask.of(ipv4, IPv4Address.FULL_MASK);
} else {
- // With mask
- int mask = (-1) << (32 - maskBits);
- return IPv4AddressWithMask.of(ipv4, IPv4Address.of(mask));
+ return IPv4AddressWithMask.of(
+ ipv4, IPv4Address.ofCidrMaskLength(cidrMaskLength));
}
}
+ @Override
+ public boolean contains(IPAddress<?> ip) {
+ Preconditions.checkNotNull(ip, "ip must not be null");
+
+ if(ip.getIpVersion() == IPVersion.IPv4) {
+ IPv4Address ipv4 = (IPv4Address) ip;
+ return this.matches(ipv4);
+ }
+
+ return false;
+ }
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
index 83fb31a..471d0fb 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
@@ -1,5 +1,7 @@
package org.projectfloodlight.openflow.types;
+import java.net.Inet6Address;
+import java.net.InetAddress;
import java.util.Arrays;
import java.util.regex.Pattern;
@@ -8,6 +10,7 @@
import org.jboss.netty.buffer.ChannelBuffer;
import org.projectfloodlight.openflow.exceptions.OFParseError;
+import com.google.common.base.Preconditions;
import com.google.common.hash.PrimitiveSink;
import com.google.common.primitives.Longs;
@@ -102,19 +105,17 @@
@Override
public IPv6Address and(IPv6Address other) {
- if (other == null) {
- throw new NullPointerException("Other IP Address must not be null");
- }
- IPv6Address otherIp = (IPv6Address) other;
+ Preconditions.checkNotNull(other, "other must not be null");
+
+ IPv6Address otherIp = other;
return IPv6Address.of((raw1 & otherIp.raw1), (raw2 & otherIp.raw2));
}
@Override
public IPv6Address or(IPv6Address other) {
- if (other == null) {
- throw new NullPointerException("Other IP Address must not be null");
- }
- IPv6Address otherIp = (IPv6Address) other;
+ Preconditions.checkNotNull(other, "other must not be null");
+
+ IPv6Address otherIp = other;
return IPv6Address.of((raw1 | otherIp.raw1), (raw2 | otherIp.raw2));
}
@@ -123,10 +124,27 @@
return IPv6Address.of(~raw1, ~raw2);
}
- public static IPv6Address of(final byte[] address) {
- if (address == null) {
- throw new NullPointerException("Address must not be null");
- }
+ /**
+ * Returns an {@code IPv6Address} object that represents the given
+ * IP address. The argument is in network byte order: the highest
+ * order byte of the address is in {@code address[0]}.
+ * <p>
+ * The address byte array must be 16 bytes long (128 bits long).
+ * <p>
+ * Similar to {@link InetAddress#getByAddress(byte[])}.
+ *
+ * @param address the raw IP address in network byte order
+ * @return an {@code IPv6Address} object that represents the given
+ * raw IP address
+ * @throws NullPointerException if the given address was {@code null}
+ * @throws IllegalArgumentException if the given address was of an invalid
+ * byte array length
+ * @see InetAddress#getByAddress(byte[])
+ */
+ @Nonnull
+ public static IPv6Address of(@Nonnull final byte[] address) {
+ Preconditions.checkNotNull(address, "address must not be null");
+
if (address.length != LENGTH) {
throw new IllegalArgumentException(
"Invalid byte array length for IPv6 address: " + address.length);
@@ -171,25 +189,30 @@
private final static Pattern colonPattern = Pattern.compile(":");
- /** parse an IPv6Address from its conventional string representation.
- * <p>
- * Expects up to 8 groups of 16-bit hex words seperated by colons
- * (e.g., 2001:db8:85a3:8d3:1319:8a2e:370:7348).
- * <p>
- * Supports zero compression (e.g., 2001:db8::7348).
- * Does <b>not</b> currently support embedding a dotted-quad IPv4 address
- * into the IPv6 address (e.g., 2001:db8::192.168.0.1).
+ /**
+ * Returns an {@code IPv6Address} object that represents the given
+ * IP address. The argument is in the conventional string representation
+ * of IPv6 addresses.
+ * <p>
+ * Expects up to 8 groups of 16-bit hex words seperated by colons
+ * (e.g., 2001:db8:85a3:8d3:1319:8a2e:370:7348).
+ * <p>
+ * Supports zero compression (e.g., 2001:db8::7348).
+ * Does <b>not</b> currently support embedding a dotted-quad IPv4 address
+ * into the IPv6 address (e.g., 2001:db8::192.168.0.1).
*
- * @param string a string representation of an IPv6 address
- * @return the parsed IPv6 address
- * @throws NullPointerException if string is null
- * @throws IllegalArgumentException if string is not a valid IPv6Address
+ * @param string the IP address in the conventional string representation
+ * of IPv6 addresses
+ * @return an {@code IPv6Address} object that represents the given
+ * IP address
+ * @throws NullPointerException if the given string was {@code null}
+ * @throws IllegalArgumentException if the given string was not a valid
+ * IPv6 address
*/
@Nonnull
public static IPv6Address of(@Nonnull final String string) throws IllegalArgumentException {
- if (string == null) {
- throw new NullPointerException("String must not be null");
- }
+ Preconditions.checkNotNull(string, "string must not be null");
+
IPv6Builder builder = new IPv6Builder();
String[] parts = colonPattern.split(string, -1);
@@ -242,19 +265,104 @@
return builder.getIPv6();
}
- /** construct an IPv6 adress from two 64 bit integers representing the first and
- * second 8-byte blocks of the address.
+ /**
+ * Returns an {@code IPv6Address} object that represents the given
+ * IP address. The arguments are the two 64-bit integers representing
+ * the first (higher-order) and second (lower-order) 64-bit blocks
+ * of the IP address.
*
- * @param raw1 - the first 8 byte block of the address
- * @param raw2 - the second 8 byte block of the address
- * @return the constructed IPv6Address
+ * @param raw1 the first (higher-order) 64-bit block of the IP address
+ * @param raw2 the second (lower-order) 64-bit block of the IP address
+ * @return an {@code IPv6Address} object that represents the given
+ * raw IP address
*/
+ @Nonnull
public static IPv6Address of(final long raw1, final long raw2) {
if(raw1==NONE_VAL1 && raw2 == NONE_VAL2)
return NONE;
return new IPv6Address(raw1, raw2);
}
+ /**
+ * Returns an {@code IPv6Address} object that represents the given
+ * IP address. The argument is given as an {@code Inet6Address} object.
+ *
+ * @param address the IP address as an {@code Inet6Address} object
+ * @return an {@code IPv6Address} object that represents the
+ * given IP address
+ * @throws NullPointerException if the given {@code Inet6Address} was
+ * {@code null}
+ */
+ @Nonnull
+ public static IPv6Address of(@Nonnull final Inet6Address address) {
+ Preconditions.checkNotNull(address, "address must not be null");
+ return IPv6Address.of(address.getAddress());
+ }
+
+ /**
+ * Returns an {@code IPv6Address} object that represents the
+ * CIDR subnet mask of the given prefix length.
+ *
+ * @param cidrMaskLength the prefix length of the CIDR subnet mask
+ * (i.e. the number of leading one-bits),
+ * where {@code 0 <= cidrMaskLength <= 128}
+ * @return an {@code IPv6Address} object that represents the
+ * CIDR subnet mask of the given prefix length
+ * @throws IllegalArgumentException if the given prefix length was invalid
+ */
+ @Nonnull
+ public static IPv6Address ofCidrMaskLength(final int cidrMaskLength) {
+ Preconditions.checkArgument(
+ cidrMaskLength >= 0 && cidrMaskLength <= 128,
+ "Invalid IPv6 CIDR mask length: %s", cidrMaskLength);
+
+ if (cidrMaskLength == 128) {
+ return IPv6Address.NO_MASK;
+ } else if (cidrMaskLength == 0) {
+ return IPv6Address.FULL_MASK;
+ } else {
+ int shift1 = Math.min(cidrMaskLength, 64);
+ long raw1 = shift1 == 0 ? 0 : -1L << (64 - shift1);
+ int shift2 = Math.max(cidrMaskLength - 64, 0);
+ long raw2 = shift2 == 0 ? 0 : -1L << (64 - shift2);
+ return IPv6Address.of(raw1, raw2);
+ }
+ }
+
+ /**
+ * Returns an {@code IPv6AddressWithMask} object that represents this
+ * IP address masked by the given IP address mask.
+ *
+ * @param mask the {@code IPv6Address} object that represents the mask
+ * @return an {@code IPv6AddressWithMask} object that represents this
+ * IP address masked by the given mask
+ * @throws NullPointerException if the given mask was {@code null}
+ */
+ @Nonnull
+ @Override
+ public IPv6AddressWithMask withMask(@Nonnull final IPv6Address mask) {
+ return IPv6AddressWithMask.of(this, mask);
+ }
+
+ /**
+ * Returns an {@code IPv6AddressWithMask} object that represents this
+ * IP address masked by the CIDR subnet mask of the given prefix length.
+ *
+ * @param cidrMaskLength the prefix length of the CIDR subnet mask
+ * (i.e. the number of leading one-bits),
+ * where {@code 0 <= cidrMaskLength <= 128}
+ * @return an {@code IPv6AddressWithMask} object that
+ * represents this IP address masked by the CIDR
+ * subnet mask of the given prefix length
+ * @throws IllegalArgumentException if the given prefix length was invalid
+ * @see #ofCidrMaskLength(int)
+ */
+ @Nonnull
+ @Override
+ public IPv6AddressWithMask withMaskOfLength(final int cidrMaskLength) {
+ return this.withMask(IPv6Address.ofCidrMaskLength(cidrMaskLength));
+ }
+
private volatile byte[] bytesCache = null;
public byte[] getBytes() {
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java
index 7259c7f..ee34923 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/IPv6AddressWithMask.java
@@ -1,7 +1,6 @@
package org.projectfloodlight.openflow.types;
-import java.math.BigInteger;
-import java.util.Arrays;
+import com.google.common.base.Preconditions;
public class IPv6AddressWithMask extends IPAddressWithMask<IPv6Address> {
public final static IPv6AddressWithMask NONE = of(IPv6Address.NONE, IPv6Address.NONE);
@@ -16,23 +15,17 @@
}
public static IPv6AddressWithMask of(IPv6Address value, IPv6Address mask) {
- if (value == null) {
- throw new NullPointerException("Value must not be null");
- }
- if (mask == null) {
- throw new NullPointerException("Mask must not be null");
- }
+ Preconditions.checkNotNull(value, "value must not be null");
+ Preconditions.checkNotNull(mask, "mask must not be null");
return new IPv6AddressWithMask(value, mask);
}
-
public static IPv6AddressWithMask of(final String string) {
- if (string == null) {
- throw new NullPointerException("String must not be null");
- }
+ Preconditions.checkNotNull(string, "string must not be null");
+
int slashPos;
String ip = string;
- int maskBits = 128;
+ int cidrMaskLength = 128;
IPv6Address maskAddress = null;
// Read mask suffix
@@ -47,14 +40,11 @@
maskAddress = IPv6Address.of(suffix);
} else {
// CIDR Suffix
- maskBits = Integer.parseInt(suffix);
+ cidrMaskLength = Integer.parseInt(suffix);
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("IPv6 Address not well formed: " + string);
}
- if (maskBits < 0 || maskBits > 128) {
- throw new IllegalArgumentException("IPv6 Address not well formed: " + string);
- }
}
// Read IP
@@ -63,30 +53,21 @@
if (maskAddress != null) {
// Full address mask
return IPv6AddressWithMask.of(ipv6, maskAddress);
- } else if (maskBits == 128) {
- // No mask
- return IPv6AddressWithMask.of(ipv6, IPv6Address.NO_MASK);
- } else if (maskBits == 0) {
- // Entirely masked out
- return IPv6AddressWithMask.of(ipv6, IPv6Address.FULL_MASK);
- }else {
- // With mask
- BigInteger mask = BigInteger.ONE.negate().shiftLeft(128 - maskBits);
- byte[] maskBytesTemp = mask.toByteArray();
- byte[] maskBytes;
- if (maskBytesTemp.length < 16) {
- maskBytes = new byte[16];
- System.arraycopy(maskBytesTemp, 0, maskBytes, 16 - maskBytesTemp.length, maskBytesTemp.length);
- Arrays.fill(maskBytes, 0, 16 - maskBytesTemp.length, (byte)(0xFF));
- } else if (maskBytesTemp.length > 16) {
- maskBytes = new byte[16];
- System.arraycopy(maskBytesTemp, 0, maskBytes, 0, maskBytes.length);
- } else {
- maskBytes = maskBytesTemp;
- }
- return IPv6AddressWithMask.of(ipv6, IPv6Address.of(maskBytes));
+ } else {
+ return IPv6AddressWithMask.of(ipv6,
+ IPv6Address.ofCidrMaskLength(cidrMaskLength));
}
}
+ @Override
+ public boolean contains(IPAddress<?> ip) {
+ Preconditions.checkNotNull(ip, "ip must not be null");
+ if(ip.getIpVersion() == IPVersion.IPv6) {
+ IPv6Address ipv6 = (IPv6Address) ip;
+ return this.matches(ipv6);
+ }
+
+ return false;
+ }
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/U128.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/U128.java
index 35ef846..ddf4faa 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/U128.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/U128.java
@@ -123,15 +123,100 @@
}
@Override
+ public U128 add(U128 other) {
+ long newRaw2 = this.raw2 + other.raw2;
+ long newRaw1 = this.raw1 + other.raw1;
+ if(UnsignedLongs.compare(newRaw2, this.raw2) < 0) {
+ // raw2 overflow
+ newRaw1+=1;
+ }
+ return U128.of(newRaw1, newRaw2);
+ }
+
+ @Override
+ public U128 subtract(U128 other) {
+ long newRaw2 = this.raw2 - other.raw2;
+ long newRaw1 = this.raw1 - other.raw1;
+ if(UnsignedLongs.compare(this.raw2, other.raw2) < 0) {
+ newRaw1 -= 1;
+ }
+ return U128.of(newRaw1, newRaw2);
+ }
+ @Override
public int prefixBits(int numBits) {
return HashValueUtils.prefixBits(this.raw1, numBits);
}
@Override
- public U128 combineWithValue(U128 value, int keyBits) {
- return U128.of(
- HashValueUtils.combineWithValue(this.raw1, value.raw1, Math.min(64, keyBits)),
- HashValueUtils.combineWithValue(this.raw2, value.raw2, Math.max(0,keyBits-64))
- );
+ public HashValue.Builder<U128> builder() {
+ return new U128Builder(raw1, raw2);
}
+
+ static class U128Builder implements HashValue.Builder<U128> {
+ private long raw1, raw2;
+
+ public U128Builder(long raw1, long raw2) {
+ this.raw1 = raw1;
+ this.raw2 = raw2;
+ }
+
+ @Override
+ public Builder<U128> add(U128 other) {
+ raw2 += other.raw2;
+ raw1 += other.raw1;
+ if(UnsignedLongs.compare(raw2, other.raw2) < 0) {
+ // raw2 overflow
+ raw1+=1;
+ }
+ return this;
+ }
+
+ @Override
+ public Builder<U128> subtract(
+ U128 other) {
+ if(UnsignedLongs.compare(this.raw2, other.raw2) >= 0) {
+ raw2 -= other.raw2;
+ raw1 -= other.raw1;
+ } else {
+ // raw2 overflow
+ raw2 -= other.raw2;
+ raw1 = this.raw1 - other.raw1 - 1;
+ }
+ return this;
+ }
+
+ @Override
+ public Builder<U128> invert() {
+ raw1 = ~raw1;
+ raw2 = ~raw2;
+ return this;
+ }
+
+ @Override
+ public Builder<U128> or(U128 other) {
+ raw1 |= other.raw1;
+ raw2 |= other.raw2;
+ return this;
+ }
+
+ @Override
+ public Builder<U128> and(U128 other) {
+ raw1 &= other.raw1;
+ raw2 &= other.raw2;
+ return this;
+ }
+
+ @Override
+ public Builder<U128> xor(U128 other) {
+ raw1 ^= other.raw1;
+ raw2 ^= other.raw2;
+ return this;
+ }
+
+ @Override
+ public U128 build() {
+ return U128.of(raw1, raw2);
+ }
+ }
+
}
diff --git a/of/lib/src/main/java/org/projectfloodlight/openflow/types/U64.java b/of/lib/src/main/java/org/projectfloodlight/openflow/types/U64.java
index 1353b42..f15544f 100644
--- a/of/lib/src/main/java/org/projectfloodlight/openflow/types/U64.java
+++ b/of/lib/src/main/java/org/projectfloodlight/openflow/types/U64.java
@@ -151,6 +151,16 @@
return U64.of(raw ^ other.raw);
}
+ @Override
+ public U64 add(U64 other) {
+ return U64.of(this.raw + other.raw);
+ }
+
+ @Override
+ public U64 subtract(U64 other) {
+ return U64.of(this.raw - other.raw);
+ }
+
/** return the "numBits" highest-order bits of the hash.
* @param numBits number of higest-order bits to return [0-32].
* @return a numberic value of the 0-32 highest-order bits.
@@ -160,11 +170,6 @@
return HashValueUtils.prefixBits(raw, numBits);
}
- @Override
- public U64 combineWithValue(U64 value, int keyBits) {
- return U64.of(HashValueUtils.combineWithValue(this.raw, value.raw, keyBits));
- }
-
public final static Reader READER = new Reader();
private static class Reader implements OFMessageReader<U64> {
@@ -174,5 +179,59 @@
}
}
+ @Override
+ public HashValue.Builder<U64> builder() {
+ return new U64Builder(raw);
+ }
+
+ static class U64Builder implements Builder<U64> {
+ long raw;
+
+ public U64Builder(long raw) {
+ this.raw = raw;
+ }
+
+ @Override
+ public Builder<U64> add(U64 other) {
+ raw += other.raw;
+ return this;
+ }
+
+ @Override
+ public Builder<U64> subtract(
+ U64 other) {
+ raw -= other.raw;
+ return this;
+ }
+
+ @Override
+ public Builder<U64> invert() {
+ raw = ~raw;
+ return this;
+ }
+
+ @Override
+ public Builder<U64> or(U64 other) {
+ raw |= other.raw;
+ return this;
+ }
+
+ @Override
+ public Builder<U64> and(U64 other) {
+ raw &= other.raw;
+ return this;
+ }
+
+ @Override
+ public Builder<U64> xor(U64 other) {
+ raw ^= other.raw;
+ return this;
+ }
+
+ @Override
+ public U64 build() {
+ return U64.of(raw);
+ }
+ }
}