Priyanka B
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
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