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.impl.attribute;
10 import com.google.common.collect.HashMultimap;
11 import com.google.common.collect.Multimap;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
15 import org.opendaylight.protocol.bgp.parser.spi.AbstractAttributeParser;
16 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
17 import org.opendaylight.protocol.bgp.parser.spi.AttributeUtil;
18 import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
19 import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandling;
20 import org.opendaylight.protocol.rsvp.parser.spi.RSVPTeObjectRegistry;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.Attributes1;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.Attributes1Builder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.ProtocolId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.ObjectType;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.destination.CLinkstateDestination;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.object.type.LinkCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.object.type.NodeCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.object.type.PrefixCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.object.type.TeLspCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.path.attribute.LinkStateAttribute;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.linkstate.path.attribute.link.state.attribute.TeLspAttributesCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 * Parser for Link State Path Attribute.
46 * @see <a href="http://tools.ietf.org/html/draft-gredler-idr-ls-distribution-04">BGP-LS draft</a>
48 public final class LinkstateAttributeParser extends AbstractAttributeParser implements AttributeSerializer {
50 private static final Logger LOG = LoggerFactory.getLogger(LinkstateAttributeParser.class);
52 private static final int TYPE = 29;
54 private static final int LEGACY_TYPE = 99;
56 private final int type;
58 private final RSVPTeObjectRegistry rsvpTeObjectRegistry;
60 public LinkstateAttributeParser(final boolean isIanaAssignedType, final RSVPTeObjectRegistry rsvpTeObjectRegistry) {
61 this.type = isIanaAssignedType ? TYPE : LEGACY_TYPE;
62 this.rsvpTeObjectRegistry = rsvpTeObjectRegistry;
65 private static Multimap<Integer, ByteBuf> getAttributesMap(final ByteBuf buffer) {
67 * e.g. IS-IS Area Identifier TLV can occur multiple times
69 final Multimap<Integer, ByteBuf> map = HashMultimap.create();
70 while (buffer.isReadable()) {
71 final int type = buffer.readUnsignedShort();
72 final int length = buffer.readUnsignedShort();
73 final ByteBuf value = buffer.readSlice(length);
79 public int getType() {
84 public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder,
85 final RevisedErrorHandling errorHandling, final PeerSpecificParserConstraint constraint)
86 throws BGPParsingException {
87 // FIXME: BGPCEP-359: we need an updated link-state spec for RFC7606
88 final CLinkstateDestination lsDestination = getNlriType(builder);
89 if (lsDestination == null) {
90 LOG.warn("No Linkstate NLRI found, not parsing Linkstate attribute");
93 final ObjectType nlriType = lsDestination.getObjectType();
94 final ProtocolId protocolId = lsDestination.getProtocolId();
95 final Attributes1 a = new Attributes1Builder().setLinkStateAttribute(
96 parseLinkState(nlriType, protocolId, buffer)).build();
97 builder.addAugmentation(Attributes1.class, a);
100 private static CLinkstateDestination getNlriType(final AttributesBuilder pab) {
101 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329
102 .Attributes1 mpr = pab.augmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
103 .multiprotocol.rev180329.Attributes1.class);
104 if (mpr != null && mpr.getMpReachNlri() != null) {
105 final DestinationType dt = mpr.getMpReachNlri().getAdvertizedRoutes().getDestinationType();
106 if (dt instanceof DestinationLinkstateCase) {
107 for (final CLinkstateDestination d : ((DestinationLinkstateCase) dt).getDestinationLinkstate()
108 .getCLinkstateDestination()) {
113 final Attributes2 mpu = pab.augmentation(Attributes2.class);
114 if (mpu != null && mpu.getMpUnreachNlri() != null) {
115 final DestinationType dt = mpu.getMpUnreachNlri().getWithdrawnRoutes().getDestinationType();
116 if (dt instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev180329
117 .update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) {
118 for (final CLinkstateDestination d : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
119 .bgp.linkstate.rev180329.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
120 .DestinationLinkstateCase) dt).getDestinationLinkstate().getCLinkstateDestination()) {
128 private LinkStateAttribute parseLinkState(final ObjectType nlri, final ProtocolId protocolId, final ByteBuf buffer)
129 throws BGPParsingException {
130 if (nlri instanceof PrefixCase) {
131 return PrefixAttributesParser.parsePrefixAttributes(getAttributesMap(buffer), protocolId);
132 } else if (nlri instanceof LinkCase) {
133 return LinkAttributesParser.parseLinkAttributes(getAttributesMap(buffer), protocolId);
134 } else if (nlri instanceof NodeCase) {
135 return NodeAttributesParser.parseNodeAttributes(getAttributesMap(buffer), protocolId);
136 } else if (nlri instanceof TeLspCase) {
137 return TeLspAttributesParser.parseTeLspAttributes(this.rsvpTeObjectRegistry, getAttributesMap(buffer)
138 .entries().iterator().next().getValue());
140 throw new IllegalStateException("Unhandled NLRI type " + nlri);
145 * Serialize linkstate attributes.
147 * @param attribute DataObject representing LinkstatePathAttribute
148 * @param byteAggregator ByteBuf where all serialized data are aggregated
152 public void serializeAttribute(final Attributes attribute, final ByteBuf byteAggregator) {
153 final Attributes1 pathAttributes1 = attribute.augmentation(Attributes1.class);
154 if (pathAttributes1 == null) {
157 final LinkStateAttribute linkState = pathAttributes1.getLinkStateAttribute();
158 final ByteBuf lsBuffer = Unpooled.buffer();
159 if (linkState instanceof LinkAttributesCase) {
160 LinkAttributesParser.serializeLinkAttributes((LinkAttributesCase) linkState, lsBuffer);
161 } else if (linkState instanceof NodeAttributesCase) {
162 NodeAttributesParser.serializeNodeAttributes((NodeAttributesCase) linkState, lsBuffer);
163 } else if (linkState instanceof PrefixAttributesCase) {
164 PrefixAttributesParser.serializePrefixAttributes((PrefixAttributesCase) linkState, lsBuffer);
165 } else if (linkState instanceof TeLspAttributesCase) {
166 TeLspAttributesParser.serializeLspAttributes(this.rsvpTeObjectRegistry, (TeLspAttributesCase) linkState,
168 byteAggregator.writeBytes(lsBuffer);
171 AttributeUtil.formatAttribute(AttributeUtil.OPTIONAL, getType(), lsBuffer, byteAggregator);