diff --git a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java index 1c1dee78cd..95c3be3ff0 100644 --- a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java +++ b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java @@ -16,10 +16,16 @@ package org.onosproject.drivers.lisp.extensions; +import com.google.common.collect.Maps; import org.onosproject.mapping.addresses.ExtensionMappingAddress; import org.onosproject.mapping.addresses.ExtensionMappingAddressType; +import org.onosproject.mapping.addresses.MappingAddress; import org.onosproject.net.flow.AbstractExtension; +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; import static org.onosproject.mapping.addresses.ExtensionMappingAddressType .ExtensionMappingAddressTypes.SOURCE_DEST_ADDRESS; @@ -31,6 +37,75 @@ import static org.onosproject.mapping.addresses.ExtensionMappingAddressType */ public class LispSrcDstAddress extends AbstractExtension implements ExtensionMappingAddress { + + private static final String SRC_MASK_LENGTH = "srcMaskLength"; + private static final String DST_MASK_LENGTH = "dstMaskLength"; + private static final String SRC_PREFIX = "srcPrefix"; + private static final String DST_PREFIX = "dstPrefix"; + + private byte srcMaskLength; + private byte dstMaskLength; + private MappingAddress srcPrefix; + private MappingAddress dstPrefix; + + /** + * Default constructor. + */ + public LispSrcDstAddress() { + } + + /** + * Creates an instance with initialized parameters. + * + * @param srcMaskLength source mask length + * @param dstMaskLength destination mask length + * @param srcPrefix source address prefix + * @param dstPrefix destination address prefix + */ + private LispSrcDstAddress(byte srcMaskLength, byte dstMaskLength, + MappingAddress srcPrefix, MappingAddress dstPrefix) { + this.srcMaskLength = srcMaskLength; + this.dstMaskLength = dstMaskLength; + this.srcPrefix = srcPrefix; + this.dstPrefix = dstPrefix; + } + + /** + * Obtains source mask length. + * + * @return source mask length + */ + public byte getSrcMaskLength() { + return srcMaskLength; + } + + /** + * Obtains destination mask length. + * + * @return destination mask length + */ + public byte getDstMaskLength() { + return dstMaskLength; + } + + /** + * Obtains source address prefix. + * + * @return source address prefix + */ + public MappingAddress getSrcPrefix() { + return srcPrefix; + } + + /** + * Obtains destination address prefix. + * + * @return destination address prefix + */ + public MappingAddress getDstPrefix() { + return dstPrefix; + } + @Override public ExtensionMappingAddressType type() { return SOURCE_DEST_ADDRESS.type(); @@ -38,11 +113,119 @@ public class LispSrcDstAddress extends AbstractExtension @Override public byte[] serialize() { - return new byte[0]; + Map parameterMap = Maps.newHashMap(); + + parameterMap.put(SRC_MASK_LENGTH, srcMaskLength); + parameterMap.put(DST_MASK_LENGTH, dstMaskLength); + parameterMap.put(SRC_PREFIX, srcPrefix); + parameterMap.put(DST_PREFIX, dstPrefix); + + return APP_KRYO.serialize(parameterMap); } @Override public void deserialize(byte[] data) { + Map parameterMap = APP_KRYO.deserialize(data); + this.srcMaskLength = (byte) parameterMap.get(SRC_MASK_LENGTH); + this.dstMaskLength = (byte) parameterMap.get(DST_MASK_LENGTH); + this.srcPrefix = (MappingAddress) parameterMap.get(SRC_PREFIX); + this.dstPrefix = (MappingAddress) parameterMap.get(DST_PREFIX); + } + + @Override + public int hashCode() { + return Objects.hash(srcPrefix, dstPrefix, srcMaskLength, dstMaskLength); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof LispSrcDstAddress) { + final LispSrcDstAddress other = (LispSrcDstAddress) obj; + return Objects.equals(this.srcPrefix, other.srcPrefix) && + Objects.equals(this.dstPrefix, other.dstPrefix) && + Objects.equals(this.srcMaskLength, other.srcMaskLength) && + Objects.equals(this.dstMaskLength, other.dstMaskLength); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("source prefix", srcPrefix) + .add("destination prefix", dstPrefix) + .add("source mask length", srcMaskLength) + .add("destination mask length", dstMaskLength) + .toString(); + } + + /** + * A builder for building LispSrcDstAddress. + */ + public static final class Builder { + private byte srcMaskLength; + private byte dstMaskLength; + private MappingAddress srcPrefix; + private MappingAddress dstPrefix; + + /** + * Sets source address prefix. + * + * @param srcPrefix source prefix + * @return Builder object + */ + public Builder withSrcPrefix(MappingAddress srcPrefix) { + this.srcPrefix = srcPrefix; + return this; + } + + /** + * Sets destination address prefix. + * + * @param dstPrefix destination prefix + * @return Builder object + */ + public Builder withDstPrefix(MappingAddress dstPrefix) { + this.dstPrefix = dstPrefix; + return this; + } + + /** + * Sets source mask length. + * + * @param srcMaskLength source mask length + * @return Builder object + */ + public Builder withSrcMaskLength(byte srcMaskLength) { + this.srcMaskLength = srcMaskLength; + return this; + } + + /** + * Sets destination mask length. + * + * @param dstMaskLength destination mask length + * @return Builder object + */ + public Builder withDstMaskLength(byte dstMaskLength) { + this.dstMaskLength = dstMaskLength; + return this; + } + + /** + * Builds LispSrcDstAddress instance. + * + * @return LispSrcDstAddress instance + */ + public LispSrcDstAddress build() { + + return new LispSrcDstAddress(srcMaskLength, dstMaskLength, + srcPrefix, dstPrefix); + } } } diff --git a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java index 4415d30efd..c569e61d10 100644 --- a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java +++ b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java @@ -16,10 +16,24 @@ package org.onosproject.drivers.lisp.extensions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; +import org.onlab.util.KryoNamespace; +import org.onosproject.mapping.addresses.ASMappingAddress; +import org.onosproject.mapping.addresses.DNMappingAddress; +import org.onosproject.mapping.addresses.EthMappingAddress; import org.onosproject.mapping.addresses.ExtensionMappingAddress; import org.onosproject.mapping.addresses.ExtensionMappingAddressType; +import org.onosproject.mapping.addresses.IPMappingAddress; +import org.onosproject.mapping.addresses.MappingAddress; import org.onosproject.net.flow.AbstractExtension; +import org.onosproject.store.serializers.KryoNamespaces; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static com.google.common.base.MoreObjects.toStringHelper; import static org.onosproject.mapping.addresses.ExtensionMappingAddressType .ExtensionMappingAddressTypes.TRAFFIC_ENGINEERING_ADDRESS; @@ -30,6 +44,46 @@ import static org.onosproject.mapping.addresses.ExtensionMappingAddressType */ public final class LispTeAddress extends AbstractExtension implements ExtensionMappingAddress { + + private static final String TE_RECORDS = "records"; + + private List records; + + private KryoNamespace appKryo = new KryoNamespace.Builder() + .register(KryoNamespaces.API) + .register(MappingAddress.class) + .register(MappingAddress.Type.class) + .register(IPMappingAddress.class) + .register(ASMappingAddress.class) + .register(DNMappingAddress.class) + .register(EthMappingAddress.class) + .register(TeRecord.class) + .build(); + + /** + * Default constructor. + */ + public LispTeAddress() { + } + + /** + * Creates an instance with initialized parameters. + * + * @param records a collection of TE records + */ + private LispTeAddress(List records) { + this.records = records; + } + + /** + * Obtains a collection of TE records. + * + * @return a collection of TE records + */ + public List getTeRecords() { + return ImmutableList.copyOf(records); + } + @Override public ExtensionMappingAddressType type() { return TRAFFIC_ENGINEERING_ADDRESS.type(); @@ -37,11 +91,224 @@ public final class LispTeAddress extends AbstractExtension @Override public byte[] serialize() { - return new byte[0]; + Map parameterMap = Maps.newHashMap(); + + parameterMap.put(TE_RECORDS, records); + return appKryo.serialize(parameterMap); } @Override public void deserialize(byte[] data) { + Map parameterMap = appKryo.deserialize(data); + this.records = (List) parameterMap.get(TE_RECORDS); + } + + @Override + public int hashCode() { + return Objects.hash(records); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof LispTeAddress) { + final LispTeAddress other = (LispTeAddress) obj; + return Objects.equals(records, other.records); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("TE records", records).toString(); + } + + /** + * A builder for building LispTeAddress. + */ + public static final class Builder { + private List records; + + /** + * Sets a collection of TE records. + * + * @param records a collection of TE records + * @return Builder object + */ + public Builder withTeRecords(List records) { + this.records = records; + return this; + } + + /** + * Builds LispTeAddress instance. + * + * @return LispTeAddress instance + */ + public LispTeAddress build() { + return new LispTeAddress(records); + } + } + + /** + * Traffic engineering record class. + */ + public static final class TeRecord { + private boolean lookup; + private boolean rlocProbe; + private boolean strict; + private MappingAddress address; + + /** + * + * + * @param lookup lookup bit + * @param rlocProbe rloc probe bit + * @param strict strict bit + * @param address RTR address + */ + private TeRecord(boolean lookup, boolean rlocProbe, boolean strict, + MappingAddress address) { + this.lookup = lookup; + this.rlocProbe = rlocProbe; + this.strict = strict; + this.address = address; + } + + /** + * Obtains lookup bit flag. + * + * @return lookup bit flag + */ + public boolean isLookup() { + return lookup; + } + + /** + * Obtains RLOC probe bit flag. + * + * @return RLOC probe bit flag + */ + public boolean isRlocProbe() { + return rlocProbe; + } + + /** + * Obtains strict bit flag. + * + * @return strict bit flag + */ + public boolean isStrict() { + return strict; + } + + /** + * Obtains Re-encapsulated RLOC address. + * + * @return Re-encapsulated RLOC address + */ + public MappingAddress getAddress() { + return address; + } + + @Override + public int hashCode() { + return Objects.hash(lookup, rlocProbe, strict, address); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof TeRecord) { + final TeRecord other = (TeRecord) obj; + return Objects.equals(this.lookup, other.lookup) && + Objects.equals(this.rlocProbe, other.rlocProbe) && + Objects.equals(this.strict, other.strict) && + Objects.equals(this.address, other.address); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("Lookup bit", lookup) + .add("RLOC probe bit", rlocProbe) + .add("strict bit", strict) + .add("RTR address", address) + .toString(); + } + + /** + * A builder for building TeRecord. + */ + public static final class Builder { + private boolean lookup; + private boolean rlocProbe; + private boolean strict; + private MappingAddress address; + + /** + * Sets lookup flag. + * + * @param lookup lookup flag + * @return Builder object + */ + public Builder withIsLookup(boolean lookup) { + this.lookup = lookup; + return this; + } + + /** + * Sets RLOC probe flag. + * + * @param rlocProbe RLOC probe flag + * @return Builder object + */ + public Builder withIsRlocProbe(boolean rlocProbe) { + this.rlocProbe = rlocProbe; + return this; + } + + /** + * Sets strict flag. + * + * @param strict strict flag + * @return Builder object + */ + public Builder withIsStrict(boolean strict) { + this.strict = strict; + return this; + } + + /** + * Sets RTR RLOC address. + * + * @param address RTR RLOC address + * @return Builder object + */ + public Builder withRtrRlocAddress(MappingAddress address) { + this.address = address; + return this; + } + + /** + * Builds TeRecord instance. + * + * @return TeRcord instance + */ + public TeRecord build() { + + return new TeRecord(lookup, rlocProbe, strict, address); + } + } } } diff --git a/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddressTest.java b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddressTest.java new file mode 100644 index 0000000000..c86c672b6d --- /dev/null +++ b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddressTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2017-present Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.drivers.lisp.extensions; + +import com.google.common.testing.EqualsTester; +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.IpPrefix; +import org.onosproject.mapping.addresses.MappingAddress; +import org.onosproject.mapping.addresses.MappingAddresses; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * Unit tests for LispSrcDstAddress extension class. + */ +public class LispSrcDstAddressTest { + + private static final IpPrefix IP_ADDRESS_1 = IpPrefix.valueOf("1.2.3.4/24"); + private static final IpPrefix IP_ADDRESS_2 = IpPrefix.valueOf("5.6.7.8/24"); + + private static final byte MASK_LENGTH_1 = 0x01; + private static final byte MASK_LENGTH_2 = 0x02; + + private LispSrcDstAddress address1; + private LispSrcDstAddress sameAsAddress1; + private LispSrcDstAddress address2; + + @Before + public void setUp() { + + MappingAddress ma1 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1); + + address1 = new LispSrcDstAddress.Builder() + .withSrcMaskLength(MASK_LENGTH_1) + .withDstMaskLength(MASK_LENGTH_1) + .withSrcPrefix(ma1) + .withDstPrefix(ma1) + .build(); + + sameAsAddress1 = new LispSrcDstAddress.Builder() + .withSrcMaskLength(MASK_LENGTH_1) + .withDstMaskLength(MASK_LENGTH_1) + .withSrcPrefix(ma1) + .withDstPrefix(ma1) + .build(); + + MappingAddress ma2 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_2); + + address2 = new LispSrcDstAddress.Builder() + .withSrcMaskLength(MASK_LENGTH_2) + .withDstMaskLength(MASK_LENGTH_2) + .withSrcPrefix(ma2) + .withDstPrefix(ma2) + .build(); + } + + @Test + public void testEquality() { + new EqualsTester() + .addEqualityGroup(address1, sameAsAddress1) + .addEqualityGroup(address2).testEquals(); + } + + @Test + public void testConstruction() { + LispSrcDstAddress address = address1; + + MappingAddress ma = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1); + + assertThat(address.getSrcMaskLength(), is(MASK_LENGTH_1)); + assertThat(address.getDstMaskLength(), is(MASK_LENGTH_1)); + assertThat(address.getSrcPrefix(), is(ma)); + assertThat(address.getDstPrefix(), is(ma)); + } + + @Test + public void testSerialization() { + LispSrcDstAddress other = new LispSrcDstAddress(); + other.deserialize(address1.serialize()); + + new EqualsTester() + .addEqualityGroup(address1, other) + .testEquals(); + } +} diff --git a/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispTeAddressTest.java b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispTeAddressTest.java new file mode 100644 index 0000000000..afccf87aec --- /dev/null +++ b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispTeAddressTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2017-present Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.drivers.lisp.extensions; + +import com.google.common.collect.ImmutableList; +import com.google.common.testing.EqualsTester; +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.IpPrefix; +import org.onosproject.mapping.addresses.MappingAddress; +import org.onosproject.mapping.addresses.MappingAddresses; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * Unit tests for LispTeAddress extension class. + */ +public class LispTeAddressTest { + + private static final IpPrefix IP_ADDRESS_1 = IpPrefix.valueOf("1.2.3.4/24"); + private static final IpPrefix IP_ADDRESS_2 = IpPrefix.valueOf("5.6.7.8/24"); + + private static final boolean IS_LOOKUP_1 = false; + private static final boolean IS_RLOC_PROBE_1 = true; + private static final boolean IS_STRICT_1 = false; + + private static final boolean IS_LOOKUP_2 = true; + private static final boolean IS_RLOC_PROBE_2 = false; + private static final boolean IS_STRICT_2 = true; + + private LispTeAddress address1; + private LispTeAddress sameAsAddress1; + private LispTeAddress address2; + + @Before + public void setUp() { + + MappingAddress ma1 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1); + MappingAddress ma2 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_2); + + LispTeAddress.TeRecord tr1 = new LispTeAddress.TeRecord.Builder() + .withIsLookup(IS_LOOKUP_1) + .withIsRlocProbe(IS_RLOC_PROBE_1) + .withIsStrict(IS_STRICT_1) + .withRtrRlocAddress(ma1) + .build(); + + LispTeAddress.TeRecord tr2 = new LispTeAddress.TeRecord.Builder() + .withIsLookup(IS_LOOKUP_2) + .withIsRlocProbe(IS_RLOC_PROBE_2) + .withIsStrict(IS_STRICT_2) + .withRtrRlocAddress(ma2) + .build(); + + address1 = new LispTeAddress.Builder() + .withTeRecords(ImmutableList.of(tr1, tr2)) + .build(); + + sameAsAddress1 = new LispTeAddress.Builder() + .withTeRecords(ImmutableList.of(tr1, tr2)) + .build(); + + address2 = new LispTeAddress.Builder() + .withTeRecords(ImmutableList.of(tr2, tr1)) + .build(); + } + + @Test + public void testEquality() { + new EqualsTester() + .addEqualityGroup(address1, sameAsAddress1) + .addEqualityGroup(address2).testEquals(); + } + + @Test + public void testConstruction() { + LispTeAddress address = address1; + + MappingAddress ma = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1); + + assertThat(address.getTeRecords().get(0).isLookup(), is(IS_LOOKUP_1)); + assertThat(address.getTeRecords().get(0).isRlocProbe(), is(IS_RLOC_PROBE_1)); + assertThat(address.getTeRecords().get(0).isStrict(), is(IS_STRICT_1)); + assertThat(address.getTeRecords().get(0).getAddress(), is(ma)); + } + + @Test + public void testSerialization() { + LispTeAddress other = new LispTeAddress(); + other.deserialize(address1.serialize()); + + new EqualsTester() + .addEqualityGroup(address1, other) + .testEquals(); + } +}