blob: f9f4f2a3b3521e99d0a81bd4cf2cb6d04df7db9f [file] [log] [blame]
/*
* 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 com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.exceptions.LispWriterException;
import java.util.List;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
/**
* Network Address Translation (NAT) address class.
* <p>
* Instance ID type is defined in draft-ietf-lisp-lcaf-20
* https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#page-12
*
* <pre>
* {@literal
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | AFI = 16387 | Rsvd1 | Flags |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type = 7 | Rsvd2 | Length |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | MS UDP Port Number | ETR UDP Port Number |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | AFI = x | Global ETR RLOC Address ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | AFI = x | MS RLOC Address ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | AFI = x | Private ETR RLOC Address ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | AFI = x | RTR RLOC Address 1 ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | AFI = x | RTR RLOC Address k ... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* }</pre>
*/
public final class LispNatLcafAddress extends LispLcafAddress {
private final short msUdpPortNumber;
private final short etrUdpPortNumber;
private final LispAfiAddress globalEtrRlocAddress;
private final LispAfiAddress msRlocAddress;
private final LispAfiAddress privateEtrRlocAddress;
private final List<LispAfiAddress> rtrRlocAddresses;
/**
* Initializes NAT type LCAF address.
*
* @param reserved2 reserved2
* @param length length
* @param msUdpPortNumber Map Server (MS) UDP port number
* @param etrUdpPortNumber ETR UDP port number
* @param globalEtrRlocAddress global ETR RLOC address
* @param msRlocAddress Map Server (MS) RLOC address
* @param privateEtrRlocAddress private ETR RLOC address
* @param rtrRlocAddresses a collection of RTR RLOC addresses
*/
private LispNatLcafAddress(byte reserved2, short length, short msUdpPortNumber,
short etrUdpPortNumber, LispAfiAddress globalEtrRlocAddress,
LispAfiAddress msRlocAddress, LispAfiAddress privateEtrRlocAddress,
List<LispAfiAddress> rtrRlocAddresses) {
super(LispCanonicalAddressFormatEnum.NAT, reserved2, length);
this.msUdpPortNumber = msUdpPortNumber;
this.etrUdpPortNumber = etrUdpPortNumber;
this.globalEtrRlocAddress = globalEtrRlocAddress;
this.msRlocAddress = msRlocAddress;
this.privateEtrRlocAddress = privateEtrRlocAddress;
this.rtrRlocAddresses = ImmutableList.copyOf(rtrRlocAddresses);
}
/**
* Obtains Map Server UDP port number.
*
* @return Map Server UDP port number
*/
public short getMsUdpPortNumber() {
return msUdpPortNumber;
}
/**
* Obtains ETR UDP port number.
*
* @return ETR UDP port number
*/
public short getEtrUdpPortNumber() {
return etrUdpPortNumber;
}
/**
* Obtains global ETR RLOC address.
*
* @return global ETR
*/
public LispAfiAddress getGlobalEtrRlocAddress() {
return globalEtrRlocAddress;
}
/**
* Obtains Map Server RLOC address.
*
* @return Map Server RLOC address
*/
public LispAfiAddress getMsRlocAddress() {
return msRlocAddress;
}
/**
* Obtains private ETR RLOC address.
*
* @return private ETR RLOC address
*/
public LispAfiAddress getPrivateEtrRlocAddress() {
return privateEtrRlocAddress;
}
/**
* Obtains a collection of RTR RLOC addresses.
*
* @return a collection of RTR RLOC addresses
*/
public List<LispAfiAddress> getRtrRlocAddresses() {
return ImmutableList.copyOf(rtrRlocAddresses);
}
@Override
public int hashCode() {
return Objects.hash(msUdpPortNumber, etrUdpPortNumber,
globalEtrRlocAddress, msRlocAddress, privateEtrRlocAddress);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof LispNatLcafAddress) {
final LispNatLcafAddress other = (LispNatLcafAddress) obj;
return Objects.equals(this.msUdpPortNumber, other.msUdpPortNumber) &&
Objects.equals(this.etrUdpPortNumber, other.etrUdpPortNumber) &&
Objects.equals(this.globalEtrRlocAddress, other.globalEtrRlocAddress) &&
Objects.equals(this.msRlocAddress, other.msRlocAddress) &&
Objects.equals(this.privateEtrRlocAddress, other.privateEtrRlocAddress);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("Map Server UDP port number", msUdpPortNumber)
.add("ETR UDP port number", etrUdpPortNumber)
.add("global ETR RLOC address", globalEtrRlocAddress)
.add("Map Server RLOC address", msRlocAddress)
.add("private ETR RLOC address", privateEtrRlocAddress)
.toString();
}
public static final class NatAddressBuilder extends LcafAddressBuilder<NatAddressBuilder> {
private short msUdpPortNumber;
private short etrUdpPortNumber;
private LispAfiAddress globalEtrRlocAddress;
private LispAfiAddress msRlocAddress;
private LispAfiAddress privateEtrRlocAddress;
private List<LispAfiAddress> rtrRlocAddresses = Lists.newArrayList();
/**
* Sets Map Server UDP port number.
*
* @param msUdpPortNumber Map Server UDP port number
* @return NatAddressBuilder object
*/
public NatAddressBuilder withMsUdpPortNumber(short msUdpPortNumber) {
this.msUdpPortNumber = msUdpPortNumber;
return this;
}
/**
* Sets ETR UDP port number.
*
* @param etrUdpPortNumber ETR UDP port number
* @return NatAddressBuilder object
*/
public NatAddressBuilder withEtrUdpPortNumber(short etrUdpPortNumber) {
this.etrUdpPortNumber = etrUdpPortNumber;
return this;
}
/**
* Sets global ETR RLOC address.
*
* @param globalEtrRlocAddress global ETR RLOC address
* @return NatAddressBuilder object
*/
public NatAddressBuilder withGlobalEtrRlocAddress(LispAfiAddress globalEtrRlocAddress) {
this.globalEtrRlocAddress = globalEtrRlocAddress;
return this;
}
/**
* Sets Map Server RLOC address.
*
* @param msRlocAddress Map Server RLOC address
* @return NatAddressBuilder object
*/
public NatAddressBuilder withMsRlocAddress(LispAfiAddress msRlocAddress) {
this.msRlocAddress = msRlocAddress;
return this;
}
/**
* Sets private ETR RLOC address.
*
* @param privateEtrRlocAddress private ETR RLOC address
* @return NatAddressBuilder object
*/
public NatAddressBuilder withPrivateEtrRlocAddress(LispAfiAddress privateEtrRlocAddress) {
this.privateEtrRlocAddress = privateEtrRlocAddress;
return this;
}
/**
* Sets RTR RLOC addresses.
*
* @param rtrRlocAddresses a collection of RTR RLOC addresses
* @return NatAddressBuilder object
*/
public NatAddressBuilder withRtrRlocAddresses(List<LispAfiAddress> rtrRlocAddresses) {
if (rtrRlocAddresses != null) {
this.rtrRlocAddresses = ImmutableList.copyOf(rtrRlocAddresses);
}
return this;
}
public LispNatLcafAddress build() {
// TODO: need to do null check
return new LispNatLcafAddress(reserved2, length, msUdpPortNumber,
etrUdpPortNumber, globalEtrRlocAddress, msRlocAddress,
privateEtrRlocAddress, rtrRlocAddresses);
}
}
/**
* NAT LCAF address reader class.
*/
public static class NatLcafAddressReader
implements LispAddressReader<LispNatLcafAddress> {
@Override
public LispNatLcafAddress readFrom(ByteBuf byteBuf)
throws LispParseError, LispReaderException {
LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
short msUdpPortNumber = (short) byteBuf.readUnsignedShort();
short etrUdpPortNumber = (short) byteBuf.readUnsignedShort();
LispAfiAddress globalEtrRlocAddress = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
LispAfiAddress msRlocAddress = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
LispAfiAddress privateEtrRlocAddress = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
List<LispAfiAddress> rtrRlocAddresses = Lists.newArrayList();
for (int i = 0; i < lcafAddress.getLength(); i++) {
rtrRlocAddresses.add(new LispAfiAddress.AfiAddressReader().readFrom(byteBuf));
}
return new NatAddressBuilder()
.withReserved1(lcafAddress.getReserved1())
.withReserved2(lcafAddress.getReserved2())
.withFlag(lcafAddress.getFlag())
.withLength(lcafAddress.getLength())
.withMsUdpPortNumber(msUdpPortNumber)
.withEtrUdpPortNumber(etrUdpPortNumber)
.withGlobalEtrRlocAddress(globalEtrRlocAddress)
.withMsRlocAddress(msRlocAddress)
.withPrivateEtrRlocAddress(privateEtrRlocAddress)
.withRtrRlocAddresses(rtrRlocAddresses).build();
}
}
/**
* NAT LCAF address writer class.
*/
public static class NatLcafAddressWriter
implements LispAddressWriter<LispNatLcafAddress> {
@Override
public void writeTo(ByteBuf byteBuf, LispNatLcafAddress address)
throws LispWriterException {
LispLcafAddress.serializeCommon(byteBuf, address);
byteBuf.writeShort(address.getMsUdpPortNumber());
byteBuf.writeShort(address.getEtrUdpPortNumber());
AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
writer.writeTo(byteBuf, address.getGlobalEtrRlocAddress());
writer.writeTo(byteBuf, address.getMsRlocAddress());
writer.writeTo(byteBuf, address.getPrivateEtrRlocAddress());
List<LispAfiAddress> rtrRlocAddresses = address.getRtrRlocAddresses();
for (int i = 0; i < rtrRlocAddresses.size(); i++) {
writer.writeTo(byteBuf, rtrRlocAddresses.get(i));
}
}
}
}