Changes to Prefix to support new PATRICIA Trie
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 9936cb7..f4ff6b1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -450,7 +450,7 @@
} catch (NumberFormatException e) {
log.warn("Wrong mask format in RIB JSON: {}", mask1);
continue;
- } catch (UnknownHostException e1) {
+ } catch (IllegalArgumentException e1) {
log.warn("Wrong prefix format in RIB JSON: {}", prefix1);
continue;
}
@@ -525,7 +525,7 @@
Prefix prefix = null;
try {
prefix = new Prefix(node.key, node.rib.masklen);
- } catch (UnknownHostException e) {
+ } catch (IllegalArgumentException e) {
log.error(" ", e);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
index 19b44c8..39a14cd 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
@@ -121,7 +121,7 @@
reply = "[POST: mask format is wrong]";
log.info(reply);
return reply + "\n";
- } catch (UnknownHostException e1) {
+ } catch (IllegalArgumentException e1) {
reply = "[POST: prefix format is wrong]";
log.info(reply);
return reply + "\n";
@@ -184,7 +184,7 @@
reply = "[DELE: mask format is wrong]";
log.info(reply);
return reply + "\n";
- } catch (UnknownHostException e1) {
+ } catch (IllegalArgumentException e1) {
reply = "[DELE: prefix format is wrong]";
log.info(reply);
return reply + "\n";
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
index 54775df..c40214b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Prefix.java
@@ -2,30 +2,89 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.Arrays;
public class Prefix {
- private int prefixLength;
- private InetAddress address;
+ private final int MAX_BYTES = 4;
+
+ private final int prefixLength;
+ private final byte[] address;
+
+ //For verifying the arguments and pretty printing
+ private final InetAddress inetAddress;
+
+ public Prefix(byte[] addr, int prefixLength) {
+ if (addr == null || addr.length != MAX_BYTES ||
+ prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+ throw new IllegalArgumentException();
+ }
- public Prefix(byte[] addr, int prefixLength) throws UnknownHostException {
- //try {
- address = InetAddress.getByAddress(addr);
- //} catch (UnknownHostException e) {
- // System.out.println("InetAddress exception");
- // return;
- //}
+ address = canonicalizeAddress(addr, prefixLength);
this.prefixLength = prefixLength;
- //System.out.println(address.toString() + "/" + prefixLength);
+
+ try {
+ inetAddress = InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException();
+ }
}
- public Prefix(String str, int prefixLength) throws UnknownHostException {
- //try {
- address = InetAddress.getByName(str);
- //} catch (UnknownHostException e) {
- // System.out.println("InetAddress exception");
- // return;
- //}
+ public Prefix(String strAddress, int prefixLength) {
+ byte[] addr = null;
+ try {
+ addr = InetAddress.getByName(strAddress).getAddress();
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException("Invalid IP inetAddress argument");
+ }
+
+ if (addr == null || addr.length != MAX_BYTES ||
+ prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+ throw new IllegalArgumentException();
+ }
+
+ address = canonicalizeAddress(addr, prefixLength);
this.prefixLength = prefixLength;
+
+ try {
+ inetAddress = InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
+ byte[] result = new byte[address.length];
+
+ if (prefixLength == 0) {
+ for (int i = 0; i < MAX_BYTES; i++) {
+ result[i] = 0;
+ }
+
+ return result;
+ }
+
+ result = Arrays.copyOf(address, address.length);
+
+ //Set all bytes after the end of the prefix to 0
+ int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
+ for (int i = lastByteIndex; i < MAX_BYTES; i++) {
+ result[i] = 0;
+ }
+
+ byte lastByte = address[lastByteIndex];
+ byte mask = 0;
+ byte lsb = 1;
+ int lastBit = (prefixLength - 1) % Byte.SIZE;
+ for (int i = 0; i < Byte.SIZE; i++) {
+ if (i <= lastBit + 1) {
+ mask |= lsb;
+ }
+ mask <<= 1;
+ }
+
+ result[lastByteIndex] = (byte) (lastByte & mask);
+
+ return result;
}
public int getPrefixLength() {
@@ -33,7 +92,7 @@
}
public byte[] getAddress() {
- return address.getAddress();
+ return address;
}
@Override
@@ -44,7 +103,7 @@
Prefix otherPrefix = (Prefix) other;
- return (address.equals(otherPrefix.address)) &&
+ return (Arrays.equals(address, otherPrefix.address)) &&
(prefixLength == otherPrefix.prefixLength);
}
@@ -52,12 +111,28 @@
public int hashCode() {
int hash = 17;
hash = 31 * hash + prefixLength;
- hash = 31 * hash + (address == null ? 0 : address.hashCode());
+ hash = 31 * hash + Arrays.hashCode(address);
return hash;
}
@Override
public String toString() {
- return address.getHostAddress() + "/" + prefixLength;
+ return inetAddress.getHostAddress() + "/" + prefixLength;
+ }
+
+ public String printAsBits() {
+ String result = "";
+ for (int i = 0; i < address.length; i++) {
+ byte b = address[i];
+ for (int j = 0; j < Byte.SIZE; j++) {
+ byte mask = (byte) (0x80 >>> j);
+ result += ((b & mask) == 0)? "0" : "1";
+ if (i*Byte.SIZE+j == prefixLength-1) {
+ return result;
+ }
+ }
+ result += " ";
+ }
+ return result.substring(0, result.length() - 1);
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index f56934d..8ef388a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -38,6 +38,7 @@
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
+//TODO have L2 and also L3 mode, where it takes into account interface addresses
public class ProxyArpManager implements IProxyArpService, IOFMessageListener {
private static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
@@ -79,7 +80,7 @@
return retry;
}
- public synchronized void dispatchReply(InetAddress ipAddress, byte[] replyMacAddress) {
+ public void dispatchReply(InetAddress ipAddress, byte[] replyMacAddress) {
log.debug("Dispatching reply for {} to {}", ipAddress.getHostAddress(),
requester);
requester.arpResponse(ipAddress, replyMacAddress);