diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2022-03-17 22:17:50 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2022-03-17 22:17:50 +0100 |
commit | 9235db7caae11826d3adf614c0a28b0d88951f93 (patch) | |
tree | 5b16c4f8e3019151eb83995d17ae885aa53a6dcb | |
parent | 4f4bd8d7bc49239a4ddbd4e39a523c0cc58c2e9b (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.java | 36 | ||||
-rw-r--r-- | src/main/java/com/lumaserv/bgp/protocol/attribute/MPUnreachableNLRIAttribute.java | 24 |
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 + "}"; } } |