2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.linkstate.nlri;
10 import com.google.common.primitives.UnsignedBytes;
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.ByteBufUtil;
13 import io.netty.buffer.Unpooled;
14 import org.opendaylight.protocol.bgp.linkstate.TlvUtil;
15 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
16 import org.opendaylight.protocol.util.ByteArray;
17 import org.opendaylight.protocol.util.Ipv4Util;
18 import org.opendaylight.protocol.util.Ipv6Util;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.OspfRouteType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.c.linkstate.destination.PrefixDescriptors;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.c.linkstate.destination.PrefixDescriptorsBuilder;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 final class PrefixNlriParser {
29 private static final Logger LOG = LoggerFactory.getLogger(PrefixNlriParser.class);
31 /* Prefix Descriptor TLVs */
32 private static final int OSPF_ROUTE_TYPE = 264;
33 private static final int IP_REACHABILITY = 265;
35 static PrefixDescriptors parsePrefixDescriptors(final ByteBuf buffer, final boolean ipv4) throws BGPParsingException {
36 final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
37 while (buffer.isReadable()) {
38 final int type = buffer.readUnsignedShort();
39 final int length = buffer.readUnsignedShort();
40 final ByteBuf value = buffer.slice(buffer.readerIndex(), length);
41 if (LOG.isTraceEnabled()) {
42 LOG.trace("Parsing Prefix Descriptor: {}", ByteBufUtil.hexDump(value));
45 case TlvUtil.MULTI_TOPOLOGY_ID:
46 final TopologyIdentifier topologyId = new TopologyIdentifier(value.readShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
47 builder.setMultiTopologyId(topologyId);
48 LOG.trace("Parsed Topology Identifier: {}", topologyId);
51 final int rt = value.readByte();
52 final OspfRouteType routeType = OspfRouteType.forValue(rt);
53 if (routeType == null) {
54 throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
56 builder.setOspfRouteType(routeType);
57 LOG.trace("Parser RouteType: {}", routeType);
60 IpPrefix prefix = null;
61 final int prefixLength = value.readByte();
62 final int size = prefixLength / Byte.SIZE + ((prefixLength % Byte.SIZE == 0) ? 0 : 1);
63 if (size != value.readableBytes()) {
64 LOG.debug("Expected length {}, actual length {}.", size, value.readableBytes());
65 throw new BGPParsingException("Illegal length of IP reachability TLV: " + (value.readableBytes()));
67 prefix = (ipv4) ? new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.readBytes(value, size), prefixLength)):
68 new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.readBytes(value, size), prefixLength));
69 builder.setIpReachabilityInformation(prefix);
70 LOG.trace("Parsed IP reachability info: {}", prefix);
73 throw new BGPParsingException("Prefix Descriptor not recognized, type: " + type);
75 buffer.skipBytes(length);
77 LOG.debug("Finished parsing Prefix descriptors.");
78 return builder.build();
81 static void serializePrefixDescriptors(final PrefixDescriptors descriptors, final ByteBuf buffer) {
82 if (descriptors.getMultiTopologyId() != null) {
83 TlvUtil.writeTLV(TlvUtil.MULTI_TOPOLOGY_ID, Unpooled.copyShort(descriptors.getMultiTopologyId().getValue()), buffer);
85 if (descriptors.getOspfRouteType() != null) {
86 TlvUtil.writeTLV(OSPF_ROUTE_TYPE,
87 Unpooled.wrappedBuffer(new byte[] {UnsignedBytes.checkedCast(descriptors.getOspfRouteType().getIntValue()) }), buffer);
89 if (descriptors.getIpReachabilityInformation() != null) {
90 final IpPrefix prefix = descriptors.getIpReachabilityInformation();
91 byte[] prefixBytes = null;
92 if (prefix.getIpv4Prefix() != null) {
93 prefixBytes = Ipv4Util.bytesForPrefixBegin(prefix.getIpv4Prefix());
94 } else if (prefix.getIpv6Prefix() != null) {
95 prefixBytes = Ipv6Util.bytesForPrefixBegin(prefix.getIpv6Prefix());
97 TlvUtil.writeTLV(IP_REACHABILITY, Unpooled.wrappedBuffer(prefixBytes), buffer);