blob: adaaf622b912c230077dee00b877cad68ebe9497 [file] [log] [blame]
Jonathan Hart3930f632015-10-19 12:12:51 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Jonathan Hart3930f632015-10-19 12:12:51 -07003 *
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
17package org.onosproject.routing.fpm.protocol;
18
19import com.google.common.base.MoreObjects;
20import com.google.common.collect.ImmutableList;
21import org.onlab.packet.DeserializationException;
22
23import java.nio.ByteBuffer;
24import java.util.ArrayList;
25import java.util.List;
Kalhee Kimba366062017-11-07 16:32:09 +000026import org.jboss.netty.buffer.ChannelBuffer;
Jonathan Hart3930f632015-10-19 12:12:51 -070027
28import static org.onlab.packet.PacketUtils.checkInput;
29
30/**
31 * Netlink routing message (rtnetlink).
32 * <p>
33 * Taken from struct rtmsg in linux/rtnetlink.h
34 * </p>
35 */
36public final class RtNetlink {
37
Kalhee Kimba366062017-11-07 16:32:09 +000038 public static final int RT_ADDRESS_FAMILY_INET = 2;
39 public static final int RT_ADDRESS_FAMILY_INET6 = 10;
40 public static final int RT_NETLINK_LENGTH = 12;
Jonathan Hart3930f632015-10-19 12:12:51 -070041
42 private static final int MASK = 0xff;
43
44 private final short addressFamily;
45 private final int dstLength;
46 private final int srcLength;
47 private final short tos;
48 private final short table;
Jonathan Hart916bf892016-01-27 16:42:55 -080049 private final RtProtocol protocol;
Jonathan Hart3930f632015-10-19 12:12:51 -070050 private final short scope;
51 private final short type;
52 private final long flags;
53
54 private final List<RouteAttribute> attributes;
55
56 /**
57 * Class constructor.
58 *
59 * @param addressFamily address family
60 * @param dstLength destination address length
61 * @param srcLength source address length
62 * @param tos type of service
63 * @param table routing table
64 * @param protocol protocol
65 * @param scope scope
66 * @param type type
67 * @param flags flags
68 * @param attributes list of attributes
69 */
Kalhee Kimba366062017-11-07 16:32:09 +000070 public RtNetlink(short addressFamily,
Jonathan Hart3930f632015-10-19 12:12:51 -070071 int dstLength,
72 int srcLength,
73 short tos,
74 short table,
Jonathan Hart916bf892016-01-27 16:42:55 -080075 RtProtocol protocol,
Jonathan Hart3930f632015-10-19 12:12:51 -070076 short scope,
77 short type,
78 long flags,
79 List<RouteAttribute> attributes) {
80
81 this.addressFamily = addressFamily;
82 this.dstLength = dstLength;
83 this.srcLength = srcLength;
84 this.tos = tos;
85 this.table = table;
86 this.protocol = protocol;
87 this.scope = scope;
88 this.type = type;
89 this.flags = flags;
90
91 this.attributes = ImmutableList.copyOf(attributes);
92
93 }
94
95 /**
96 * Returns the address family of the route.
97 *
98 * @return address family
99 */
100 public short addressFamily() {
101 return addressFamily;
102 }
103
104 /**
105 * Returns the destination address length.
106 *
107 * @return destination address length
108 */
109 public int dstLength() {
110 return dstLength;
111 }
112
113 /**
114 * Returns the source address length.
115 *
116 * @return source address length
117 */
118 public int srcLength() {
119 return srcLength;
120 }
121
122 /**
123 * Returns the type of service.
124 *
125 * @return type of service
126 */
127 public short tos() {
128 return tos;
129 }
130
131 /**
132 * Returns the routing table.
133 *
134 * @return routing table
135 */
136 public short table() {
137 return table;
138 }
139
140 /**
141 * Returns the protocol.
142 *
143 * @return protocol
144 */
Jonathan Hart916bf892016-01-27 16:42:55 -0800145 public RtProtocol protocol() {
Jonathan Hart3930f632015-10-19 12:12:51 -0700146 return protocol;
147 }
148
149 /**
150 * Returns the route scope.
151 *
152 * @return scope
153 */
154 public short scope() {
155 return scope;
156 }
157
158 /**
159 * Returns the route type.
160 *
161 * @return route type
162 */
163 public short type() {
164 return type;
165 }
166
167 /**
168 * Returns the route flags.
169 *
170 * @return route flags
171 */
172 public long flags() {
173 return flags;
174 }
175
176 /**
177 * Returns the list of route attributes.
178 *
179 * @return route attributes
180 */
181 public List<RouteAttribute> attributes() {
182 return attributes;
183 }
184
185 @Override
186 public String toString() {
187 return MoreObjects.toStringHelper(getClass())
188 .add("addressFamily", addressFamily)
189 .add("dstLength", dstLength)
190 .add("srcLength", srcLength)
191 .add("tos", tos)
192 .add("table", table)
193 .add("protocol", protocol)
194 .add("scope", scope)
195 .add("type", type)
196 .add("flags", flags)
197 .add("attributes", attributes)
198 .toString();
199 }
200
201 /**
202 * Decodes an rtnetlink message from an input buffer.
203 *
204 * @param buffer input buffer
205 * @param start starting position the rtnetlink message
206 * @param length length of the message
207 * @return rtnetlink message
208 * @throws DeserializationException if an rtnetlink message could not be
209 * decoded from the input buffer
210 */
211 public static RtNetlink decode(byte[] buffer, int start, int length)
212 throws DeserializationException {
213 checkInput(buffer, start, length, RT_NETLINK_LENGTH);
214
215 ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
216
217 short addressFamily = (short) (bb.get() & MASK);
218 int dstLength = bb.get() & MASK;
219 int srcLength = bb.get() & MASK;
220 short tos = (short) (bb.get() & MASK);
221 short table = (short) (bb.get() & MASK);
222 short protocol = (short) (bb.get() & MASK);
223 short scope = (short) (bb.get() & MASK);
224 short type = (short) (bb.get() & MASK);
225 long flags = Integer.reverseBytes(bb.getInt());
226 List<RouteAttribute> attributes = new ArrayList<>();
227
Jonathan Hart916bf892016-01-27 16:42:55 -0800228 RtProtocol rtProtocol = RtProtocol.get(protocol);
229
Jonathan Hart3930f632015-10-19 12:12:51 -0700230 while (bb.hasRemaining()) {
231 RouteAttribute attribute = RouteAttribute.decode(buffer, bb.position(),
232 bb.limit() - bb.position());
233 attributes.add(attribute);
234 bb.position(bb.position() + attribute.length());
235 }
236
237 return new RtNetlink(
238 addressFamily,
239 dstLength,
240 srcLength,
241 tos,
242 table,
Jonathan Hart916bf892016-01-27 16:42:55 -0800243 rtProtocol,
Jonathan Hart3930f632015-10-19 12:12:51 -0700244 scope,
245 type,
246 flags,
247 attributes);
248 }
249
Kalhee Kimba366062017-11-07 16:32:09 +0000250
251 /**
252 * Encode the RtNetlink contents into the ChannelBuffer.
253 *
254 * @param cb channelbuffer to be filled in
255 */
256 public void encode(ChannelBuffer cb) {
257
258 cb.writeByte(addressFamily);
259 cb.writeByte(dstLength);
260 cb.writeByte(srcLength);
261 cb.writeByte(tos);
262 cb.writeByte(table);
263 cb.writeByte(protocol.value());
264 cb.writeByte(scope);
265 cb.writeByte(type);
266 cb.writeInt(Integer.reverseBytes((int) flags));
267
268 for (RouteAttribute attribute : attributes()) {
269 attribute.encode(cb);
270 }
271 }
272
Jonathan Hart3930f632015-10-19 12:12:51 -0700273}