blob: 90176186dbcb3352233b4264034cf8d384069171 [file] [log] [blame]
/*
* Copyright 2016 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.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import org.onlab.packet.DeserializationException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import static org.onlab.packet.PacketUtils.checkInput;
/**
* Netlink routing message (rtnetlink).
* <p>
* Taken from struct rtmsg in linux/rtnetlink.h
* </p>
*/
public final class RtNetlink {
private static final int RT_NETLINK_LENGTH = 12;
private static final int MASK = 0xff;
private final short addressFamily;
private final int dstLength;
private final int srcLength;
private final short tos;
private final short table;
private final RtProtocol protocol;
private final short scope;
private final short type;
private final long flags;
private final List<RouteAttribute> attributes;
/**
* Class constructor.
*
* @param addressFamily address family
* @param dstLength destination address length
* @param srcLength source address length
* @param tos type of service
* @param table routing table
* @param protocol protocol
* @param scope scope
* @param type type
* @param flags flags
* @param attributes list of attributes
*/
private RtNetlink(short addressFamily,
int dstLength,
int srcLength,
short tos,
short table,
RtProtocol protocol,
short scope,
short type,
long flags,
List<RouteAttribute> attributes) {
this.addressFamily = addressFamily;
this.dstLength = dstLength;
this.srcLength = srcLength;
this.tos = tos;
this.table = table;
this.protocol = protocol;
this.scope = scope;
this.type = type;
this.flags = flags;
this.attributes = ImmutableList.copyOf(attributes);
}
/**
* Returns the address family of the route.
*
* @return address family
*/
public short addressFamily() {
return addressFamily;
}
/**
* Returns the destination address length.
*
* @return destination address length
*/
public int dstLength() {
return dstLength;
}
/**
* Returns the source address length.
*
* @return source address length
*/
public int srcLength() {
return srcLength;
}
/**
* Returns the type of service.
*
* @return type of service
*/
public short tos() {
return tos;
}
/**
* Returns the routing table.
*
* @return routing table
*/
public short table() {
return table;
}
/**
* Returns the protocol.
*
* @return protocol
*/
public RtProtocol protocol() {
return protocol;
}
/**
* Returns the route scope.
*
* @return scope
*/
public short scope() {
return scope;
}
/**
* Returns the route type.
*
* @return route type
*/
public short type() {
return type;
}
/**
* Returns the route flags.
*
* @return route flags
*/
public long flags() {
return flags;
}
/**
* Returns the list of route attributes.
*
* @return route attributes
*/
public List<RouteAttribute> attributes() {
return attributes;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("addressFamily", addressFamily)
.add("dstLength", dstLength)
.add("srcLength", srcLength)
.add("tos", tos)
.add("table", table)
.add("protocol", protocol)
.add("scope", scope)
.add("type", type)
.add("flags", flags)
.add("attributes", attributes)
.toString();
}
/**
* Decodes an rtnetlink message from an input buffer.
*
* @param buffer input buffer
* @param start starting position the rtnetlink message
* @param length length of the message
* @return rtnetlink message
* @throws DeserializationException if an rtnetlink message could not be
* decoded from the input buffer
*/
public static RtNetlink decode(byte[] buffer, int start, int length)
throws DeserializationException {
checkInput(buffer, start, length, RT_NETLINK_LENGTH);
ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);
short addressFamily = (short) (bb.get() & MASK);
int dstLength = bb.get() & MASK;
int srcLength = bb.get() & MASK;
short tos = (short) (bb.get() & MASK);
short table = (short) (bb.get() & MASK);
short protocol = (short) (bb.get() & MASK);
short scope = (short) (bb.get() & MASK);
short type = (short) (bb.get() & MASK);
long flags = Integer.reverseBytes(bb.getInt());
List<RouteAttribute> attributes = new ArrayList<>();
RtProtocol rtProtocol = RtProtocol.get(protocol);
while (bb.hasRemaining()) {
RouteAttribute attribute = RouteAttribute.decode(buffer, bb.position(),
bb.limit() - bb.position());
attributes.add(attribute);
bb.position(bb.position() + attribute.length());
}
return new RtNetlink(
addressFamily,
dstLength,
srcLength,
tos,
table,
rtProtocol,
scope,
type,
flags,
attributes);
}
}