7fb1b316b58a453d8990aeb84361dd460ea0fe66
[onosfw.git] /
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
17 package org.onosproject.bgpio.protocol.linkstate;
18
19 import java.util.Iterator;
20 import java.util.LinkedList;
21 import java.util.List;
22 import java.util.ListIterator;
23 import java.util.Objects;
24
25 import org.jboss.netty.buffer.ChannelBuffer;
26 import org.onosproject.bgpio.exceptions.BgpParseException;
27 import org.onosproject.bgpio.types.AreaIDTlv;
28 import org.onosproject.bgpio.types.AutonomousSystemTlv;
29 import org.onosproject.bgpio.types.BgpErrorType;
30 import org.onosproject.bgpio.types.BgpLSIdentifierTlv;
31 import org.onosproject.bgpio.types.BgpValueType;
32 import org.onosproject.bgpio.types.IsIsNonPseudonode;
33 import org.onosproject.bgpio.types.IsIsPseudonode;
34 import org.onosproject.bgpio.types.OSPFNonPseudonode;
35 import org.onosproject.bgpio.types.OSPFPseudonode;
36 import org.onosproject.bgpio.util.UnSupportedAttribute;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import com.google.common.base.MoreObjects;
41
42 /**
43  * Provides Local and Remote NodeDescriptors which contains Node Descriptor Sub-TLVs.
44  */
45 public class NodeDescriptors {
46
47     /*
48      *Reference :draft-ietf-idr-ls-distribution-11
49           0                   1                   2                   3
50           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
51          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52          |              Type             |             Length            |
53          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54          |                                                               |
55          //              Node Descriptor Sub-TLVs (variable)            //
56          |                                                               |
57          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58
59                    Figure : Local or Remote Node Descriptors TLV format
60      */
61
62     private static final Logger log = LoggerFactory.getLogger(NodeDescriptors.class);
63
64     public static final short LOCAL_NODE_DES_TYPE = 256;
65     public static final short REMOTE_NODE_DES_TYPE = 257;
66     public static final short IGP_ROUTERID_TYPE = 515;
67     public static final short IS_IS_LEVEL_1_PROTOCOL_ID = 1;
68     public static final short IS_IS_LEVEL_2_PROTOCOL_ID = 2;
69     public static final short OSPF_V2_PROTOCOL_ID = 3;
70     public static final short OSPF_V3_PROTOCOL_ID = 6;
71     public static final int TYPE_AND_LEN = 4;
72     public static final int ISISNONPSEUDONODE_LEN = 6;
73     public static final int ISISPSEUDONODE_LEN = 7;
74     public static final int OSPFNONPSEUDONODE_LEN = 4;
75     public static final int OSPFPSEUDONODE_LEN = 8;
76     private List<BgpValueType> subTlvs;
77     private short deslength;
78     private short desType;
79
80     /**
81      * Resets parameters.
82      */
83     public NodeDescriptors() {
84         this.subTlvs = null;
85         this.deslength = 0;
86         this.desType = 0;
87     }
88
89     /**
90      * Constructor to initialize parameters.
91      *
92      * @param subTlvs list of subTlvs
93      * @param deslength Descriptors length
94      * @param desType local node descriptor or remote node descriptor type
95      */
96     public NodeDescriptors(List<BgpValueType> subTlvs, short deslength, short desType) {
97         this.subTlvs = subTlvs;
98         this.deslength = deslength;
99         this.desType = desType;
100     }
101
102     /**
103      * Returns list of subTlvs.
104      *
105      * @return subTlvs list of subTlvs
106      */
107     public List<BgpValueType> getSubTlvs() {
108         return subTlvs;
109     }
110
111     @Override
112     public int hashCode() {
113         return Objects.hash(subTlvs.hashCode());
114     }
115
116     @Override
117     public boolean equals(Object obj) {
118         if (this == obj) {
119             return true;
120         }
121
122         if (obj instanceof NodeDescriptors) {
123             int countObjSubTlv = 0;
124             int countOtherSubTlv = 0;
125             boolean isCommonSubTlv = true;
126             NodeDescriptors other = (NodeDescriptors) obj;
127             Iterator<BgpValueType> objListIterator = other.subTlvs.iterator();
128             countOtherSubTlv = other.subTlvs.size();
129             countObjSubTlv = subTlvs.size();
130             if (countObjSubTlv != countOtherSubTlv) {
131                 return false;
132             } else {
133                 while (objListIterator.hasNext() && isCommonSubTlv) {
134                     BgpValueType subTlv = objListIterator.next();
135                     if (subTlvs.contains(subTlv) && other.subTlvs.contains(subTlv)) {
136                         isCommonSubTlv = Objects.equals(subTlvs.get(subTlvs.indexOf(subTlv)),
137                                          other.subTlvs.get(other.subTlvs.indexOf(subTlv)));
138                     } else {
139                         isCommonSubTlv = false;
140                     }
141                 }
142                 return isCommonSubTlv;
143             }
144         }
145         return false;
146     }
147
148     /**
149      * Reads node descriptors Sub-TLVs.
150      *
151      * @param cb ChannelBuffer
152      * @param desLength node descriptor length
153      * @param desType local node descriptor or remote node descriptor type
154      * @param protocolId protocol ID
155      * @return object of NodeDescriptors
156      * @throws BgpParseException while parsing node descriptors
157      */
158     public static NodeDescriptors read(ChannelBuffer cb, short desLength, short desType, byte protocolId)
159             throws BgpParseException {
160         log.debug("Read NodeDescriptor");
161         List<BgpValueType> subTlvs = new LinkedList<>();
162         BgpValueType tlv = null;
163
164         while (cb.readableBytes() > 0) {
165             ChannelBuffer tempBuf = cb.copy();
166             short type = cb.readShort();
167             short length = cb.readShort();
168             if (cb.readableBytes() < length) {
169                 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.OPTIONAL_ATTRIBUTE_ERROR,
170                         tempBuf.readBytes(cb.readableBytes() + TYPE_AND_LEN));
171             }
172             ChannelBuffer tempCb = cb.readBytes(length);
173             switch (type) {
174             case AutonomousSystemTlv.TYPE:
175                 tlv = AutonomousSystemTlv.read(tempCb);
176                 break;
177             case BgpLSIdentifierTlv.TYPE:
178                 tlv = BgpLSIdentifierTlv.read(tempCb);
179                 break;
180             case AreaIDTlv.TYPE:
181                 tlv = AreaIDTlv.read(tempCb);
182                 break;
183             case IGP_ROUTERID_TYPE:
184                 if (protocolId == IS_IS_LEVEL_1_PROTOCOL_ID || protocolId == IS_IS_LEVEL_2_PROTOCOL_ID) {
185                     if (length == ISISNONPSEUDONODE_LEN) {
186                         tlv = IsIsNonPseudonode.read(tempCb);
187                     } else if (length == ISISPSEUDONODE_LEN) {
188                         tlv = IsIsPseudonode.read(tempCb);
189                     }
190                 } else if (protocolId == OSPF_V2_PROTOCOL_ID || protocolId == OSPF_V3_PROTOCOL_ID) {
191                     if (length == OSPFNONPSEUDONODE_LEN) {
192                         tlv = OSPFNonPseudonode.read(tempCb);
193                     } else if (length == OSPFPSEUDONODE_LEN) {
194                         tlv = OSPFPseudonode.read(tempCb);
195                     }
196                 }
197                 break;
198             default:
199                 UnSupportedAttribute.skipBytes(tempCb, length);
200             }
201             subTlvs.add(tlv);
202         }
203         return new NodeDescriptors(subTlvs, desLength, desType);
204     }
205
206     /**
207      * Returns node descriptors length.
208      *
209      * @return node descriptors length
210      */
211     public short getLength() {
212         return this.deslength;
213     }
214
215     /**
216      * Returns node descriptors type.
217      *
218      * @return node descriptors type
219      */
220     public short getType() {
221         return this.desType;
222     }
223
224     @Override
225     public String toString() {
226         return MoreObjects.toStringHelper(getClass())
227                 .add("desType", desType)
228                 .add("deslength", deslength)
229                 .add("subTlvs", subTlvs)
230                 .toString();
231     }
232
233     public int compareTo(Object o) {
234         if (this.equals(o)) {
235             return 0;
236         }
237         ListIterator<BgpValueType> listIterator = subTlvs.listIterator();
238         ListIterator<BgpValueType> listIteratorOther = ((NodeDescriptors) o).subTlvs.listIterator();
239         int countOtherSubTlv = ((NodeDescriptors) o).subTlvs.size();
240         int countObjSubTlv = subTlvs.size();
241         if (countOtherSubTlv != countObjSubTlv) {
242              if (countOtherSubTlv > countObjSubTlv) {
243                  return 1;
244              } else {
245                  return -1;
246              }
247         } else {
248             while (listIterator.hasNext()) {
249             BgpValueType tlv = listIterator.next();
250                 BgpValueType tlv1 = listIteratorOther.next();
251                 if (subTlvs.contains(tlv) && ((NodeDescriptors) o).subTlvs.contains(tlv1)) {
252                     int result = subTlvs.get(subTlvs.indexOf(tlv)).compareTo(
253                             ((NodeDescriptors) o).subTlvs.get(((NodeDescriptors) o).subTlvs.indexOf(tlv1)));
254                     if (result != 0) {
255                         return result;
256                     }
257                 }
258             }
259         }
260         return 0;
261     }
262 }