blob: d8b047469f5cf759f765adc6ac2b605a17668cbb [file] [log] [blame]
/*
* Copyright 2015-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.routing.fpm.protocol;
import com.google.common.collect.ImmutableMap;
import org.onlab.packet.DeserializationException;
import java.nio.ByteBuffer;
import java.util.Map;
import static org.onlab.packet.PacketUtils.checkInput;
/**
* Route attribute header.
*/
public abstract class RouteAttribute {
public static final int ROUTE_ATTRIBUTE_HEADER_LENGTH = 4;
public static final int RTA_DST = 1;
public static final int RTA_OIF = 4;
public static final int RTA_GATEWAY = 5;
public static final int RTA_PRIORITY = 6;
private final int length;
private final int type;
private static final Map<Integer, RouteAttributeDecoder<?>> TYPE_DECODER_MAP
= ImmutableMap.<Integer, RouteAttributeDecoder<?>>builder()
.put(RTA_DST, RouteAttributeDst.decoder())
.put(RTA_OIF, RouteAttributeOif.decoder())
.put(RTA_GATEWAY, RouteAttributeGateway.decoder())
.put(RTA_PRIORITY, RouteAttributePriority.decoder())
.build();
/**
* Class constructor.
*
* @param length attribute length
* @param type attribute type
*/
protected RouteAttribute(int length, int type) {
this.length = length;
this.type = type;
}
/**
* Returns the attribute length.
*
* @return length
*/
public int length() {
return length;
}
/**
* Returns the attribute type.
*
* @return type
*/
public int type() {
return type;
}
@Override
public abstract String toString();
/**
* Decodes a route attribute from an input buffer.
*
* @param buffer input buffer
* @param start starting position the route attribute message
* @param length length of the message
* @return route attribute message
* @throws DeserializationException if a route attribute could not be
* decoded from the input buffer
*/
public static RouteAttribute decode(byte[] buffer, int start, int length)
throws DeserializationException {
checkInput(buffer, start, length, ROUTE_ATTRIBUTE_HEADER_LENGTH);
ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
int tlvLength = Short.reverseBytes(bb.getShort());
int type = Short.reverseBytes(bb.getShort());
if (bb.remaining() < tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH) {
throw new DeserializationException(
"Incorrect buffer size when decoding route attribute");
}
byte[] value = new byte[tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH];
bb.get(value);
RouteAttributeDecoder<?> decoder = TYPE_DECODER_MAP.get(type);
if (decoder == null) {
throw new DeserializationException(
"No decoder found for route attribute type " + type);
}
return decoder.decodeAttribute(tlvLength, type, value);
}
}