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.attribute;
10 import com.google.common.collect.Multimap;
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.ByteBufUtil;
13 import io.netty.buffer.Unpooled;
14 import java.util.ArrayList;
15 import java.util.BitSet;
16 import java.util.List;
17 import java.util.Map.Entry;
18 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
19 import org.opendaylight.protocol.util.ByteArray;
20 import org.opendaylight.protocol.util.Ipv4Util;
21 import org.opendaylight.protocol.util.Ipv6Util;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ExtendedRouteTag;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.IgpBits.UpDown;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.RouteTag;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.prefix.state.IgpBitsBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.LinkStateAttribute;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.PrefixAttributesCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributes;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.path.attributes.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributesBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IgpMetric;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 final class PrefixAttributesParser {
38 private static final Logger LOG = LoggerFactory.getLogger(PrefixAttributesParser.class);
40 private static final int ROUTE_TAG_LENGTH = 4;
41 private static final int EXTENDED_ROUTE_TAG_LENGTH = 8;
42 private static final int UP_DOWN_BIT = 7;
44 /* Prefix Attribute TLVs */
45 private static final int IGP_FLAGS = 1152;
46 private static final int ROUTE_TAG = 1153;
47 private static final int EXTENDED_ROUTE_TAG = 1154;
48 private static final int PREFIX_METRIC = 1155;
49 private static final int FORWARDING_ADDRESS = 1156;
50 private static final int PREFIX_OPAQUE = 1157;
53 * Parse prefix attributes.
55 * @param attributes key is the tlv type and value are the value bytes of the tlv
56 * @return {@link LinkStateAttribute}
58 static LinkStateAttribute parsePrefixAttributes(final Multimap<Integer, ByteBuf> attributes) {
59 final PrefixAttributesBuilder builder = new PrefixAttributesBuilder();
60 final List<RouteTag> routeTags = new ArrayList<>();
61 final List<ExtendedRouteTag> exRouteTags = new ArrayList<>();
62 for (final Entry<Integer, ByteBuf> entry : attributes.entries()) {
63 final int key = entry.getKey();
64 final ByteBuf value = entry.getValue();
65 LOG.trace("Prefix attribute TLV {}", key);
68 final BitSet flags = BitSet.valueOf(ByteArray.readAllBytes(value));
69 final boolean upDownBit = flags.get(UP_DOWN_BIT);
70 builder.setIgpBits(new IgpBitsBuilder().setUpDown(new UpDown(upDownBit)).build());
71 LOG.debug("Parsed IGP flag (up/down bit) : {}", upDownBit);
74 while (value.isReadable()) {
75 final RouteTag routeTag = new RouteTag(ByteArray.readBytes(value, ROUTE_TAG_LENGTH));
76 routeTags.add(routeTag);
77 LOG.debug("Parsed Route Tag: {}", routeTag);
80 case EXTENDED_ROUTE_TAG:
81 while (value.isReadable()) {
82 final ExtendedRouteTag exRouteTag = new ExtendedRouteTag(ByteArray.readBytes(value, EXTENDED_ROUTE_TAG_LENGTH));
83 exRouteTags.add(exRouteTag);
84 LOG.debug("Parsed Extended Route Tag: {}", exRouteTag);
88 final IgpMetric metric = new IgpMetric(value.readUnsignedInt());
89 builder.setPrefixMetric(metric);
90 LOG.debug("Parsed Metric: {}", metric);
92 case FORWARDING_ADDRESS:
93 final IpAddress fwdAddress = parseForwardingAddress(value);
94 builder.setOspfForwardingAddress(fwdAddress);
95 LOG.debug("Parsed FWD Address: {}", fwdAddress);
98 LOG.debug("Parsed Opaque value: {}, not preserving it", ByteBufUtil.hexDump(value));
101 LOG.warn("TLV {} is not a valid prefix attribute, ignoring it", key);
104 LOG.trace("Finished parsing Prefix Attributes.");
105 builder.setRouteTags(routeTags);
106 builder.setExtendedTags(exRouteTags);
107 return new PrefixAttributesCaseBuilder().setPrefixAttributes(builder.build()).build();
110 private static IpAddress parseForwardingAddress(final ByteBuf value) {
111 IpAddress fwdAddress = null;
112 switch (value.readableBytes()) {
113 case Ipv4Util.IP4_LENGTH:
114 fwdAddress = new IpAddress(Ipv4Util.addressForByteBuf(value));
116 case Ipv6Util.IPV6_LENGTH:
117 fwdAddress = new IpAddress(Ipv6Util.addressForByteBuf(value));
120 LOG.debug("Ignoring unsupported forwarding address length {}", value.readableBytes());
125 static void serializePrefixAttributes(final PrefixAttributesCase prefixAttributesCase, final ByteBuf byteAggregator) {
126 final PrefixAttributes prefixAtrributes = prefixAttributesCase.getPrefixAttributes();
127 if (prefixAtrributes.getIgpBits() != null) {
128 final BitSet igpBit = new BitSet();
129 final Boolean bit = prefixAtrributes.getIgpBits().getUpDown().isUpDown();
131 igpBit.set(UP_DOWN_BIT, bit);
133 TlvUtil.writeTLV(IGP_FLAGS, Unpooled.wrappedBuffer(igpBit.toByteArray()), byteAggregator);
135 if (prefixAtrributes.getRouteTags() != null) {
136 final ByteBuf routeTagsBuf = Unpooled.buffer();
137 for (final RouteTag routeTag : prefixAtrributes.getRouteTags()) {
138 routeTagsBuf.writeBytes(routeTag.getValue());
140 TlvUtil.writeTLV(ROUTE_TAG, routeTagsBuf, byteAggregator);
142 final List<ExtendedRouteTag> routeTagList = prefixAtrributes.getExtendedTags();
143 if (routeTagList != null) {
144 final ByteBuf extendedBuf = Unpooled.buffer();
145 for (final ExtendedRouteTag extendedRouteTag : routeTagList) {
146 extendedBuf.writeBytes(extendedRouteTag.getValue());
148 TlvUtil.writeTLV(EXTENDED_ROUTE_TAG, extendedBuf, byteAggregator);
150 serializeForwardingAddress(prefixAtrributes.getOspfForwardingAddress(), byteAggregator);
151 if (prefixAtrributes.getPrefixMetric() != null) {
152 TlvUtil.writeTLV(PREFIX_METRIC, Unpooled.copyInt(prefixAtrributes.getPrefixMetric().getValue().intValue()), byteAggregator);
156 private static void serializeForwardingAddress(final IpAddress forwardingAddress, final ByteBuf byteAggregator) {
157 if (forwardingAddress != null) {
158 final ByteBuf ospfBuf = Unpooled.buffer();
159 if (forwardingAddress.getIpv4Address() != null) {
160 ospfBuf.writeBytes(Ipv4Util.bytesForAddress(forwardingAddress.getIpv4Address()));
161 } else if (forwardingAddress.getIpv6Address() != null) {
162 ospfBuf.writeBytes(Ipv6Util.bytesForAddress(forwardingAddress.getIpv6Address()));
164 TlvUtil.writeTLV(FORWARDING_ADDRESS, ospfBuf, byteAggregator);