blob: 6133ea0462064a6dc47bf0e6f07c579db091b499 [file] [log] [blame]
Jian Li99f83ef2016-11-03 19:14:25 +01001/*
2 * Copyright 2016-present 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 */
16package org.onosproject.lisp.msg.types;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Lists;
20import io.netty.buffer.ByteBuf;
21import org.onosproject.lisp.msg.exceptions.LispParseError;
22import org.onosproject.lisp.msg.exceptions.LispReaderException;
23import org.onosproject.lisp.msg.exceptions.LispWriterException;
24import org.onosproject.lisp.msg.types.LispTeRecord.TeRecordWriter;
25
26import java.util.List;
27import java.util.Objects;
28
29import static com.google.common.base.MoreObjects.toStringHelper;
30
31/**
32 * Traffic Engineering (TE) type LCAF address class.
33 * <p>
Jian Li89c9ca92016-11-11 04:09:02 +090034 * Traffic Engineering type is defined in draft-ietf-lisp-lcaf-20
35 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#page-16
36 *
Jian Li99f83ef2016-11-03 19:14:25 +010037 * <pre>
38 * {@literal
39 * 0 1 2 3
40 * 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
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | AFI = 16387 | Rsvd1 | Flags |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li89c9ca92016-11-11 04:09:02 +090044 * | Type = 10 | Rsvd2 | Length |
Jian Li99f83ef2016-11-03 19:14:25 +010045 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 * | Rsvd3 |L|P|S| AFI = x |
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * | Reencap Hop 1 ... |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * | Rsvd3 |L|P|S| AFI = x |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * | Reencap Hop k ... |
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 * }</pre>
55 */
56public final class LispTeLcafAddress extends LispLcafAddress {
57
58 private final List<LispTeRecord> records;
59
60 /**
61 * Initializes Traffic Engineering type LCAF address.
62 *
63 * @param records a collection of Re-encapsulated RLOC addresses
64 */
65 private LispTeLcafAddress(short length, List<LispTeRecord> records) {
66 super(LispCanonicalAddressFormatEnum.TRAFFIC_ENGINEERING, length);
67 this.records = records;
68 }
69
70 /**
71 * Obtains a collection of TE records.
72 *
73 * @return a collection of TE records
74 */
75 public List<LispTeRecord> getTeRecords() {
76 return ImmutableList.copyOf(records);
77 }
78
79 @Override
80 public int hashCode() {
81 return Objects.hash(records);
82 }
83
84 @Override
85 public boolean equals(Object obj) {
86 if (this == obj) {
87 return true;
88 }
89
90 if (obj instanceof LispTeLcafAddress) {
91 final LispTeLcafAddress other = (LispTeLcafAddress) obj;
92 return Objects.equals(records, other.records);
93 }
94 return false;
95 }
96
97 @Override
98 public String toString() {
99 return toStringHelper(this)
100 .add("TE records", records).toString();
101 }
102
103 public static final class TeAddressBuilder extends LcafAddressBuilder<TeAddressBuilder> {
104 private List<LispTeRecord> records;
105 private short length;
106 private static final int SIZE_OF_AFI_RECORD = 8;
107
108 /**
109 * Sets a collection of TE records.
110 *
111 * @param records a collection of TE records
112 * @return TeAddressBuilder object
113 */
114 public TeAddressBuilder withTeRecords(List<LispTeRecord> records) {
115 this.records = records;
116 this.length = (short) (records.size() * SIZE_OF_AFI_RECORD);
117 return this;
118 }
119
120 /**
121 * Builds LispTeLcafAddress instance.
122 *
123 * @return LispTeLcafAddress instance
124 */
125 public LispTeLcafAddress build() {
126 return new LispTeLcafAddress(length, records);
127 }
128
129 /**
130 * TE LCAF address reader class.
131 */
132 public static class TeLcafAddressReader implements LispAddressReader<LispTeLcafAddress> {
133
134 private static final int SIZE_OF_AFI_RECORD = 8;
135
136 @Override
137 public LispTeLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
138
139 LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
140
141 // TODO: for RTR RLOC is IPv4 only for now
142 int numOfRecords = lcafAddress.getLength() / SIZE_OF_AFI_RECORD;
143
144 List<LispTeRecord> teRecords = Lists.newArrayList();
145 for (int i = 0; i < numOfRecords; i++) {
146 teRecords.add(new LispTeRecord.TeRecordReader().readFrom(byteBuf));
147 }
148
149 return new TeAddressBuilder()
150 .withTeRecords(teRecords)
151 .build();
152 }
153 }
154
155 /**
156 * TE LCAF address writer class.
157 */
158 public static class TeLcafAddressWriter implements LispAddressWriter<LispTeLcafAddress> {
159
160 @Override
161 public void writeTo(ByteBuf byteBuf, LispTeLcafAddress address) throws LispWriterException {
162 LispLcafAddress.serializeCommon(byteBuf, address);
163
164 TeRecordWriter writer = new TeRecordWriter();
165
166 List<LispTeRecord> teRecords = address.getTeRecords();
167 for (int i = 0; i < teRecords.size(); i++) {
168 writer.writeTo(byteBuf, teRecords.get(i));
169 }
170 }
171 }
172 }
173}