Update Linkstate attribute parser 97/4497/5
authorRobert Varga <rovarga@cisco.com>
Tue, 21 Jan 2014 12:59:59 +0000 (13:59 +0100)
committerRobert Varga <rovarga@cisco.com>
Tue, 21 Jan 2014 16:36:11 +0000 (17:36 +0100)
This updates the parser to check which NLRI type is being handled and
set attributes accordingly.

Do not trigger deserialization errors when an unexpected TLV is seen in
the attribute, just emit a warning.

Change-Id: I5be1bae5448ae299082023b4fd8f424645236c63
Signed-off-by: Robert Varga <rovarga@cisco.com>
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParser.java
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java

index 9e873c4a1336282d148c9c77efd06b16f227c5d2..d20027d0bb878de042561d227d1a5385f426b0db 100644 (file)
@@ -8,11 +8,10 @@
 package org.opendaylight.protocol.bgp.linkstate;
 
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
+import java.util.TreeMap;
 
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
@@ -29,12 +28,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.IsisAreaIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkProtectionType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.MplsProtocolMask;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.NlriType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.NodeFlagBits;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.PathAttributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.PathAttributes1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.RouteTag;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.TopologyIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.link.state.UnreservedBandwidthBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.linkstate.destination.CLinkstateDestination;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.prefix.state.IgpBitsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.LinkstatePathAttribute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.LinkstatePathAttributeBuilder;
@@ -45,7 +46,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributesBuilder;
+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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IgpMetric;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Metric;
@@ -56,7 +60,6 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 import com.google.common.primitives.UnsignedBytes;
 
 /**
@@ -74,76 +77,83 @@ public class LinkstateAttributeParser implements AttributeParser {
 
        private static final int LENGTH_SIZE = 2;
 
-       private static final Set<Short> NODE_TLVS = Sets.newHashSet(TlvCode.MULTI_TOPOLOGY_ID, TlvCode.NODE_FLAG_BITS, TlvCode.NODE_OPAQUE,
-                       TlvCode.DYNAMIC_HOSTNAME, TlvCode.ISIS_AREA_IDENTIFIER, TlvCode.LOCAL_IPV4_ROUTER_ID, TlvCode.LOCAL_IPV6_ROUTER_ID);
-
-       private static final Set<Short> LINK_TLVS = Sets.newHashSet(TlvCode.LOCAL_IPV4_ROUTER_ID, TlvCode.LOCAL_IPV6_ROUTER_ID,
-                       TlvCode.REMOTE_IPV4_ROUTER_ID, TlvCode.REMOTE_IPV6_ROUTER_ID, TlvCode.ADMIN_GROUP, TlvCode.MAX_BANDWIDTH,
-                       TlvCode.MAX_RESERVABLE_BANDWIDTH, TlvCode.UNRESERVED_BANDWIDTH, TlvCode.TE_METRIC, TlvCode.LINK_PROTECTION_TYPE,
-                       TlvCode.MPLS_PROTOCOL, TlvCode.METRIC, TlvCode.SHARED_RISK_LINK_GROUP, TlvCode.LINK_OPAQUE, TlvCode.LINK_NAME);
-
-       private static final Set<Short> PREFIX_TLVS = Sets.newHashSet(TlvCode.IGP_FLAGS, TlvCode.ROUTE_TAG, TlvCode.EXTENDED_ROUTE_TAG,
-                       TlvCode.PREFIX_METRIC, TlvCode.FORWARDING_ADDRESS, TlvCode.PREFIX_OPAQUE);
-
-       @Override
-       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPParsingException {
-               final PathAttributes1 a = new PathAttributes1Builder().setLinkstatePathAttribute(parseLinkState(bytes)).build();
-               builder.addAugmentation(PathAttributes1.class, a);
-       }
-
-       private static boolean verifyLink(final Set<Short> keys) {
-               for (final Short i : keys) {
-                       if (!LINK_TLVS.contains(i)) {
-                               LOG.debug("Link attribute {} not found.", i);
-                               return false;
+       private final NlriType getNlriType(final PathAttributesBuilder pab) {
+               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);
+               if (mpr != null && mpr.getMpReachNlri() != null) {
+                       final DestinationType dt = mpr.getMpReachNlri().getAdvertizedRoutes().getDestinationType();
+                       if (dt instanceof DestinationLinkstateCase) {
+                               for (CLinkstateDestination d : ((DestinationLinkstateCase)dt).getDestinationLinkstate().getCLinkstateDestination()) {
+                                       return d.getNlriType();
+                               }
                        }
+               } else {
+                       LOG.debug("No MP_REACH attribute present");
                }
-               return true;
-       }
 
-       private static boolean verifyNode(final Set<Short> keys) {
-               for (final Short i : keys) {
-                       if (!NODE_TLVS.contains(i)) {
-                               LOG.debug("Node attribute {} not found.", i);
-                               return false;
+               final PathAttributes2 mpu = pab.getAugmentation(PathAttributes2.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.rev131125.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase) {
+                               for (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()) {
+                                       return d.getNlriType();
+                               }
                        }
+               } else {
+                       LOG.debug("No MP_UNREACH attribute present");
                }
-               return true;
+
+               return null;
        }
 
-       private static boolean verifyPrefix(final Set<Short> keys) {
-               for (final Short i : keys) {
-                       if (!PREFIX_TLVS.contains(i)) {
-                               LOG.debug("Prefix attribute {} not found.", i);
-                               return false;
-                       }
+       @Override
+       public void parseAttribute(final byte[] bytes, final PathAttributesBuilder builder) throws BGPParsingException {
+               final NlriType type = getNlriType(builder);
+               if (type == null) {
+                       LOG.warn("No Linkstate NLRI found, not parsing Linkstate attribute");
+                       return;
                }
-               return true;
+
+               final PathAttributes1 a = new PathAttributes1Builder().setLinkstatePathAttribute(parseLinkState(type, bytes)).build();
+               builder.addAugmentation(PathAttributes1.class, a);
        }
 
-       private static LinkstatePathAttribute parseLinkState(final byte[] bytes) throws BGPParsingException {
-               final Map<Short, ByteList> map = new HashMap<>();
+       private static LinkstatePathAttribute parseLinkState(final NlriType nlri, final byte[] bytes) throws BGPParsingException {
+               final Map<Short, ByteList> map = new TreeMap<>();
                int byteOffset = 0;
                while (byteOffset != bytes.length) {
-                       final short type = ByteArray.bytesToShort(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
+                       final Short type = ByteArray.bytesToShort(ByteArray.subByte(bytes, byteOffset, TYPE_LENGTH));
                        byteOffset += TYPE_LENGTH;
                        final int length = ByteArray.bytesToInt(ByteArray.subByte(bytes, byteOffset, LENGTH_SIZE));
                        byteOffset += LENGTH_SIZE;
                        final byte[] value = ByteArray.subByte(bytes, byteOffset, length);
-                       final ByteList values = map.containsKey(type) ? map.get(type) : new ByteList();
+
+                       // TODO: does the specification allow for a TLV to occur multiple times? If so, provide a reference to
+                       // that section and replace this comment which description of what we are doing here.
+                       ByteList values = map.get(type);
+                       if (values == null) {
+                               values = new ByteList();
+                       }
+
                        values.add(value);
                        map.put(type, values);
                        byteOffset += length;
                }
                final LinkstatePathAttributeBuilder builder = new LinkstatePathAttributeBuilder();
-               if (verifyLink(map.keySet())) {
+
+               switch (nlri) {
+               case Ipv4Prefix:
+               case Ipv6Prefix:
+                       builder.setLinkStateAttribute(parsePrefixAttributes(map));
+                       return builder.build();
+               case Link:
                        builder.setLinkStateAttribute(parseLinkAttributes(map));
-               } else if (verifyNode(map.keySet())) {
+                       return builder.build();
+               case Node:
                        builder.setLinkStateAttribute(parseNodeAttributes(map));
-               } else if (verifyPrefix(map.keySet())) {
-                       builder.setLinkStateAttribute(parsePrefixAttributes(map));
+                       return builder.build();
                }
-               return builder.build();
+
+               throw new IllegalStateException("Unhandled NLRI type " + nlri);
        }
 
        /**
@@ -246,7 +256,7 @@ public class LinkstateAttributeParser implements AttributeParser {
                                        LOG.debug("Parsed Link Name : {}", name);
                                        break;
                                default:
-                                       throw new BGPParsingException("Link Attribute not recognized, type: " + entry.getKey());
+                                       LOG.warn("TLV {} is not a valid link attribute, ignoring it", entry.getKey());
                                }
                        }
                }
@@ -261,7 +271,7 @@ public class LinkstateAttributeParser implements AttributeParser {
         * @return {@link LinkStateAttribute}
         * @throws BGPParsingException if a node attribute is not recognized
         */
-       private static LinkStateAttribute parseNodeAttributes(final Map<Short, ByteList> attributes) throws BGPParsingException {
+       private static LinkStateAttribute parseNodeAttributes(final Map<Short, ByteList> attributes) {
                final List<TopologyIdentifier> topologyMembership = Lists.newArrayList();
                final List<IsisAreaIdentifier> areaMembership = Lists.newArrayList();
                final NodeAttributesBuilder builder = new NodeAttributesBuilder();
@@ -306,13 +316,14 @@ public class LinkstateAttributeParser implements AttributeParser {
                                        LOG.debug("Parsed IPv6 Router Identifier {}", ip6);
                                        break;
                                default:
-                                       throw new BGPParsingException("Node Attribute not recognized, type: " + entry.getKey());
+                                       LOG.warn("TLV {} is not a valid node attribute, ignoring it", entry.getKey());
                                }
                        }
                }
+               LOG.trace("Finished parsing Node Attributes.");
+
                builder.setTopologyIdentifier(topologyMembership);
                builder.setIsisAreaId(areaMembership);
-               LOG.trace("Finished parsing Node Attributes.");
                return new NodeAttributesCaseBuilder().setNodeAttributes(builder.build()).build();
        }
 
@@ -323,7 +334,7 @@ public class LinkstateAttributeParser implements AttributeParser {
         * @return {@link LinkStateAttribute}
         * @throws BGPParsingException if some prefix attributes is not recognized
         */
-       private static LinkStateAttribute parsePrefixAttributes(final Map<Short, ByteList> attributes) throws BGPParsingException {
+       private static LinkStateAttribute parsePrefixAttributes(final Map<Short, ByteList> attributes) {
                final PrefixAttributesBuilder builder = new PrefixAttributesBuilder();
                final List<RouteTag> routeTags = Lists.newArrayList();
                final List<ExtendedRouteTag> exRouteTags = Lists.newArrayList();
@@ -375,11 +386,10 @@ public class LinkstateAttributeParser implements AttributeParser {
                                        LOG.trace("Parsed FWD Address: {}", fwdAddress);
                                        break;
                                case TlvCode.PREFIX_OPAQUE:
-                                       final byte[] opaque = value;
-                                       LOG.trace("Parsed Opaque value: {}", Arrays.toString(opaque));
+                                       LOG.debug("Parsed Opaque value: {}, not preserving it", ByteArray.bytesToHexString(value));
                                        break;
                                default:
-                                       throw new BGPParsingException("Prefix Attribute not recognized, type: " + entry.getKey());
+                                       LOG.warn("TLV {} is not a valid prefix attribute, ignoring it", entry.getKey());
                                }
                        }
                }
index 8893788b1ed64b0b2f93caa1b964298c82b5a3eb..6f26988c5c81b72c3c268fd67150e1890e73a9aa 100644 (file)
@@ -10,45 +10,61 @@ package org.opendaylight.protocol.bgp.linkstate;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
 
 import org.junit.Test;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.NlriType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.PathAttributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.linkstate.destination.CLinkstateDestinationBuilder;
 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;
 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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.update.path.attributes.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
+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.DestinationLinkstateCaseBuilder;
+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.destination.linkstate._case.DestinationLinkstateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+
+import com.google.common.collect.Lists;
 
 public class LinkstateAttributeParserTest {
 
        private static final byte[] LINK_ATTR = new byte[] { (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2a, (byte) 0x2a,
-                       (byte) 0x2a, (byte) 0x2a, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b,
-                       (byte) 0x2b, (byte) 0x04, (byte) 0x40, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-                       (byte) 0x04, (byte) 0x41, (byte) 0x00, (byte) 0x04, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x04,
-                       (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x46, (byte) 0x43, (byte) 0x50, (byte) 0x00, (byte) 0x04, (byte) 0x43,
-                       (byte) 0x00, (byte) 0x20, (byte) 0x46, (byte) 0x43, (byte) 0x50, (byte) 0x00, (byte) 0x46, (byte) 0x43, (byte) 0x50,
-                       (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-                       (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
-                       (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x44,
-                       (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x47, (byte) 0x00, (byte) 0x03,
-                       (byte) 0x00, (byte) 0x00, (byte) 0x0a };
+               (byte) 0x2a, (byte) 0x2a, (byte) 0x04, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x2b, (byte) 0x2b, (byte) 0x2b,
+               (byte) 0x2b, (byte) 0x04, (byte) 0x40, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+               (byte) 0x04, (byte) 0x41, (byte) 0x00, (byte) 0x04, (byte) 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, (byte) 0x04,
+               (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x46, (byte) 0x43, (byte) 0x50, (byte) 0x00, (byte) 0x04, (byte) 0x43,
+               (byte) 0x00, (byte) 0x20, (byte) 0x46, (byte) 0x43, (byte) 0x50, (byte) 0x00, (byte) 0x46, (byte) 0x43, (byte) 0x50,
+               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+               (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x44,
+               (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x47, (byte) 0x00, (byte) 0x03,
+               (byte) 0x00, (byte) 0x00, (byte) 0x0a };
 
        private static final byte[] NODE_ATTR = new byte[] { (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x05, (byte) 0x31, (byte) 0x32,
-                       (byte) 0x4b, (byte) 0x2d, (byte) 0x32, (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04,
-                       (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x29, (byte) 0x29, (byte) 0x29, (byte) 0x29 };
+               (byte) 0x4b, (byte) 0x2d, (byte) 0x32, (byte) 0x04, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04,
+               (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x29, (byte) 0x29, (byte) 0x29, (byte) 0x29 };
 
        private final LinkstateAttributeParser parser = new LinkstateAttributeParser();
 
+       private static PathAttributesBuilder createBuilder(final NlriType type) {
+               return new PathAttributesBuilder().addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1.class,
+                               new PathAttributes1Builder().setMpReachNlri(
+                                               new MpReachNlriBuilder().setAfi(LinkstateAddressFamily.class).setSafi(LinkstateSubsequentAddressFamily.class).setAdvertizedRoutes(
+                                                               new AdvertizedRoutesBuilder().setDestinationType(
+                                                                               new DestinationLinkstateCaseBuilder().setDestinationLinkstate(
+                                                                                               new DestinationLinkstateBuilder().setCLinkstateDestination(
+                                                                                                               Lists.newArrayList(new CLinkstateDestinationBuilder().setNlriType(type).build())).build()).build()).build()).build()).build());
+       }
+
        @Test
-       public void testPositiveLinks() {
-               final PathAttributesBuilder builder = new PathAttributesBuilder();
-               try {
-                       this.parser.parseAttribute(LINK_ATTR, builder);
-               } catch (final BGPParsingException e) {
-                       fail("No exception should occur.");
-               }
+       public void testPositiveLinks() throws BGPParsingException {
+               final PathAttributesBuilder builder = createBuilder(NlriType.Link);
+               this.parser.parseAttribute(LINK_ATTR, builder);
                final PathAttributes1 attrs = builder.getAugmentation(PathAttributes1.class);
                final LinkAttributes ls = ((LinkAttributesCase) attrs.getLinkstatePathAttribute().getLinkStateAttribute()).getLinkAttributes();
                assertNotNull(ls);
@@ -64,13 +80,10 @@ public class LinkstateAttributeParserTest {
        }
 
        @Test
-       public void testPositiveNodes() {
-               final PathAttributesBuilder builder = new PathAttributesBuilder();
-               try {
-                       this.parser.parseAttribute(NODE_ATTR, builder);
-               } catch (final BGPParsingException e) {
-                       fail("No exception should occur.");
-               }
+       public void testPositiveNodes() throws BGPParsingException {
+               final PathAttributesBuilder builder = createBuilder(NlriType.Node);
+               this.parser.parseAttribute(NODE_ATTR, builder);
+
                final PathAttributes1 attrs = builder.getAugmentation(PathAttributes1.class);
                final NodeAttributes ls = ((NodeAttributesCase) attrs.getLinkstatePathAttribute().getLinkStateAttribute()).getNodeAttributes();
                assertNotNull(ls);