2 * Copyright (c) 2013 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.base.Preconditions;
11 import com.google.common.collect.HashMultimap;
12 import com.google.common.collect.Multimap;
13 import io.netty.buffer.ByteBuf;
14 import io.netty.buffer.Unpooled;
15 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
16 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
17 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
18 import org.opendaylight.protocol.bgp.parser.spi.AttributeUtil;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.NlriType;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.PathAttributes1;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.PathAttributes1Builder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.linkstate.destination.CLinkstateDestination;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.LinkstatePathAttribute;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.LinkstatePathAttributeBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.LinkStateAttribute;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.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.rev131125.update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
34 import org.opendaylight.yangtools.yang.binding.DataObject;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Parser for Link State Path Attribute.
41 * @see <a href="http://tools.ietf.org/html/draft-gredler-idr-ls-distribution-04">BGP-LS draft</a>
43 public class LinkstateAttributeParser implements AttributeParser, AttributeSerializer {
45 private static final Logger LOG = LoggerFactory.getLogger(LinkstateAttributeParser.class);
47 private static final int TYPE = 29;
49 private static final int LEGACY_TYPE = 99;
51 private final int type;
53 public LinkstateAttributeParser(final boolean isIanaAssignedType) {
54 this.type = (isIanaAssignedType) ? TYPE : LEGACY_TYPE;
57 public int getType() {
62 public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) throws BGPParsingException {
63 final NlriType nlriType = getNlriType(builder);
64 if (nlriType == null) {
65 LOG.warn("No Linkstate NLRI found, not parsing Linkstate attribute");
68 final PathAttributes1 a = new PathAttributes1Builder().setLinkstatePathAttribute(parseLinkState(nlriType, buffer)).build();
69 builder.addAugmentation(PathAttributes1.class, a);
72 private NlriType getNlriType(final PathAttributesBuilder pab) {
73 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1 mpr = pab.getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1.class);
74 if (mpr != null && mpr.getMpReachNlri() != null) {
75 final DestinationType dt = mpr.getMpReachNlri().getAdvertizedRoutes().getDestinationType();
76 if (dt instanceof DestinationLinkstateCase) {
77 for (final CLinkstateDestination d : ((DestinationLinkstateCase) dt).getDestinationLinkstate().getCLinkstateDestination()) {
78 return d.getNlriType();
82 final PathAttributes2 mpu = pab.getAugmentation(PathAttributes2.class);
83 if (mpu != null && mpu.getMpUnreachNlri() != null) {
84 final DestinationType dt = mpu.getMpUnreachNlri().getWithdrawnRoutes().getDestinationType();
85 if (dt instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) {
86 for (final CLinkstateDestination d : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) dt).getDestinationLinkstate().getCLinkstateDestination()) {
87 return d.getNlriType();
94 private static LinkstatePathAttribute parseLinkState(final NlriType nlri, final ByteBuf buffer) throws BGPParsingException {
96 * e.g. IS-IS Area Identifier TLV can occur multiple times
98 final Multimap<Integer, ByteBuf> map = HashMultimap.create();
99 while (buffer.isReadable()) {
100 final int type = buffer.readUnsignedShort();
101 final int length = buffer.readUnsignedShort();
102 final ByteBuf value = buffer.slice(buffer.readerIndex(), length);
103 map.put(type, value);
104 buffer.skipBytes(length);
106 final LinkstatePathAttributeBuilder builder = new LinkstatePathAttributeBuilder();
111 builder.setLinkStateAttribute(PrefixAttributesParser.parsePrefixAttributes(map));
112 return builder.build();
114 builder.setLinkStateAttribute(LinkAttributesParser.parseLinkAttributes(map));
115 return builder.build();
117 builder.setLinkStateAttribute(NodeAttributesParser.parseNodeAttributes(map));
118 return builder.build();
120 throw new IllegalStateException("Unhandled NLRI type " + nlri);
125 * Serialize linkstate attributes.
127 * @param attribute DataObject representing LinkstatePathAttribute
128 * @param byteAggregator ByteBuf where all serialized data are aggregated
132 public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
133 Preconditions.checkArgument(attribute instanceof PathAttributes, "Attribute parameter is not a PathAttribute object.");
134 final PathAttributes1 pathAttributes1 = ((PathAttributes) attribute).getAugmentation(PathAttributes1.class);
135 if (pathAttributes1 == null) {
138 final LinkStateAttribute linkState = pathAttributes1.getLinkstatePathAttribute().getLinkStateAttribute();
139 final ByteBuf lsBuffer = Unpooled.buffer();
140 if (linkState instanceof LinkAttributesCase) {
141 LinkAttributesParser.serializeLinkAttributes((LinkAttributesCase) linkState, lsBuffer);
142 } else if (linkState instanceof NodeAttributesCase) {
143 NodeAttributesParser.serializeNodeAttributes((NodeAttributesCase) linkState, lsBuffer);
144 } else if (linkState instanceof PrefixAttributesCase) {
145 PrefixAttributesParser.serializePrefixAttributes((PrefixAttributesCase) linkState, lsBuffer);
147 AttributeUtil.formatAttribute(AttributeUtil.OPTIONAL, getType(), lsBuffer, byteAggregator);