blob: d8b047469f5cf759f765adc6ac2b605a17668cbb [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.collect.ImmutableMap;
20import org.onlab.packet.DeserializationException;
21
22import java.nio.ByteBuffer;
23import java.util.Map;
24
25import static org.onlab.packet.PacketUtils.checkInput;
26
27/**
28 * Route attribute header.
29 */
30public abstract class RouteAttribute {
31
32 public static final int ROUTE_ATTRIBUTE_HEADER_LENGTH = 4;
33
34 public static final int RTA_DST = 1;
35 public static final int RTA_OIF = 4;
36 public static final int RTA_GATEWAY = 5;
37 public static final int RTA_PRIORITY = 6;
38
39 private final int length;
40 private final int type;
41
42 private static final Map<Integer, RouteAttributeDecoder<?>> TYPE_DECODER_MAP
43 = ImmutableMap.<Integer, RouteAttributeDecoder<?>>builder()
44 .put(RTA_DST, RouteAttributeDst.decoder())
45 .put(RTA_OIF, RouteAttributeOif.decoder())
46 .put(RTA_GATEWAY, RouteAttributeGateway.decoder())
47 .put(RTA_PRIORITY, RouteAttributePriority.decoder())
48 .build();
49
50 /**
51 * Class constructor.
52 *
53 * @param length attribute length
54 * @param type attribute type
55 */
56 protected RouteAttribute(int length, int type) {
57 this.length = length;
58 this.type = type;
59 }
60
61 /**
62 * Returns the attribute length.
63 *
64 * @return length
65 */
66 public int length() {
67 return length;
68 }
69
70 /**
71 * Returns the attribute type.
72 *
73 * @return type
74 */
75 public int type() {
76 return type;
77 }
78
79 @Override
80 public abstract String toString();
81
82 /**
83 * Decodes a route attribute from an input buffer.
84 *
85 * @param buffer input buffer
86 * @param start starting position the route attribute message
87 * @param length length of the message
88 * @return route attribute message
89 * @throws DeserializationException if a route attribute could not be
90 * decoded from the input buffer
91 */
92 public static RouteAttribute decode(byte[] buffer, int start, int length)
93 throws DeserializationException {
94 checkInput(buffer, start, length, ROUTE_ATTRIBUTE_HEADER_LENGTH);
95
96 ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
97
98 int tlvLength = Short.reverseBytes(bb.getShort());
99 int type = Short.reverseBytes(bb.getShort());
100
101 if (bb.remaining() < tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH) {
102 throw new DeserializationException(
103 "Incorrect buffer size when decoding route attribute");
104 }
105
106 byte[] value = new byte[tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH];
107 bb.get(value);
108
109 RouteAttributeDecoder<?> decoder = TYPE_DECODER_MAP.get(type);
110 if (decoder == null) {
111 throw new DeserializationException(
112 "No decoder found for route attribute type " + type);
113 }
114
115 return decoder.decodeAttribute(tlvLength, type, value);
116 }
117}