blob: c3cf65accdb34f090f538451d3fb397508ee8891 [file] [log] [blame]
Jonathan Hart3930f632015-10-19 12:12:51 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
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;
26
27import static org.onlab.packet.PacketUtils.checkInput;
28
29/**
30 * Netlink routing message (rtnetlink).
31 * <p>
32 * Taken from struct rtmsg in linux/rtnetlink.h
33 * </p>
34 */
35public final class RtNetlink {
36
37 private static final int RT_NETLINK_LENGTH = 12;
38
39 private static final int MASK = 0xff;
40
41 private final short addressFamily;
42 private final int dstLength;
43 private final int srcLength;
44 private final short tos;
45 private final short table;
Jonathan Hart916bf892016-01-27 16:42:55 -080046 private final RtProtocol protocol;
Jonathan Hart3930f632015-10-19 12:12:51 -070047 private final short scope;
48 private final short type;
49 private final long flags;
50
51 private final List<RouteAttribute> attributes;
52
53 /**
54 * Class constructor.
55 *
56 * @param addressFamily address family
57 * @param dstLength destination address length
58 * @param srcLength source address length
59 * @param tos type of service
60 * @param table routing table
61 * @param protocol protocol
62 * @param scope scope
63 * @param type type
64 * @param flags flags
65 * @param attributes list of attributes
66 */
67 private RtNetlink(short addressFamily,
68 int dstLength,
69 int srcLength,
70 short tos,
71 short table,
Jonathan Hart916bf892016-01-27 16:42:55 -080072 RtProtocol protocol,
Jonathan Hart3930f632015-10-19 12:12:51 -070073 short scope,
74 short type,
75 long flags,
76 List<RouteAttribute> attributes) {
77
78 this.addressFamily = addressFamily;
79 this.dstLength = dstLength;
80 this.srcLength = srcLength;
81 this.tos = tos;
82 this.table = table;
83 this.protocol = protocol;
84 this.scope = scope;
85 this.type = type;
86 this.flags = flags;
87
88 this.attributes = ImmutableList.copyOf(attributes);
89
90 }
91
92 /**
93 * Returns the address family of the route.
94 *
95 * @return address family
96 */
97 public short addressFamily() {
98 return addressFamily;
99 }
100
101 /**
102 * Returns the destination address length.
103 *
104 * @return destination address length
105 */
106 public int dstLength() {
107 return dstLength;
108 }
109
110 /**
111 * Returns the source address length.
112 *
113 * @return source address length
114 */
115 public int srcLength() {
116 return srcLength;
117 }
118
119 /**
120 * Returns the type of service.
121 *
122 * @return type of service
123 */
124 public short tos() {
125 return tos;
126 }
127
128 /**
129 * Returns the routing table.
130 *
131 * @return routing table
132 */
133 public short table() {
134 return table;
135 }
136
137 /**
138 * Returns the protocol.
139 *
140 * @return protocol
141 */
Jonathan Hart916bf892016-01-27 16:42:55 -0800142 public RtProtocol protocol() {
Jonathan Hart3930f632015-10-19 12:12:51 -0700143 return protocol;
144 }
145
146 /**
147 * Returns the route scope.
148 *
149 * @return scope
150 */
151 public short scope() {
152 return scope;
153 }
154
155 /**
156 * Returns the route type.
157 *
158 * @return route type
159 */
160 public short type() {
161 return type;
162 }
163
164 /**
165 * Returns the route flags.
166 *
167 * @return route flags
168 */
169 public long flags() {
170 return flags;
171 }
172
173 /**
174 * Returns the list of route attributes.
175 *
176 * @return route attributes
177 */
178 public List<RouteAttribute> attributes() {
179 return attributes;
180 }
181
182 @Override
183 public String toString() {
184 return MoreObjects.toStringHelper(getClass())
185 .add("addressFamily", addressFamily)
186 .add("dstLength", dstLength)
187 .add("srcLength", srcLength)
188 .add("tos", tos)
189 .add("table", table)
190 .add("protocol", protocol)
191 .add("scope", scope)
192 .add("type", type)
193 .add("flags", flags)
194 .add("attributes", attributes)
195 .toString();
196 }
197
198 /**
199 * Decodes an rtnetlink message from an input buffer.
200 *
201 * @param buffer input buffer
202 * @param start starting position the rtnetlink message
203 * @param length length of the message
204 * @return rtnetlink message
205 * @throws DeserializationException if an rtnetlink message could not be
206 * decoded from the input buffer
207 */
208 public static RtNetlink decode(byte[] buffer, int start, int length)
209 throws DeserializationException {
210 checkInput(buffer, start, length, RT_NETLINK_LENGTH);
211
212 ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
213
214 short addressFamily = (short) (bb.get() & MASK);
215 int dstLength = bb.get() & MASK;
216 int srcLength = bb.get() & MASK;
217 short tos = (short) (bb.get() & MASK);
218 short table = (short) (bb.get() & MASK);
219 short protocol = (short) (bb.get() & MASK);
220 short scope = (short) (bb.get() & MASK);
221 short type = (short) (bb.get() & MASK);
222 long flags = Integer.reverseBytes(bb.getInt());
223 List<RouteAttribute> attributes = new ArrayList<>();
224
Jonathan Hart916bf892016-01-27 16:42:55 -0800225 RtProtocol rtProtocol = RtProtocol.get(protocol);
226
Jonathan Hart3930f632015-10-19 12:12:51 -0700227 while (bb.hasRemaining()) {
228 RouteAttribute attribute = RouteAttribute.decode(buffer, bb.position(),
229 bb.limit() - bb.position());
230 attributes.add(attribute);
231 bb.position(bb.position() + attribute.length());
232 }
233
234 return new RtNetlink(
235 addressFamily,
236 dstLength,
237 srcLength,
238 tos,
239 table,
Jonathan Hart916bf892016-01-27 16:42:55 -0800240 rtProtocol,
Jonathan Hart3930f632015-10-19 12:12:51 -0700241 scope,
242 type,
243 flags,
244 attributes);
245 }
246
247}