Committed by
Ray Milkey
[Emu] [ONOS-2602]Implement BGP Update Protocol Message Mpreach and MPunreach parse and
decode(Node, Link and Prefix) Change-Id: If979c8eaa7127a3c6701ebca07ea779c039369fb
Showing
1 changed file
with
252 additions
and
0 deletions
bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPLinkLSIdentifier.java
0 → 100755
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.bgpio.protocol.link_state; | ||
| 17 | + | ||
| 18 | +import java.util.Iterator; | ||
| 19 | +import java.util.LinkedList; | ||
| 20 | +import java.util.List; | ||
| 21 | +import java.util.Objects; | ||
| 22 | + | ||
| 23 | +import org.jboss.netty.buffer.ChannelBuffer; | ||
| 24 | +import org.onosproject.bgpio.exceptions.BGPParseException; | ||
| 25 | +import org.onosproject.bgpio.types.BGPErrorType; | ||
| 26 | +import org.onosproject.bgpio.types.BGPValueType; | ||
| 27 | +import org.onosproject.bgpio.types.IPv4AddressTlv; | ||
| 28 | +import org.onosproject.bgpio.types.IPv6AddressTlv; | ||
| 29 | +import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv; | ||
| 30 | +import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId; | ||
| 31 | +import org.onosproject.bgpio.util.UnSupportedAttribute; | ||
| 32 | +import org.slf4j.Logger; | ||
| 33 | +import org.slf4j.LoggerFactory; | ||
| 34 | + | ||
| 35 | +import com.google.common.base.MoreObjects; | ||
| 36 | +import com.google.common.base.Preconditions; | ||
| 37 | + | ||
| 38 | +/** | ||
| 39 | + * Implementation of local node descriptors, remote node descriptors and link descriptors. | ||
| 40 | + */ | ||
| 41 | +public class BGPLinkLSIdentifier { | ||
| 42 | + private static final Logger log = LoggerFactory.getLogger(BGPLinkLSIdentifier.class); | ||
| 43 | + public static final short IPV4_INTERFACE_ADDRESS_TYPE = 259; | ||
| 44 | + public static final short IPV4_NEIGHBOR_ADDRESS_TYPE = 260; | ||
| 45 | + public static final short IPV6_INTERFACE_ADDRESS_TYPE = 261; | ||
| 46 | + public static final short IPV6_NEIGHBOR_ADDRESS_TYPE = 262; | ||
| 47 | + public static final int TYPE_AND_LEN = 4; | ||
| 48 | + | ||
| 49 | + private NodeDescriptors localNodeDescriptors; | ||
| 50 | + private NodeDescriptors remoteNodeDescriptors; | ||
| 51 | + private List<BGPValueType> linkDescriptor; | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * Initialize fields. | ||
| 55 | + */ | ||
| 56 | + public BGPLinkLSIdentifier() { | ||
| 57 | + this.localNodeDescriptors = null; | ||
| 58 | + this.remoteNodeDescriptors = null; | ||
| 59 | + this.linkDescriptor = null; | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * Constructors to initialize parameters. | ||
| 64 | + * | ||
| 65 | + * @param localNodeDescriptors local node descriptors | ||
| 66 | + * @param remoteNodeDescriptors remote node descriptors | ||
| 67 | + * @param linkDescriptor link descriptors | ||
| 68 | + */ | ||
| 69 | + public BGPLinkLSIdentifier(NodeDescriptors localNodeDescriptors, NodeDescriptors remoteNodeDescriptors, | ||
| 70 | + LinkedList<BGPValueType> linkDescriptor) { | ||
| 71 | + this.localNodeDescriptors = Preconditions.checkNotNull(localNodeDescriptors); | ||
| 72 | + this.remoteNodeDescriptors = Preconditions.checkNotNull(remoteNodeDescriptors); | ||
| 73 | + this.linkDescriptor = Preconditions.checkNotNull(linkDescriptor); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * Reads channel buffer and parses link identifier. | ||
| 78 | + * | ||
| 79 | + * @param cb ChannelBuffer | ||
| 80 | + * @param protocolId in linkstate nlri | ||
| 81 | + * @return object of BGPLinkLSIdentifier | ||
| 82 | + * @throws BGPParseException while parsing link identifier | ||
| 83 | + */ | ||
| 84 | + public static BGPLinkLSIdentifier parseLinkIdendifier(ChannelBuffer cb, byte protocolId) throws BGPParseException { | ||
| 85 | + //Parse local node descriptor | ||
| 86 | + NodeDescriptors localNodeDescriptors = new NodeDescriptors(); | ||
| 87 | + localNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.LOCAL_NODE_DES_TYPE, protocolId); | ||
| 88 | + | ||
| 89 | + //Parse remote node descriptor | ||
| 90 | + NodeDescriptors remoteNodeDescriptors = new NodeDescriptors(); | ||
| 91 | + remoteNodeDescriptors = parseNodeDescriptors(cb, NodeDescriptors.REMOTE_NODE_DES_TYPE, protocolId); | ||
| 92 | + | ||
| 93 | + //Parse link descriptor | ||
| 94 | + LinkedList<BGPValueType> linkDescriptor = new LinkedList<>(); | ||
| 95 | + linkDescriptor = parseLinkDescriptors(cb); | ||
| 96 | + return new BGPLinkLSIdentifier(localNodeDescriptors, remoteNodeDescriptors, linkDescriptor); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * Parses Local/Remote node descriptors. | ||
| 101 | + * | ||
| 102 | + * @param cb ChannelBuffer | ||
| 103 | + * @param desType descriptor type | ||
| 104 | + * @param protocolId protocol identifier | ||
| 105 | + * @return object of NodeDescriptors | ||
| 106 | + * @throws BGPParseException while parsing Local/Remote node descriptors | ||
| 107 | + */ | ||
| 108 | + public static NodeDescriptors parseNodeDescriptors(ChannelBuffer cb, short desType, byte protocolId) | ||
| 109 | + throws BGPParseException { | ||
| 110 | + ChannelBuffer tempBuf = cb; | ||
| 111 | + short type = cb.readShort(); | ||
| 112 | + short length = cb.readShort(); | ||
| 113 | + if (cb.readableBytes() < length) { | ||
| 114 | + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, | ||
| 115 | + tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); | ||
| 116 | + } | ||
| 117 | + NodeDescriptors nodeIdentifier = new NodeDescriptors(); | ||
| 118 | + ChannelBuffer tempCb = cb.readBytes(length); | ||
| 119 | + | ||
| 120 | + if (type == desType) { | ||
| 121 | + nodeIdentifier = NodeDescriptors.read(tempCb, length, desType, protocolId); | ||
| 122 | + } else { | ||
| 123 | + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.MALFORMED_ATTRIBUTE_LIST, null); | ||
| 124 | + } | ||
| 125 | + return nodeIdentifier; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + /** | ||
| 129 | + * Parses link descriptors. | ||
| 130 | + * | ||
| 131 | + * @param cb ChannelBuffer | ||
| 132 | + * @return list of link descriptors | ||
| 133 | + * @throws BGPParseException while parsing link descriptors | ||
| 134 | + */ | ||
| 135 | + public static LinkedList<BGPValueType> parseLinkDescriptors(ChannelBuffer cb) throws BGPParseException { | ||
| 136 | + LinkedList<BGPValueType> linkDescriptor = new LinkedList<>(); | ||
| 137 | + BGPValueType tlv = null; | ||
| 138 | + int count = 0; | ||
| 139 | + | ||
| 140 | + while (cb.readableBytes() > 0) { | ||
| 141 | + ChannelBuffer tempBuf = cb; | ||
| 142 | + short type = cb.readShort(); | ||
| 143 | + short length = cb.readShort(); | ||
| 144 | + if (cb.readableBytes() < length) { | ||
| 145 | + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, | ||
| 146 | + tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN)); | ||
| 147 | + } | ||
| 148 | + ChannelBuffer tempCb = cb.readBytes(length); | ||
| 149 | + switch (type) { | ||
| 150 | + case LinkLocalRemoteIdentifiersTlv.TYPE: | ||
| 151 | + tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb); | ||
| 152 | + break; | ||
| 153 | + case IPV4_INTERFACE_ADDRESS_TYPE: | ||
| 154 | + tlv = IPv4AddressTlv.read(tempCb, IPV4_INTERFACE_ADDRESS_TYPE); | ||
| 155 | + break; | ||
| 156 | + case IPV4_NEIGHBOR_ADDRESS_TYPE: | ||
| 157 | + tlv = IPv4AddressTlv.read(tempCb, IPV4_NEIGHBOR_ADDRESS_TYPE); | ||
| 158 | + break; | ||
| 159 | + case IPV6_INTERFACE_ADDRESS_TYPE: | ||
| 160 | + tlv = IPv6AddressTlv.read(tempCb, IPV6_INTERFACE_ADDRESS_TYPE); | ||
| 161 | + break; | ||
| 162 | + case IPV6_NEIGHBOR_ADDRESS_TYPE: | ||
| 163 | + tlv = IPv6AddressTlv.read(tempCb, IPV6_NEIGHBOR_ADDRESS_TYPE); | ||
| 164 | + break; | ||
| 165 | + case BgpAttrNodeMultiTopologyId.ATTRNODE_MULTITOPOLOGY: | ||
| 166 | + tlv = BgpAttrNodeMultiTopologyId.read(tempCb); | ||
| 167 | + count = count++; | ||
| 168 | + //MultiTopologyId TLV cannot repeat more than once | ||
| 169 | + if (count > 1) { | ||
| 170 | + //length + 4 implies data contains type, length and value | ||
| 171 | + throw new BGPParseException(BGPErrorType.UPDATE_MESSAGE_ERROR, | ||
| 172 | + BGPErrorType.OPTIONAL_ATTRIBUTE_ERROR, tempBuf.readBytes(length | ||
| 173 | + + TYPE_AND_LEN)); | ||
| 174 | + } | ||
| 175 | + break; | ||
| 176 | + default: | ||
| 177 | + UnSupportedAttribute.skipBytes(tempCb, length); | ||
| 178 | + } | ||
| 179 | + linkDescriptor.add(tlv); | ||
| 180 | + } | ||
| 181 | + return linkDescriptor; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + /** | ||
| 185 | + * Returns local node descriptors. | ||
| 186 | + * | ||
| 187 | + * @return local node descriptors | ||
| 188 | + */ | ||
| 189 | + public NodeDescriptors localNodeDescriptors() { | ||
| 190 | + return this.localNodeDescriptors; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** | ||
| 194 | + * Returns remote node descriptors. | ||
| 195 | + * | ||
| 196 | + * @return remote node descriptors | ||
| 197 | + */ | ||
| 198 | + public NodeDescriptors remoteNodeDescriptors() { | ||
| 199 | + return this.remoteNodeDescriptors; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + /** | ||
| 203 | + * Returns link descriptors. | ||
| 204 | + * | ||
| 205 | + * @return link descriptors | ||
| 206 | + */ | ||
| 207 | + public List<BGPValueType> linkDescriptors() { | ||
| 208 | + return this.linkDescriptor; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + @Override | ||
| 212 | + public int hashCode() { | ||
| 213 | + return Objects.hash(linkDescriptor, localNodeDescriptors, remoteNodeDescriptors); | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + @Override | ||
| 217 | + public boolean equals(Object obj) { | ||
| 218 | + if (this == obj) { | ||
| 219 | + return true; | ||
| 220 | + } | ||
| 221 | + if (obj instanceof BGPLinkLSIdentifier) { | ||
| 222 | + int countObjSubTlv = 0; | ||
| 223 | + int countOtherSubTlv = 0; | ||
| 224 | + boolean isCommonSubTlv = true; | ||
| 225 | + BGPLinkLSIdentifier other = (BGPLinkLSIdentifier) obj; | ||
| 226 | + Iterator<BGPValueType> objListIterator = other.linkDescriptor.iterator(); | ||
| 227 | + countOtherSubTlv = other.linkDescriptor.size(); | ||
| 228 | + countObjSubTlv = linkDescriptor.size(); | ||
| 229 | + if (countObjSubTlv != countOtherSubTlv) { | ||
| 230 | + return false; | ||
| 231 | + } else { | ||
| 232 | + while (objListIterator.hasNext() && isCommonSubTlv) { | ||
| 233 | + BGPValueType subTlv = objListIterator.next(); | ||
| 234 | + isCommonSubTlv = Objects.equals(linkDescriptor.contains(subTlv), | ||
| 235 | + other.linkDescriptor.contains(subTlv)); | ||
| 236 | + } | ||
| 237 | + return isCommonSubTlv && Objects.equals(this.localNodeDescriptors, other.localNodeDescriptors) | ||
| 238 | + && Objects.equals(this.remoteNodeDescriptors, other.remoteNodeDescriptors); | ||
| 239 | + } | ||
| 240 | + } | ||
| 241 | + return false; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + @Override | ||
| 245 | + public String toString() { | ||
| 246 | + return MoreObjects.toStringHelper(getClass()) | ||
| 247 | + .add("localNodeDescriptors", localNodeDescriptors) | ||
| 248 | + .add("remoteNodeDescriptors", remoteNodeDescriptors) | ||
| 249 | + .add("linkDescriptor", linkDescriptor) | ||
| 250 | + .toString(); | ||
| 251 | + } | ||
| 252 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment