| /* |
| * Copyright 2016-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.lisp.msg.types; |
| |
| import io.netty.buffer.ByteBuf; |
| import org.onlab.util.ByteOperator; |
| import org.onosproject.lisp.msg.exceptions.LispParseError; |
| import org.onosproject.lisp.msg.exceptions.LispReaderException; |
| import org.onosproject.lisp.msg.exceptions.LispWriterException; |
| import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressReader; |
| import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter; |
| |
| import java.util.Objects; |
| |
| import static com.google.common.base.MoreObjects.toStringHelper; |
| |
| /** |
| * Traffic Engineering record class. |
| */ |
| public class LispTeRecord { |
| |
| private final boolean lookup; |
| private final boolean rlocProbe; |
| private final boolean strict; |
| private final LispAfiAddress rtrRlocAddress; |
| |
| /** |
| * Initializes TE record. |
| * |
| * @param lookup lookup bit |
| * @param rlocProbe rloc probe bit |
| * @param strict strict bit |
| * @param rtrAddress RTR address |
| */ |
| public LispTeRecord(boolean lookup, boolean rlocProbe, |
| boolean strict, LispAfiAddress rtrAddress) { |
| this.lookup = lookup; |
| this.rlocProbe = rlocProbe; |
| this.strict = strict; |
| this.rtrRlocAddress = rtrAddress; |
| } |
| |
| /** |
| * 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 LispAfiAddress getRtrRlocAddress() { |
| return rtrRlocAddress; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(lookup, rlocProbe, strict, rtrRlocAddress); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| |
| if (obj instanceof LispTeRecord) { |
| final LispTeRecord other = (LispTeRecord) obj; |
| return Objects.equals(this.lookup, other.lookup) && |
| Objects.equals(this.rlocProbe, other.rlocProbe) && |
| Objects.equals(this.strict, other.strict) && |
| Objects.equals(this.rtrRlocAddress, other.rtrRlocAddress); |
| } |
| 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", rtrRlocAddress) |
| .toString(); |
| } |
| |
| public static final class TeRecordBuilder { |
| private boolean lookup; |
| private boolean rlocProbe; |
| private boolean strict; |
| private LispAfiAddress rtrRlocAddress; |
| |
| /** |
| * Sets lookup flag. |
| * |
| * @param lookup lookup flag |
| * @return TeRecordBuilder object |
| */ |
| public TeRecordBuilder withIsLookup(boolean lookup) { |
| this.lookup = lookup; |
| return this; |
| } |
| |
| /** |
| * Sets RLOC probe flag. |
| * |
| * @param rlocProbe RLOC probe flag |
| * @return TeRecordBuilder object |
| */ |
| public TeRecordBuilder withIsRlocProbe(boolean rlocProbe) { |
| this.rlocProbe = rlocProbe; |
| return this; |
| } |
| |
| /** |
| * Sets strict flag. |
| * |
| * @param strict strict flag |
| * @return TeRecordBuilder object |
| */ |
| public TeRecordBuilder withIsStrict(boolean strict) { |
| this.strict = strict; |
| return this; |
| } |
| |
| /** |
| * Sets RTR RLOC address. |
| * |
| * @param rtrRlocAddress RTR RLOC address |
| * @return TeRecordBuilder object |
| */ |
| public TeRecordBuilder withRtrRlocAddress(LispAfiAddress rtrRlocAddress) { |
| this.rtrRlocAddress = rtrRlocAddress; |
| return this; |
| } |
| |
| /** |
| * Builds TeRecord instance. |
| * |
| * @return TeRcord instance |
| */ |
| public LispTeRecord build() { |
| |
| return new LispTeRecord(lookup, rlocProbe, strict, rtrRlocAddress); |
| } |
| } |
| |
| /** |
| * Traffic Engineering record reader class. |
| */ |
| public static class TeRecordReader implements LispAddressReader<LispTeRecord> { |
| |
| private static final int RESERVED_SKIP_LENGTH = 1; |
| |
| private static final int STRICT_INDEX = 1; |
| private static final int RLOC_PROBE_INDEX = 2; |
| private static final int LOOKUP_INDEX = 3; |
| |
| @Override |
| public LispTeRecord readFrom(ByteBuf byteBuf) |
| throws LispParseError, LispReaderException { |
| |
| // let's skip reserved 3 |
| byteBuf.skipBytes(RESERVED_SKIP_LENGTH); |
| |
| byte flags = byteBuf.readByte(); |
| |
| // lookup -> 1 bit |
| boolean lookup = ByteOperator.getBit(flags, LOOKUP_INDEX); |
| |
| // rlocProbe -> 1 bit |
| boolean rlocProbe = ByteOperator.getBit(flags, RLOC_PROBE_INDEX); |
| |
| // strict -> 1 bit |
| boolean strict = ByteOperator.getBit(flags, STRICT_INDEX); |
| |
| AfiAddressReader reader = new AfiAddressReader(); |
| |
| LispAfiAddress rtrAddress = reader.readFrom(byteBuf); |
| |
| return new LispTeRecord(lookup, rlocProbe, strict, rtrAddress); |
| } |
| } |
| |
| /** |
| * Traffic Engineering record writer class. |
| */ |
| public static class TeRecordWriter implements LispAddressWriter<LispTeRecord> { |
| |
| private static final int LOOKUP_FLAG_SHIFT_BIT = 3; |
| private static final int RLOC_PROBE_FLAG_SHIFT_BIT = 2; |
| private static final int STRICT_FLAG_SHIFT_BIT = 1; |
| |
| private static final int ENABLE_BIT = 1; |
| private static final int DISABLE_BIT = 0; |
| |
| private static final int UNUSED_ZERO = 0; |
| |
| @Override |
| public void writeTo(ByteBuf byteBuf, LispTeRecord record) |
| throws LispWriterException { |
| |
| byteBuf.writeByte(UNUSED_ZERO); |
| |
| // lookup flag |
| byte lookup = DISABLE_BIT; |
| if (record.isLookup()) { |
| lookup = (byte) (ENABLE_BIT << LOOKUP_FLAG_SHIFT_BIT); |
| } |
| |
| // RLOC probe flag |
| byte rlocProbe = DISABLE_BIT; |
| if (record.isRlocProbe()) { |
| rlocProbe = (byte) (ENABLE_BIT << RLOC_PROBE_FLAG_SHIFT_BIT); |
| } |
| |
| // strict flag |
| byte strict = DISABLE_BIT; |
| if (record.isStrict()) { |
| strict = (byte) (ENABLE_BIT << STRICT_FLAG_SHIFT_BIT); |
| } |
| |
| byteBuf.writeByte((byte) (lookup + rlocProbe + strict)); |
| |
| // RTR RLOC address |
| AfiAddressWriter writer = new AfiAddressWriter(); |
| writer.writeTo(byteBuf, record.rtrRlocAddress); |
| } |
| } |
| } |