org.opendaylight.protocol.bgp.linkstate.attribute.LinkstateAttributeParser.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.protocol.bgp.linkstate.attribute.LinkstateAttributeParser.java

Source

/*
 * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.protocol.bgp.linkstate.attribute;

import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.opendaylight.protocol.bgp.parser.BGPParsingException;
import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
import org.opendaylight.protocol.bgp.parser.spi.AttributeUtil;
import org.opendaylight.protocol.rsvp.parser.spi.RSVPTeObjectRegistry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1Builder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.LinkStateAttribute;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.TeLspAttributesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Parser for Link State Path Attribute.
 *
 * @see <a href="http://tools.ietf.org/html/draft-gredler-idr-ls-distribution-04">BGP-LS draft</a>
 */
public class LinkstateAttributeParser implements AttributeParser, AttributeSerializer {

    private static final Logger LOG = LoggerFactory.getLogger(LinkstateAttributeParser.class);

    private static final int TYPE = 29;

    private static final int LEGACY_TYPE = 99;

    private final int type;

    private final RSVPTeObjectRegistry rsvpTeObjectRegistry;

    public LinkstateAttributeParser(final boolean isIanaAssignedType,
            final RSVPTeObjectRegistry rsvpTeObjectRegistry) {
        this.type = (isIanaAssignedType) ? TYPE : LEGACY_TYPE;
        this.rsvpTeObjectRegistry = rsvpTeObjectRegistry;
    }

    private static Multimap<Integer, ByteBuf> getAttributesMap(final ByteBuf buffer) {
        /*
         * e.g. IS-IS Area Identifier TLV can occur multiple times
         */
        final Multimap<Integer, ByteBuf> map = HashMultimap.create();
        while (buffer.isReadable()) {
            final int type = buffer.readUnsignedShort();
            final int length = buffer.readUnsignedShort();
            final ByteBuf value = buffer.readSlice(length);
            map.put(type, value);
        }
        return map;
    }

    public int getType() {
        return this.type;
    }

    @Override
    public void parseAttribute(final ByteBuf buffer, final AttributesBuilder builder) throws BGPParsingException {
        final CLinkstateDestination lsDestination = getNlriType(builder);
        if (lsDestination == null) {
            LOG.warn("No Linkstate NLRI found, not parsing Linkstate attribute");
            return;
        }
        final ObjectType nlriType = lsDestination.getObjectType();
        final ProtocolId protocolId = lsDestination.getProtocolId();
        final Attributes1 a = new Attributes1Builder()
                .setLinkStateAttribute(parseLinkState(nlriType, protocolId, buffer)).build();
        builder.addAugmentation(Attributes1.class, a);
    }

    private CLinkstateDestination getNlriType(final AttributesBuilder pab) {
        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1 mpr = pab
                .getAugmentation(
                        org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1.class);
        if (mpr != null && mpr.getMpReachNlri() != null) {
            final DestinationType dt = mpr.getMpReachNlri().getAdvertizedRoutes().getDestinationType();
            if (dt instanceof DestinationLinkstateCase) {
                for (final CLinkstateDestination d : ((DestinationLinkstateCase) dt).getDestinationLinkstate()
                        .getCLinkstateDestination()) {
                    return d;
                }
            }
        }
        final Attributes2 mpu = pab.getAugmentation(Attributes2.class);
        if (mpu != null && mpu.getMpUnreachNlri() != null) {
            final DestinationType dt = mpu.getMpUnreachNlri().getWithdrawnRoutes().getDestinationType();
            if (dt instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) {
                for (final CLinkstateDestination d : ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) dt)
                        .getDestinationLinkstate().getCLinkstateDestination()) {
                    return d;
                }
            }
        }
        return null;
    }

    private LinkStateAttribute parseLinkState(final ObjectType nlri, final ProtocolId protocolId,
            final ByteBuf buffer) throws BGPParsingException {

        if (nlri instanceof PrefixCase) {
            return PrefixAttributesParser.parsePrefixAttributes(getAttributesMap(buffer), protocolId);
        } else if (nlri instanceof LinkCase) {
            return LinkAttributesParser.parseLinkAttributes(getAttributesMap(buffer), protocolId);
        } else if (nlri instanceof NodeCase) {
            return NodeAttributesParser.parseNodeAttributes(getAttributesMap(buffer), protocolId);
        } else if (nlri instanceof TeLspCase) {
            return TeLspAttributesParser.parseTeLspAttributes(this.rsvpTeObjectRegistry,
                    getAttributesMap(buffer).entries().iterator().next().getValue());
        } else {
            throw new IllegalStateException("Unhandled NLRI type " + nlri);
        }
    }

    /**
     * Serialize linkstate attributes.
     *
     * @param attribute      DataObject representing LinkstatePathAttribute
     * @param byteAggregator ByteBuf where all serialized data are aggregated
     */

    @Override
    public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
        Preconditions.checkArgument(attribute instanceof Attributes,
                "Attribute parameter is not a PathAttribute object.");
        final Attributes1 pathAttributes1 = ((Attributes) attribute).getAugmentation(Attributes1.class);
        if (pathAttributes1 == null) {
            return;
        }
        final LinkStateAttribute linkState = pathAttributes1.getLinkStateAttribute();
        final ByteBuf lsBuffer = Unpooled.buffer();
        if (linkState instanceof LinkAttributesCase) {
            LinkAttributesParser.serializeLinkAttributes((LinkAttributesCase) linkState, lsBuffer);
        } else if (linkState instanceof NodeAttributesCase) {
            NodeAttributesParser.serializeNodeAttributes((NodeAttributesCase) linkState, lsBuffer);
        } else if (linkState instanceof PrefixAttributesCase) {
            PrefixAttributesParser.serializePrefixAttributes((PrefixAttributesCase) linkState, lsBuffer);
        } else if (linkState instanceof TeLspAttributesCase) {
            TeLspAttributesParser.serializeLspAttributes(this.rsvpTeObjectRegistry, (TeLspAttributesCase) linkState,
                    lsBuffer);
            byteAggregator.writeBytes(lsBuffer);
            return;
        }
        AttributeUtil.formatAttribute(AttributeUtil.OPTIONAL, getType(), lsBuffer, byteAggregator);
    }
}