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;
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;
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;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import com.google.common.primitives.UnsignedBytes;
/**
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);
}
/**
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());
}
}
}
* @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();
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();
}
* @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();
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());
}
}
}
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);
}
@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);