summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2022-03-17 22:17:50 +0100
committerMikael Magnusson <mikma@users.sourceforge.net>2022-03-17 22:17:50 +0100
commit9235db7caae11826d3adf614c0a28b0d88951f93 (patch)
tree5b16c4f8e3019151eb83995d17ae885aa53a6dcb
parent4f4bd8d7bc49239a4ddbd4e39a523c0cc58c2e9b (diff)
Add support for longest prefix match of IPPrefixes
* Implement IPPrefix.hashCode() and equals() for longest prefix match. * Add withdrawnPrefixes to MPUnreachableNLRIAttribute.
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java36
-rw-r--r--src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java24
2 files changed, 57 insertions, 3 deletions
diff --git a/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java b/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java
index 5d38cf6..57cfe90 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/IPPrefix.java
@@ -15,6 +15,42 @@ public class IPPrefix {
byte[] address;
int length;
+ /**
+ * Include length bits from address in hash to allow longest
+ * prefix matches.
+ */
+ public int hashCode() {
+ int hash = length + address.length << 7;
+ final int bytes = (length+7)/8;
+ for (int i = 0; i < bytes; i++) {
+ hash += (int)address[i] << (i % 4) * 8;
+ }
+ return hash;
+ }
+
+ /**
+ * Include length bits from address in comparison to allow longest
+ * prefix matches.
+ */
+ public boolean equals(Object obj) {
+ if (!(obj instanceof IPPrefix))
+ return false;
+
+ IPPrefix other = (IPPrefix)obj;
+
+ if (length != other.length
+ || address.length != other.address.length)
+ return false;
+
+ final int bytes = (length+7)/8;
+ for (int i=0; i < bytes; i++) {
+ if (address[i] != other.address[i])
+ return false;
+ }
+
+ return true;
+ }
+
public String toString() {
try {
return IPAddress.toString(InetAddress.getByAddress(address)) + "/" + length;
diff --git a/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java b/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java
index 32600d9..fdbec22 100644
--- a/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java
+++ b/src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java
@@ -4,9 +4,12 @@ import lombok.Getter;
import lombok.Setter;
import com.lumaserv.bgp.protocol.AFI;
+import com.lumaserv.bgp.protocol.IPPrefix;
import com.lumaserv.bgp.protocol.SAFI;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
@Getter
@Setter
@@ -14,12 +17,27 @@ public class MPUnreachableNLRIAttribute implements PathAttribute {
AFI afi;
SAFI safi;
- int nlriLen;
+ Collection<IPPrefix> withdrawnPrefixes;
public MPUnreachableNLRIAttribute(byte typeCode, byte[] data) {
afi = AFI.fromInteger((data[0] << 8) | data[1]);
safi = SAFI.fromInteger(data[2]);
- nlriLen = data.length - 3;
+ int nlriLen = data.length - 3;
+
+ withdrawnPrefixes = new ArrayList<>();
+
+ int offset = 3;
+ int offsetOffset = offset;
+ while ((offset - offsetOffset) < nlriLen) {
+ IPPrefix prefix = new IPPrefix()
+ .setLength((int)(data[offset]&0xff)) // FIXME IPv4/IPv6 etc
+ .setAddress(new byte[16]);
+ offset++;
+ int addressLen = (int) Math.ceil(prefix.getLength() / 8d);
+ System.arraycopy(data, offset, prefix.getAddress(), 0, addressLen);
+ offset += addressLen;
+ withdrawnPrefixes.add(prefix);
+ }
}
public byte getTypeCode() {
@@ -32,6 +50,6 @@ public class MPUnreachableNLRIAttribute implements PathAttribute {
}
public String toString() {
- return "{AFI:" + afi + " SAFI:" + safi + " NLRIs:" + nlriLen + "}";
+ return "{AFI:" + afi + " SAFI:" + safi + " Withdrawn NLRIs:" + withdrawnPrefixes + "}";
}
}