Shashikanth VH
Committed by Gerrit Code Review

[ONOS-4240, ONOS-4241] Support wide community optional path attribute

Change-Id: I59f9c4b69e8c26702ab955d58655497a394b9ec9
/*
* 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.bgpio.types;
import com.google.common.base.MoreObjects;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.util.Validation;
import org.jboss.netty.buffer.ChannelBuffer;
import java.util.Objects;
/**
* Provides implementation of BGP wide community attribute header.
*/
public class WideCommunityAttrHeader implements BgpValueType {
/* 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Flags | Hop Count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/
/*FLAG
+------+-------+----------------------------------------------------+
| Bit | Value | Meaning |
+------+-------+----------------------------------------------------+
| 0 | 0 | Local community value. |
| | 1 | Registered community value. |
| 1 | 0 | Do not decrement Hop Count field across |
| | | confederation boundaries. |
| | 1 | Decrement Hop Count field across confederation |
| | | boundaries. |
| 2..7 | - | MUST be zero when sent and ignored upon receipt. |
+------+-------+----------------------------------------------------+*/
public static final short TYPE = 1;
public static final short HEADER_LENGTH = 6;
private byte flag;
private byte hopCount;
private short length;
/**
* Wide community attribute header.
*
* @param flag to apply to all wide community container types
* @param hopCount represents the forwarding radius, in units of AS hops, for the given Wide BGP Community
* @param length field represents the total length of a given container
*/
public WideCommunityAttrHeader(byte flag, byte hopCount, short length) {
this.flag = flag;
this.hopCount = hopCount;
this.length = length;
}
/**
* Returns object of this class with specified values.
*
* @param flag flag to apply to all wide community container types
* @param hopCount represents the forwarding radius, in units of AS hops, for the given Wide BGP Community
* @param length field represents the total length of a given container
* @return wide community attribute header
*/
public static WideCommunityAttrHeader of(byte flag, byte hopCount, short length) {
return new WideCommunityAttrHeader(flag, hopCount, length);
}
/**
* Returns wide community flag.
*
* @return wide community flag
*/
public byte flag() {
return flag;
}
/**
* Sets wide community flag.
*
* @param flag to apply to all wide community container types
*/
public void setFlag(byte flag) {
this.flag = flag;
}
/**
* Returns hop count for wide community attribute.
*
* @return hop count from wide community
*/
public byte hopCount() {
return hopCount;
}
/**
* Sets wide community hop count.
*
* @param hopCount represents the forwarding radius, in units of AS hops, for the given Wide BGP Community
*/
public void setHopCount(byte hopCount) {
this.hopCount = hopCount;
}
/**
* Returns length of wide community attribute.
*
* @return length of wide community attribute
*/
public short length() {
return length;
}
/**
* Sets wide community length.
*
* @param length total length of a given container
*/
public void setLength(short length) {
this.length = length;
}
@Override
public int hashCode() {
return Objects.hash(flag, hopCount, length);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof WideCommunityAttrHeader) {
WideCommunityAttrHeader other = (WideCommunityAttrHeader) obj;
return Objects.equals(flag, other.flag) && Objects.equals(hopCount, other.hopCount)
&& Objects.equals(length, other.length);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iLenStartIndex = c.writerIndex();
c.writeShort(TYPE);
c.writeByte(flag);
c.writeByte(hopCount);
c.writeShort(length);
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of WideCommunityAttrHeader.
*
* @param c ChannelBuffer
* @return object of WideCommunityAttrHeader
*/
public static WideCommunityAttrHeader read(ChannelBuffer c) throws BgpParseException {
if (c.readableBytes() < HEADER_LENGTH) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
BgpErrorType.ATTRIBUTE_LENGTH_ERROR, c.readableBytes());
}
short type = c.readShort();
byte flag = c.readByte();
byte hopCount = c.readByte();
short length = c.readShort();
return WideCommunityAttrHeader.of(flag, hopCount, length);
}
@Override
public short getType() {
return TYPE;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("Type", TYPE)
.add("flag", flag)
.add("hopCount", hopCount)
.add("length", length)
.toString();
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}
\ No newline at end of file
/*
* 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.bgpio.types;
import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.attr.WideCommunity;
import java.util.List;
import java.util.Objects;
/**
* Provides implementation of BGP wide community exclude target.
*/
public class WideCommunityExcludeTarget implements BgpValueType {
public static final byte TYPE = 2;
private List<BgpValueType> excludeTargetTlv;
/**
* Wide community targets.
*
* @param excludeTargetTlv wide community exclude target
*/
public WideCommunityExcludeTarget(List<BgpValueType> excludeTargetTlv) {
this.excludeTargetTlv = excludeTargetTlv;
}
/**
* Returns object of this class with specified values.
*
* @param excludeTargetTlv exclude target
* @return object of WideCommunityExcludeTarget
*/
public static BgpValueType of(List<BgpValueType> excludeTargetTlv) {
return new WideCommunityExcludeTarget(excludeTargetTlv);
}
/**
* Returns wide community targets.
*
* @return wide community targets
*/
public List<BgpValueType> excludeTargetTlv() {
return excludeTargetTlv;
}
/**
* Sets wide community target.
*
* @param excludeTargetTlv wide community exclude targets
*/
public void setExcludeTargetTlv(List<BgpValueType> excludeTargetTlv) {
this.excludeTargetTlv = excludeTargetTlv;
}
@Override
public int hashCode() {
return Objects.hash(excludeTargetTlv);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof WideCommunityExcludeTarget) {
WideCommunityExcludeTarget other = (WideCommunityExcludeTarget) obj;
return Objects.equals(excludeTargetTlv, other.excludeTargetTlv);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iLenStartIndex = c.writerIndex();
WideCommunity.encodeWideCommunityTlv(c, excludeTargetTlv());
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of WideCommunityExcludeTarget.
*
* @param c ChannelBuffer
* @return object of WideCommunityExcludeTarget
* @throws BgpParseException on read error
*/
public static WideCommunityExcludeTarget read(ChannelBuffer c) throws BgpParseException {
return new WideCommunityExcludeTarget(WideCommunity.decodeWideCommunityTlv(c));
}
@Override
public short getType() {
return TYPE;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("Type", TYPE)
.add("targetTlv", excludeTargetTlv)
.toString();
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}
\ No newline at end of file
/*
* 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.bgpio.types;
import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.util.Validation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
/**
* Provides implementation of BGP wide community integer subtlv.
*/
public class WideCommunityInteger implements BgpValueType {
public static final short TYPE = 4;
private List<Integer> integer;
/**
* Creates an instance of wide community integer subtlv.
*
* @param integer integer
*/
public WideCommunityInteger(List<Integer> integer) {
this.integer = integer;
}
/**
* Returns object of this class with specified values.
*
* @param integer wide community subtlv integer
* @return object of WideCommunityInteger
*/
public static WideCommunityInteger of(List<Integer> integer) {
return new WideCommunityInteger(integer);
}
/**
* Returns wide community subtlv integer.
*
* @return wide community subtlv integer
*/
public List<Integer> integer() {
return integer;
}
/**
* Sets wide community subtlv integer.
*
* @param integer wide community subtlv integer
*/
public void setInteger(List<Integer> integer) {
this.integer = integer;
}
@Override
public int hashCode() {
return Objects.hash(integer);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof WideCommunityInteger) {
WideCommunityInteger other = (WideCommunityInteger) obj;
return Objects.equals(integer, other.integer);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iLenStartIndex = c.writerIndex();
Iterator<Integer> listIterator = integer.iterator();
c.writeByte(TYPE);
int iLengthIndex = c.writerIndex();
c.writeShort(0);
while (listIterator.hasNext()) {
Integer integer = listIterator.next();
if (integer instanceof Integer) {
c.writeInt(integer);
}
}
int length = c.writerIndex() - iLengthIndex;
c.setShort(iLengthIndex, (short) (length - 2));
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of WideCommunityInteger.
*
* @param c ChannelBuffer
* @return object of WideCommunityInteger
* @throws BgpParseException on read error
*/
public static WideCommunityInteger read(ChannelBuffer c) throws BgpParseException {
List<Integer> integer = new ArrayList<>();
short length;
if (c.readableBytes() < 2) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
length = c.readShort();
if (length == 0) {
return new WideCommunityInteger(integer);
}
if (c.readableBytes() < length) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
while (c.readableBytes() > 0) {
if (c.readableBytes() < 4) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
integer.add(c.readInt());
}
return new WideCommunityInteger(integer);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("integer", integer)
.toString();
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
@Override
public short getType() {
// TODO Auto-generated method stub
return 0;
}
}
/*
* 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.bgpio.types;
import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.IpAddress;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.util.Validation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
/**
* Provides implementation of BGP wide community IPV4 neighbour subtlv.
*/
public class WideCommunityIpV4Neighbour implements BgpValueType {
public static final byte TYPE = 8;
private List<IpV4Neighbour> ipv4Neighbour;
public static final byte IPV4_NEIGHBOUR_SIZE = 8;
/**
* Creates an instance of wide community ipv4 neighbour subtlv.
*
*/
public WideCommunityIpV4Neighbour() {
this.ipv4Neighbour = new ArrayList<>();
}
/**
* Adds local and remote speakers.
*
* @param localSpeaker local speaker
* @param remoteSpeaker remote speaker
*/
public void add(IpAddress localSpeaker, IpAddress remoteSpeaker) {
ipv4Neighbour.add(new IpV4Neighbour(localSpeaker, remoteSpeaker));
}
/**
* Deletes local and remote speakers.
*
* @param localSpeaker local speaker
* @param remoteSpeaker remote speaker
*/
public void remove(IpAddress localSpeaker, IpAddress remoteSpeaker) {
ipv4Neighbour.remove(new IpV4Neighbour(localSpeaker, remoteSpeaker));
}
@Override
public int hashCode() {
return Objects.hash(ipv4Neighbour);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof WideCommunityIpV4Neighbour) {
WideCommunityIpV4Neighbour other = (WideCommunityIpV4Neighbour) obj;
return Objects.equals(ipv4Neighbour, other.ipv4Neighbour);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iLenStartIndex = c.writerIndex();
Iterator<IpV4Neighbour> listIterator = ipv4Neighbour.iterator();
c.writeByte(TYPE);
int iLengthIndex = c.writerIndex();
c.writeShort(0);
while (listIterator.hasNext()) {
IpV4Neighbour speaker = listIterator.next();
if (speaker instanceof IpV4Neighbour) {
c.writeInt(Integer.valueOf(speaker.localSpeaker.toString()));
c.writeInt(Integer.valueOf(speaker.remoteSpeaker.toString()));
}
}
int length = c.writerIndex() - iLengthIndex;
c.setShort(iLengthIndex, (short) (length - 2));
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of WideCommunityIpV4Neighbour.
*
* @param c ChannelBuffer
* @return object of WideCommunityIpV4Neighbour
* @throws BgpParseException on read error
*/
public static WideCommunityIpV4Neighbour read(ChannelBuffer c) throws BgpParseException {
WideCommunityIpV4Neighbour wideCommNeighbour = new WideCommunityIpV4Neighbour();
short length;
if (c.readableBytes() == 0) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
length = c.readShort();
if (c.readableBytes() == 0) {
return wideCommNeighbour;
}
if (c.readableBytes() < length) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
while (c.readableBytes() > 0) {
if (c.readableBytes() < IPV4_NEIGHBOUR_SIZE) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
IpAddress localSpeaker = IpAddress.valueOf(c.readInt());
IpAddress remoteSpeaker = IpAddress.valueOf(c.readInt());
wideCommNeighbour.add(localSpeaker, remoteSpeaker);
}
return wideCommNeighbour;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("ipv4Neighbour", ipv4Neighbour)
.toString();
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
@Override
public short getType() {
// TODO Auto-generated method stub
return 0;
}
/*
* IpV4Neighbour class contain remote and local speaker.
*/
private class IpV4Neighbour {
private IpAddress localSpeaker;
private IpAddress remoteSpeaker;
/**
* Creates an instance of ipv4 neighbour.
*
* @param localSpeaker ip address of local speaker
* @param remoteSpeaker ip address of remote speaker
*/
public IpV4Neighbour(IpAddress localSpeaker, IpAddress remoteSpeaker) {
this.localSpeaker = localSpeaker;
this.remoteSpeaker = remoteSpeaker;
}
/**
* Returns IPV4 neighbour local speaker.
*
* @return IPV4 neighbour local speaker
*/
public IpAddress localSpeaker() {
return localSpeaker;
}
/**
* Returns IPV4 neighbour remote speaker.
*
* @return IPV4 neighbour remote speaker
*/
public IpAddress remoteSpeaker() {
return remoteSpeaker;
}
}
}
\ No newline at end of file
/*
* 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.bgpio.types;
import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.attr.WideCommunity;
import java.util.List;
import java.util.Objects;
/**
* Provides implementation of BGP wide community parameter.
*/
public class WideCommunityParameter implements BgpValueType {
public static final byte TYPE = 3;
private List<BgpValueType> parameterTlv;
/**
* Creates an instance of wide community parameter.
*
* @param parameterTlv wide community parameter
*/
public WideCommunityParameter(List<BgpValueType> parameterTlv) {
this.parameterTlv = parameterTlv;
}
/**
* Returns object of this class with specified values.
*
* @param parameterTlv wide community parameter
* @return object of WideCommunityParameter
*/
public static WideCommunityParameter of(List<BgpValueType> parameterTlv) {
return new WideCommunityParameter(parameterTlv);
}
/**
* Returns wide community parameter.
*
* @return wide community parameter
*/
public List<BgpValueType> parameterTlv() {
return parameterTlv;
}
/**
* Sets wide community parameter.
*
* @param parameterTlv wide community parameter
*/
public void setParameterTlv(List<BgpValueType> parameterTlv) {
this.parameterTlv = parameterTlv;
}
@Override
public int hashCode() {
return Objects.hash(parameterTlv);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof WideCommunityParameter) {
WideCommunityParameter other = (WideCommunityParameter) obj;
return Objects.equals(parameterTlv, other.parameterTlv);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iLenStartIndex = c.writerIndex();
WideCommunity.encodeWideCommunityTlv(c, parameterTlv());
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of WideCommunityParameter.
*
* @param c ChannelBuffer
* @return object of WideCommunityParameter
* @throws BgpParseException on read error
*/
public static WideCommunityParameter read(ChannelBuffer c) throws BgpParseException {
return new WideCommunityParameter(WideCommunity.decodeWideCommunityTlv(c));
}
@Override
public short getType() {
return TYPE;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("Type", TYPE)
.add("parameterTlv", parameterTlv)
.toString();
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}
\ No newline at end of file
/*
* 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.bgpio.types;
import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.attr.WideCommunity;
import java.util.List;
import java.util.Objects;
/**
* Provides implementation of BGP wide community target.
*/
public class WideCommunityTarget implements BgpValueType {
public static final byte TYPE = 1;
private List<BgpValueType> targetTlv;
/**
* Creates an instance of Wide community targets.
*
* @param targetTlv wide community targets to match
*/
public WideCommunityTarget(List<BgpValueType> targetTlv) {
this.targetTlv = targetTlv;
}
/**
* Returns object of this class with specified values.
*
* @param targetTlv wide community target
* @return object of WideCommunityTarget
*/
public static WideCommunityTarget of(List<BgpValueType> targetTlv) {
return new WideCommunityTarget(targetTlv);
}
/**
* Returns wide community targets.
*
* @return wide community targets
*/
public List<BgpValueType> targetTlv() {
return targetTlv;
}
/**
* Sets wide community target.
*
* @param targetTlv wide community targets to match
*/
public void setTargetTlv(List<BgpValueType> targetTlv) {
this.targetTlv = targetTlv;
}
@Override
public int hashCode() {
return Objects.hash(targetTlv);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj instanceof WideCommunityTarget) {
WideCommunityTarget other = (WideCommunityTarget) obj;
return Objects.equals(targetTlv, other.targetTlv);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iLenStartIndex = c.writerIndex();
WideCommunity.encodeWideCommunityTlv(c, targetTlv());
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the channel buffer and returns object of WideCommunityTarget.
*
* @param c ChannelBuffer
* @return object of WideCommunityTarget
* @throws BgpParseException on read error
*/
public static WideCommunityTarget read(ChannelBuffer c) throws BgpParseException {
return new WideCommunityTarget(WideCommunity.decodeWideCommunityTlv(c));
}
@Override
public short getType() {
return TYPE;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("Type", TYPE)
.add("targetTlv", targetTlv)
.toString();
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}
/*
* 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.bgpio.types.attr;
import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.IpAddress;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.WideCommunityAttrHeader;
import org.onosproject.bgpio.types.WideCommunityExcludeTarget;
import org.onosproject.bgpio.types.WideCommunityInteger;
import org.onosproject.bgpio.types.WideCommunityIpV4Neighbour;
import org.onosproject.bgpio.types.WideCommunityParameter;
import org.onosproject.bgpio.types.WideCommunityTarget;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
/**
* Provides implementation of wide community path attribute.
*/
public class WideCommunity implements BgpValueType {
private static final Logger log = LoggerFactory.getLogger(WideCommunity.class);
public static final byte TYPE = (byte) 254; /* TODO: IANA Assigned */
public static final short LENGTH = 4;
public static final byte TYPE_LENGTH_SIZE = 3;
public static final byte FLAGS = (byte) 0x40;
private WideCommunityAttrHeader wideCommunityHeader;
private int community;
private int localAsn;
private int contextAsn;
private WideCommunityTarget target;
private WideCommunityExcludeTarget excludeTarget;
private WideCommunityParameter parameter;
/**
* Creates an instance of wide community.
*
* @param wideCommunityHeader wide community header
* @param community wide community
* @param localAsn local ASN number
* @param contextAsn context ASN number
* @param target wide community include target
* @param excludeTarget wide community exclude target
* @param parameter wide community parameter
*/
public WideCommunity(WideCommunityAttrHeader wideCommunityHeader, int community, int localAsn, int contextAsn,
WideCommunityTarget target, WideCommunityExcludeTarget excludeTarget,
WideCommunityParameter parameter) {
this.wideCommunityHeader = wideCommunityHeader;
this.community = community;
this.localAsn = localAsn;
this.contextAsn = contextAsn;
this.target = target;
this.excludeTarget = excludeTarget;
this.parameter = parameter;
}
/**
* Returns object of this class with specified values.
*
* @param community wide community
* @param localAsn local ASN number
* @param contextAsn context ASN number
* @param target wide community include target
* @param excludeTarget wide community exclude target
* @param parameter wide community parameter
* @return object of WideCommunityAttr
*/
public static WideCommunity of(WideCommunityAttrHeader wideCommunityHeader, int community, int localAsn,
int contextAsn, WideCommunityTarget target,
WideCommunityExcludeTarget excludeTarget, WideCommunityParameter parameter) {
return new WideCommunity(wideCommunityHeader, community, localAsn, contextAsn, target, excludeTarget,
parameter);
}
/**
* Returns wide community value.
*
* @return wide community value
*/
public int community() {
return community;
}
/**
* Sets wide community value.
*
* @param community wide community value
*/
public void setCommunity(int community) {
this.community = community;
}
/**
* Returns wide community local autonomous number.
*
* @return local autonomous number
*/
public int localAsn() {
return localAsn;
}
/**
* Sets wide community local autonomous number.
*
* @param localAsn local autonomous number
*/
public void setLocalAsn(int localAsn) {
this.localAsn = localAsn;
}
/**
* Returns wide community context autonomous number.
*
* @return contest autonomous number
*/
public int contextAsn() {
return contextAsn;
}
/**
* Sets wide community context autonomous number.
*
* @param contextAsn context autonomous number
*/
public void setContextAsn(int contextAsn) {
this.contextAsn = contextAsn;
}
/**
* Returns wide community target.
*
* @return wide community target
*/
public WideCommunityTarget target() {
return target;
}
/**
* Sets wide community target.
*
* @param target wide community target
*/
public void setTarget(WideCommunityTarget target) {
this.target = target;
}
/**
* Returns wide community exclude target.
*
* @return wide community exclude target
*/
public WideCommunityExcludeTarget excludeTarget() {
return excludeTarget;
}
/**
* Sets wide community exclude target.
*
* @param excludeTarget wide community texclude arget
*/
public void setExcludeTarget(WideCommunityExcludeTarget excludeTarget) {
this.excludeTarget = excludeTarget;
}
/**
* Returns wide community parameter.
*
* @return wide community parameter
*/
public WideCommunityParameter parameter() {
return parameter;
}
/**
* Sets wide community parameter.
*
* @param parameter wide community parameter
*/
public void setParameter(WideCommunityParameter parameter) {
this.parameter = parameter;
}
@Override
public int hashCode() {
return Objects.hash(wideCommunityHeader, community, localAsn, contextAsn, target, excludeTarget, parameter);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof WideCommunity) {
WideCommunity other = (WideCommunity) obj;
return Objects.equals(wideCommunityHeader, other.wideCommunityHeader)
&& Objects.equals(community, other.community) && Objects.equals(localAsn, other.localAsn)
&& Objects.equals(contextAsn, other.contextAsn) && Objects.equals(target, other.target)
&& Objects.equals(excludeTarget, other.excludeTarget) && Objects.equals(parameter, other.parameter);
}
return false;
}
@Override
public int write(ChannelBuffer c) {
int iTargetLenIndex;
int length;
int iLenStartIndex = c.writerIndex();
c.writeByte(FLAGS); // TODO: update flag value
c.writeByte(TYPE);
int iLengthIndex = c.writerIndex();
c.writeShort(0);
wideCommunityHeader.write(c);
c.writeInt(community);
c.writeInt(localAsn);
c.writeInt(contextAsn);
if (target() != null) {
c.writeByte(WideCommunityTarget.TYPE);
iTargetLenIndex = c.writerIndex();
c.writeShort(0); // length
target.write(c);
length = c.writerIndex() - iTargetLenIndex;
c.setShort(iTargetLenIndex, (short) (length - 2));
}
if (excludeTarget() != null) {
c.writeByte(WideCommunityExcludeTarget.TYPE);
iTargetLenIndex = c.writerIndex();
c.writeShort(0); // length
excludeTarget.write(c);
length = c.writerIndex() - iTargetLenIndex;
c.setShort(iTargetLenIndex, (short) (length - 2));
}
if (parameter() != null) {
c.writeByte(WideCommunityParameter.TYPE);
iTargetLenIndex = c.writerIndex();
c.writeShort(0); // length
parameter.write(c);
length = c.writerIndex() - iTargetLenIndex;
c.setShort(iTargetLenIndex, (short) (length - 2));
}
length = c.writerIndex() - iLengthIndex;
c.setShort(iLengthIndex, (short) (length - 2));
return c.writerIndex() - iLenStartIndex;
}
/**
* Reads the wide community attribute.
*
* @param c ChannelBuffer
* @return object of WideCommunityAttr
* @throws BgpParseException while parsing BgpPrefixAttrRouteTag
*/
public static WideCommunity read(ChannelBuffer c) throws BgpParseException {
WideCommunityAttrHeader wideCommunityHeader;
int community;
int localAsn;
int contextAsn;
WideCommunityTarget target = null;
WideCommunityExcludeTarget excludeTarget = null;
WideCommunityParameter parameter = null;
short length = c.readShort();
if (c.readableBytes() < length) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, length);
}
wideCommunityHeader = WideCommunityAttrHeader.read(c);
if ((c.readableBytes() < 12) || (c.readableBytes() < wideCommunityHeader.length())) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR, length);
}
community = c.readInt();
localAsn = c.readInt();
contextAsn = c.readInt();
while (c.readableBytes() > 0) {
if (c.readableBytes() < TYPE_LENGTH_SIZE) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
byte type = c.readByte();
length = c.readShort();
if (c.readableBytes() < length) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
if (type == WideCommunityTarget.TYPE) {
target = WideCommunityTarget.read(c);
} else if (type == WideCommunityExcludeTarget.TYPE) {
excludeTarget = WideCommunityExcludeTarget.read(c);
} else if (type == WideCommunityParameter.TYPE) {
parameter = WideCommunityParameter.read(c);
}
}
return new WideCommunity(wideCommunityHeader, community, localAsn, contextAsn,
target, excludeTarget, parameter);
}
/**
* Encode wide community target(s).
*
* @param c channel buffer
* @param targetTlv wide community include/exclude target
*/
public static void encodeWideCommunityTlv(ChannelBuffer c,
List<BgpValueType> targetTlv) {
/*
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IPV4Neig(8) | Length: 8 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| local 10101010 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| remote 10101010 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* */
List<BgpValueType> target = targetTlv;
if (target == null) {
log.debug("target is null");
return;
}
Iterator<BgpValueType> listIterator = targetTlv.iterator();
while (listIterator.hasNext()) {
BgpValueType attr = listIterator.next();
if (attr instanceof WideCommunityIpV4Neighbour) {
WideCommunityIpV4Neighbour ipv4Neig = (WideCommunityIpV4Neighbour) attr;
ipv4Neig.write(c);
} else if (attr instanceof WideCommunityInteger) {
WideCommunityInteger integer = (WideCommunityInteger) attr;
integer.write(c);
}
}
return;
}
/**
* Decode wide community target(s).
*
* @param c channel buffer
* @return target list
* @throws BgpParseException on decode error
*/
public static List<BgpValueType> decodeWideCommunityTlv(ChannelBuffer c) throws BgpParseException {
List<BgpValueType> targetTlv = new ArrayList<>();
while (c.readableBytes() > 0) {
if (c.readableBytes() < TYPE_LENGTH_SIZE) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
c.readableBytes());
}
byte atomType = c.readByte();
short atomLength = c.readShort();
if (c.readableBytes() < atomLength) {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
atomLength);
}
if (atomType == WideCommunityIpV4Neighbour.TYPE) {
ChannelBuffer tempBuf = c.readBytes(atomLength);
WideCommunityIpV4Neighbour wideCommAtom = new WideCommunityIpV4Neighbour();
while (tempBuf.readableBytes() > 0) {
wideCommAtom.add(IpAddress.valueOf(tempBuf.readInt()),
IpAddress.valueOf(tempBuf.readInt()));
}
targetTlv.add(wideCommAtom);
} else if (atomType == WideCommunityInteger.TYPE) {
ChannelBuffer tempBuf = c.readBytes(atomLength);
List<Integer> integer = new ArrayList<>();
while (tempBuf.readableBytes() > 0) {
integer.add(tempBuf.readInt());
}
targetTlv.add(new WideCommunityInteger(integer));
} else {
Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.MALFORMED_ATTRIBUTE_LIST,
atomLength);
}
}
return targetTlv;
}
@Override
public short getType() {
return TYPE;
}
@Override
public int compareTo(Object o) {
// TODO:
return 0;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("FLAGS", FLAGS)
.add("wideCommunityHeader", wideCommunityHeader)
.add("community", community)
.add("localAsn", localAsn)
.add("contextAsn", contextAsn)
.add("target", target)
.add("excludeTarget", excludeTarget)
.add("parameter", parameter).toString();
}
}