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.annotations.VisibleForTesting;
11 import com.google.common.primitives.UnsignedBytes;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.ByteBufUtil;
14 import io.netty.buffer.Unpooled;
15 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
16 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
17 import org.opendaylight.protocol.util.ByteArray;
18 import org.opendaylight.protocol.util.Ipv4Util;
19 import org.opendaylight.protocol.util.Ipv6Util;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.OspfRouteType;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.TopologyIdentifier;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptors;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptorsBuilder;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 public final class PrefixNlriParser {
31 private static final Logger LOG = LoggerFactory.getLogger(PrefixNlriParser.class);
33 private PrefixNlriParser() {
34 throw new UnsupportedOperationException();
37 /* Prefix Descriptor TLVs */
38 private static final int OSPF_ROUTE_TYPE = 264;
39 private static final int IP_REACHABILITY = 265;
41 static PrefixDescriptors parsePrefixDescriptors(final ByteBuf buffer, final boolean ipv4) throws BGPParsingException {
42 final PrefixDescriptorsBuilder builder = new PrefixDescriptorsBuilder();
43 while (buffer.isReadable()) {
44 final int type = buffer.readUnsignedShort();
45 final int length = buffer.readUnsignedShort();
46 final ByteBuf value = buffer.readSlice(length);
47 if (LOG.isTraceEnabled()) {
48 LOG.trace("Parsing Prefix Descriptor: {}", ByteBufUtil.hexDump(value));
51 case TlvUtil.MULTI_TOPOLOGY_ID:
52 final TopologyIdentifier topologyId = new TopologyIdentifier(value.readShort() & TlvUtil.TOPOLOGY_ID_OFFSET);
53 builder.setMultiTopologyId(topologyId);
54 LOG.trace("Parsed Topology Identifier: {}", topologyId);
57 final int rt = value.readByte();
58 final OspfRouteType routeType = OspfRouteType.forValue(rt);
59 if (routeType == null) {
60 throw new BGPParsingException("Unknown OSPF Route Type: " + rt);
62 builder.setOspfRouteType(routeType);
63 LOG.trace("Parser RouteType: {}", routeType);
66 IpPrefix prefix = null;
67 final int prefixLength = value.readByte();
68 final int size = prefixLength / Byte.SIZE + ((prefixLength % Byte.SIZE == 0) ? 0 : 1);
69 if (size != value.readableBytes()) {
70 LOG.debug("Expected length {}, actual length {}.", size, value.readableBytes());
71 throw new BGPParsingException("Illegal length of IP reachability TLV: " + (value.readableBytes()));
73 prefix = (ipv4) ? new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.readBytes(value, size), prefixLength)):
74 new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.readBytes(value, size), prefixLength));
75 builder.setIpReachabilityInformation(prefix);
76 LOG.trace("Parsed IP reachability info: {}", prefix);
79 throw new BGPParsingException("Prefix Descriptor not recognized, type: " + type);
82 LOG.debug("Finished parsing Prefix descriptors.");
83 return builder.build();
86 static void serializePrefixDescriptors(final PrefixDescriptors descriptors, final ByteBuf buffer) {
87 if (descriptors.getMultiTopologyId() != null) {
88 TlvUtil.writeTLV(TlvUtil.MULTI_TOPOLOGY_ID, Unpooled.copyShort(descriptors.getMultiTopologyId().getValue()), buffer);
90 if (descriptors.getOspfRouteType() != null) {
91 TlvUtil.writeTLV(OSPF_ROUTE_TYPE,
92 Unpooled.wrappedBuffer(new byte[] {UnsignedBytes.checkedCast(descriptors.getOspfRouteType().getIntValue()) }), buffer);
94 if (descriptors.getIpReachabilityInformation() != null) {
95 final IpPrefix prefix = descriptors.getIpReachabilityInformation();
96 byte[] prefixBytes = null;
97 if (prefix.getIpv4Prefix() != null) {
98 prefixBytes = Ipv4Util.bytesForPrefixBegin(prefix.getIpv4Prefix());
99 } else if (prefix.getIpv6Prefix() != null) {
100 prefixBytes = Ipv6Util.bytesForPrefixBegin(prefix.getIpv6Prefix());
102 TlvUtil.writeTLV(IP_REACHABILITY, Unpooled.wrappedBuffer(prefixBytes), buffer);