BUG-4827: BGP Add path Labeled ribSupport 68/37668/6
authorClaudio D. Gasparini <cgaspari@cisco.com>
Fri, 15 Apr 2016 12:19:40 +0000 (14:19 +0200)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Wed, 27 Apr 2016 10:14:58 +0000 (12:14 +0200)
BGP Add path support for labeled extension

Change-Id: I6c94948bc90035078cb04f976457cff0a2591ca9
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
bgp/labeled-unicast/src/main/java/org/opendaylight/protocol/bgp/labeled/unicast/LUNlriParser.java
bgp/labeled-unicast/src/main/java/org/opendaylight/protocol/bgp/labeled/unicast/LabeledUnicastRIBSupport.java
bgp/labeled-unicast/src/main/yang/bgp-labeled-unicast.yang
bgp/labeled-unicast/src/test/java/org/opendaylight/protocol/bgp/labeled/unicast/LUNlriParserTest.java

index b143dbe368efd61944b0bf6147122ecf4cafe162..dae59f67141084d0601c5db978e337c77b55f9ab 100644 (file)
@@ -14,9 +14,15 @@ import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupportUtil;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.protocol.util.Ipv4Util;
 import org.opendaylight.protocol.util.Ipv6Util;
@@ -71,6 +77,8 @@ public class LUNlriParser implements NlriParser, NlriSerializer {
     protected static void serializeNlri(final List<CLabeledUnicastDestination> dests, final ByteBuf buffer) {
         final ByteBuf nlriByteBuf = Unpooled.buffer();
         for (final CLabeledUnicastDestination dest: dests) {
+            PathIdUtil.writePathId(dest.getPathId(), buffer);
+
             final List<LabelStack> labelStack = dest.getLabelStack();
             final IpPrefix prefix = dest.getPrefix();
             // Serialize the length field
@@ -115,20 +123,11 @@ public class LUNlriParser implements NlriParser, NlriSerializer {
     }
 
     @Override
-    public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder)
-            throws BGPParsingException {
-        if (!nlri.isReadable()) {
-            return;
-        }
-        final List<CLabeledUnicastDestination> dst = parseNlri(nlri, builder.getAfi());
-
-        builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(
-                    dst).build()).build()).build());
+    public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
+        parseNlri(nlri, builder, null);
     }
 
-    private static List<CLabeledUnicastDestination> parseNlri(final ByteBuf nlri, final Class<? extends AddressFamily> afi) {
+    private static List<CLabeledUnicastDestination> parseNlri(final ByteBuf nlri, final Class<? extends AddressFamily> afi, final boolean mPathSupported) {
         if (!nlri.isReadable()) {
             return null;
         }
@@ -136,6 +135,9 @@ public class LUNlriParser implements NlriParser, NlriSerializer {
 
         while (nlri.isReadable()) {
             final CLabeledUnicastDestinationBuilder builder = new CLabeledUnicastDestinationBuilder();
+            if (mPathSupported) {
+                builder.setPathId(PathIdUtil.readPathId(nlri));
+            }
             final short length = nlri.readUnsignedByte();
             builder.setLabelStack(parseLabel(nlri));
             final int labelNum = builder.getLabelStack().size();
@@ -171,16 +173,35 @@ public class LUNlriParser implements NlriParser, NlriSerializer {
     }
 
     @Override
-    public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder)
-            throws BGPParsingException {
+    public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) throws BGPParsingException {
+        parseNlri(nlri, builder, null);
+    }
+
+    @Override
+    public void parseNlri(@Nonnull final ByteBuf nlri, @Nonnull final MpReachNlriBuilder builder, @Nullable final PeerSpecificParserConstraint constraint) throws BGPParsingException {
         if (!nlri.isReadable()) {
             return;
         }
-        final List<CLabeledUnicastDestination> dst = parseNlri(nlri, builder.getAfi());
+        final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
+        final List<CLabeledUnicastDestination> dst = parseNlri(nlri, builder.getAfi(), mPathSupported);
 
         builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
             new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
                 new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(
                     dst).build()).build()).build());
     }
+
+    @Override
+    public void parseNlri(@Nonnull final ByteBuf nlri, @Nonnull final MpUnreachNlriBuilder builder, @Nullable final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+        if (!nlri.isReadable()) {
+            return;
+        }
+        final boolean mPathSupported = MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(builder.getAfi(), builder.getSafi()));
+        final List<CLabeledUnicastDestination> dst = parseNlri(nlri, builder.getAfi(), mPathSupported);
+
+        builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(
+                    dst).build()).build()).build());
+    }
 }
index 9054779307a9f3a06b5436db4c8f1f54ada18171..c0925d5c88248a8c1ed1d6a246da011cac748bb7 100644 (file)
@@ -16,8 +16,10 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
 import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.protocol.util.Ipv4Util;
@@ -56,6 +58,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -67,9 +70,10 @@ import org.slf4j.LoggerFactory;
 
 public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
 
+    private static final QName PATHID_QNAME = QName.create(LabeledUnicastRoute.QNAME, "path-id").intern();
     private static final Logger LOG = LoggerFactory.getLogger(LabeledUnicastRIBSupport.class);
-
     private static final NodeIdentifier PREFIX_TYPE_NID = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "prefix").intern());
+    private static final NodeIdentifier PATH_ID_LEAF = new NodeIdentifier(PATHID_QNAME);
     private static final NodeIdentifier LABEL_STACK_NID = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "label-stack").intern());
     private static final NodeIdentifier LV_NID = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "label-value").intern());
 
@@ -181,14 +185,14 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
 
     @Override
     protected void deleteDestinationRoutes(final DOMDataWriteTransaction tx,
-        final YangInstanceIdentifier tablePath, final ContainerNode destination,final NodeIdentifier routesNodeId) {
+        final YangInstanceIdentifier tablePath, final ContainerNode destination, final NodeIdentifier routesNodeId) {
         processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
     }
 
     @Override
     protected void putDestinationRoutes(final DOMDataWriteTransaction tx,
         final YangInstanceIdentifier tablePath, final ContainerNode destination,
-        final ContainerNode attributes,final NodeIdentifier routesNodeId) {
+        final ContainerNode attributes, final NodeIdentifier routesNodeId) {
         processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
     }
 
@@ -232,6 +236,7 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
         final CLabeledUnicastDestinationBuilder builder = new CLabeledUnicastDestinationBuilder();
         builder.setPrefix(extractPrefix(route, PREFIX_TYPE_NID));
         builder.setLabelStack(extractLabel(route, LABEL_STACK_NID, LV_NID));
+        builder.setPathId(PathIdUtil.buildPathId(route, PATH_ID_LEAF));
         return builder.build();
     }
 
@@ -253,7 +258,7 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
         final List<LabelStack> labels = new ArrayList<>();
         final Optional<DataContainerChild<? extends PathArgument, ?>> labelStacks = route.getChild(labelStackNid);
         if (labelStacks.isPresent()) {
-            for(final UnkeyedListEntryNode label : ((UnkeyedListNode)labelStacks.get()).getValue()) {
+            for (final UnkeyedListEntryNode label : ((UnkeyedListNode) labelStacks.get()).getValue()) {
                 final Optional<DataContainerChild<? extends PathArgument, ?>> labelStack = label.getChild(labelValueNid);
                 if (labelStack.isPresent()) {
                     final LabelStackBuilder labelStackbuilder = new LabelStackBuilder();
@@ -264,4 +269,15 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
         }
         return labels;
     }
+
+    @Nonnull
+    @Override
+    public PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
+        return PathIdUtil.createNiiKey(pathId, routeId, LabeledUnicastRoute.QNAME, PATHID_QNAME, ROUTE_KEY);
+    }
+
+    @Override
+    public Long extractPathId(final NormalizedNode<?, ?> data) {
+        return PathIdUtil.extractPathId(data, PATH_ID_LEAF);
+    }
 }
index 22ded4bba3035c90d501cc03b7d536a5a3e00eee..7abdd35d16cb7956b2828c67ad4c81e73a226b73 100644 (file)
@@ -10,6 +10,7 @@ module bgp-labeled-unicast {
     import bgp-types { prefix bgp-t; revision-date 2013-09-19; }
     import bmp-monitor { prefix bmp-mon; revision-date 2015-05-12; }
     import network-concepts { prefix netc; revision-date 2013-11-25; }
+    import bgp-inet { prefix bgp-inet; revision-date 2015-03-05; }
 
     organization "Cisco Systems, Inc.";
     contact "GE QU <gequ@cisco.com>"
@@ -65,6 +66,7 @@ module bgp-labeled-unicast {
         leaf prefix {
             type inet:ip-prefix;
         }
+        uses bgp-msg:path-id-grouping;
     }
 
     grouping labeled-unicast-destination {
@@ -79,7 +81,7 @@ module bgp-labeled-unicast {
                 leaf route-key {
                     type binary;
                 }
-                key "route-key";
+                key "route-key path-id";
                 uses labeled-unicast;
                 uses bgp-rib:route {
                     augment "attributes/bgp-prefix-sid/bgp-prefix-sid-tlvs/bgp-prefix-sid-tlv" {
index d598d2363e8b25d33ab1bd976f01e31f51f9c1ce..9de76997e1c2339032717406c2de221e7155b2ca 100644 (file)
@@ -11,9 +11,16 @@ import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
+import java.util.Optional;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupport;
+import org.opendaylight.protocol.bgp.parser.spi.PeerSpecificParserConstraint;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
@@ -25,6 +32,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labe
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.destination.CLabeledUnicastDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLabeledUnicastCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathId;
 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.Attributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1Builder;
@@ -62,6 +70,28 @@ public class LUNlriParserTest {
         (byte) 0x22, (byte) 0x01, (byte) 0x16,
     };
 
+    /*label stacks with multiple labels.
+    *
+    * label stack:
+    * 1        <- Path Id
+    * 60       <- length 96
+    * 00 16 3  <- labelValue 355
+    * 0        <- etc&bottomBit 0
+    * 00 16 4  <- labelValue 356
+    * 0        <- etc&bottomBit 0
+    * 00 16 6  <- labelValue 357
+    * 1        <- bottomBit 1
+    * 22 01 16 <- prefixType IPV4=34.1.22.0/24
+    */
+    private static final byte[] LU_NLRI_IPv4_ADD_PATH = new byte[] {
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
+        (byte) 0x60,
+        (byte) 0x00, (byte) 0x16, (byte) 0x30,
+        (byte) 0x00, (byte) 0x16, (byte) 0x40,
+        (byte) 0x00, (byte) 0x16, (byte) 0x51,
+        (byte) 0x22, (byte) 0x01, (byte) 0x16,
+    };
+
     /*label stacks with multiple labels.
      *
      * label stack:
@@ -85,6 +115,29 @@ public class LUNlriParserTest {
         (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
     };
 
+    /*label stacks with multiple labels.
+     *
+     * label stack:
+     * C8       <- length 200
+     * 00 16 3  <- labelValue 355
+     * 0        <- etc&bottomBit 0
+     * 00 16 4  <- labelValue 356
+     * 0        <- etc&bottomBit 0
+     * 00 16 6  <- labelValue 357
+     * 1        <- bottomBit 1
+     * 20 01 D B8 0 1 0 2 0 0 0 0 0 0 0 0 80  <- prefixType IPV6=2001:db8:1:2::/128
+     */
+    private static final byte[] LU_NLRI_IPv6_ADD_PATH = new byte[] {
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
+        (byte) 0xC8,
+        (byte) 0x00, (byte) 0x16, (byte) 0x30,
+        (byte) 0x00, (byte) 0x16, (byte) 0x40,
+        (byte) 0x00, (byte) 0x16, (byte) 0x51,
+        (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8,
+        (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
+    };
     private static final List<LabelStack> LABEL_STACK = Lists.newArrayList(
             new LabelStackBuilder().setLabelValue(new MplsLabel(355L)).build(),
             new LabelStackBuilder().setLabelValue(new MplsLabel(356L)).build(),
@@ -92,6 +145,20 @@ public class LUNlriParserTest {
 
     private static final IpPrefix IPv4_PREFIX = new IpPrefix(new Ipv4Prefix("34.1.22.0/24"));
     private static final IpPrefix IPv6_PREFIX = new IpPrefix(new Ipv6Prefix("2001:db8:1:2::/128"));
+    private static final PathId PATH_ID = new PathId(1L);
+
+    @Mock
+    private PeerSpecificParserConstraint constraint;
+    @Mock
+    private MultiPathSupport muliPathSupport;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        Mockito.doReturn(Optional.of(this.muliPathSupport)).when(constraint).getPeerConstraint(Mockito.any());
+        Mockito.doReturn(true).when(this.muliPathSupport).isTableTypeSupported(Mockito.any());
+    }
 
     @Test
     public void testMpReachNlriIpv4() throws BGPParsingException {
@@ -102,16 +169,15 @@ public class LUNlriParserTest {
         final CLabeledUnicastDestination lu = new CLabeledUnicastDestinationBuilder().setPrefix(IPv4_PREFIX).setLabelStack(LABEL_STACK).build();
         mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
                 new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
-                        new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build())
-                        .build())
-                        .build());
+                        new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build()).build()).build());
         final MpReachNlri mpReachExpected = mpBuilder.build();
 
         //test parser
         final MpReachNlriBuilder testBuilder = new MpReachNlriBuilder();
         testBuilder.setAfi(Ipv4AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
         parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv4), testBuilder);
-        Assert.assertEquals(mpBuilder.build(), mpReachExpected);
+        Assert.assertEquals(mpReachExpected, testBuilder.build());
 
         //test serializer
         final ByteBuf output = Unpooled.buffer();
@@ -120,6 +186,33 @@ public class LUNlriParserTest {
         Assert.assertArrayEquals(LU_NLRI_IPv4, ByteArray.readAllBytes(output));
     }
 
+    @Test
+    public void testMpReachNlriIpv4Constraint() throws BGPParsingException {
+        final LUNlriParser parser = new LUNlriParser();
+        final MpReachNlriBuilder mpBuilder = new MpReachNlriBuilder();
+        mpBuilder.setAfi(Ipv4AddressFamily.class);
+        mpBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        final CLabeledUnicastDestination lu = new CLabeledUnicastDestinationBuilder().setPathId(PATH_ID).setPrefix(IPv4_PREFIX).setLabelStack
+            (LABEL_STACK).build();
+        mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+            new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+                new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build()).build()).build());
+        final MpReachNlri mpReachExpected = mpBuilder.build();
+
+        //test parser
+        final MpReachNlriBuilder testBuilder = new MpReachNlriBuilder();
+        testBuilder.setAfi(Ipv4AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv4_ADD_PATH), testBuilder, this.constraint);
+        Assert.assertEquals(mpReachExpected, testBuilder.build());
+
+        //test serializer
+        final ByteBuf output = Unpooled.buffer();
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
+            new Attributes1Builder().setMpReachNlri(mpReachExpected).build()).build(), output);
+        Assert.assertArrayEquals(LU_NLRI_IPv4_ADD_PATH, ByteArray.readAllBytes(output));
+    }
+
     @Test
     public void testMpUnreachNlriIpv4() throws BGPParsingException {
         final LUNlriParser parser = new LUNlriParser();
@@ -130,15 +223,15 @@ public class LUNlriParserTest {
         mpBuilder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
                         new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build())
-                        .build())
-                        .build());
+                        .build()).build());
         final MpUnreachNlri mpUnreachExpected = mpBuilder.build();
 
         //test parser
         final MpUnreachNlriBuilder testBuilder = new MpUnreachNlriBuilder();
         testBuilder.setAfi(Ipv4AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
         parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv4), testBuilder);
-        Assert.assertEquals(mpBuilder.build(), mpUnreachExpected);
+        Assert.assertEquals(mpUnreachExpected, testBuilder.build());
 
         //test serializer
         final ByteBuf output = Unpooled.buffer();
@@ -147,6 +240,33 @@ public class LUNlriParserTest {
         Assert.assertArrayEquals(LU_NLRI_IPv4, ByteArray.readAllBytes(output));
     }
 
+    @Test
+    public void testMpUnreachNlriIpv4Constraint() throws BGPParsingException {
+        final LUNlriParser parser = new LUNlriParser();
+        final MpUnreachNlriBuilder mpBuilder = new MpUnreachNlriBuilder();
+        mpBuilder.setAfi(Ipv4AddressFamily.class);
+        mpBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        final CLabeledUnicastDestination lu = new CLabeledUnicastDestinationBuilder().setPathId(PATH_ID).setPrefix(IPv4_PREFIX).setLabelStack(LABEL_STACK).build();
+        mpBuilder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build())
+                .build()).build());
+        final MpUnreachNlri mpUnreachExpected = mpBuilder.build();
+
+        //test parser
+        final MpUnreachNlriBuilder testBuilder = new MpUnreachNlriBuilder();
+        testBuilder.setAfi(Ipv4AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv4_ADD_PATH), testBuilder, this.constraint);
+        Assert.assertEquals(mpUnreachExpected, testBuilder.build());
+
+        //test serializer
+        final ByteBuf output = Unpooled.buffer();
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
+            new Attributes2Builder().setMpUnreachNlri(mpUnreachExpected).build()).build(), output);
+        Assert.assertArrayEquals(LU_NLRI_IPv4_ADD_PATH, ByteArray.readAllBytes(output));
+    }
+
     @Test
     public void testMpReachNlriIpv6() throws BGPParsingException {
         final LUNlriParser parser = new LUNlriParser();
@@ -154,18 +274,16 @@ public class LUNlriParserTest {
         mpBuilder.setAfi(Ipv6AddressFamily.class);
         mpBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
         final CLabeledUnicastDestination lu = new CLabeledUnicastDestinationBuilder().setPrefix(IPv6_PREFIX).setLabelStack(LABEL_STACK).build();
-        mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-                new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
-                        new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build())
-                        .build())
-                        .build());
+        mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new DestinationLabeledUnicastCaseBuilder()
+            .setDestinationLabeledUnicast(new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build()).build()).build());
         final MpReachNlri mpReachExpected = mpBuilder.build();
 
         //test parser
         final MpReachNlriBuilder testBuilder = new MpReachNlriBuilder();
         testBuilder.setAfi(Ipv6AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
         parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv6), testBuilder);
-        Assert.assertEquals(mpBuilder.build(), mpReachExpected);
+        Assert.assertEquals(mpReachExpected, testBuilder.build());
 
         //test serializer
         final ByteBuf output = Unpooled.buffer();
@@ -174,6 +292,34 @@ public class LUNlriParserTest {
         Assert.assertArrayEquals(LU_NLRI_IPv6, ByteArray.readAllBytes(output));
     }
 
+    @Test
+    public void testMpReachNlriIpv6Constraint() throws BGPParsingException {
+        final LUNlriParser parser = new LUNlriParser();
+        final MpReachNlriBuilder mpBuilder = new MpReachNlriBuilder();
+        mpBuilder.setAfi(Ipv6AddressFamily.class);
+        mpBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        final CLabeledUnicastDestination lu = new CLabeledUnicastDestinationBuilder().setPathId(PATH_ID).setPrefix(IPv6_PREFIX).setLabelStack(LABEL_STACK).build();
+        mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+            new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+                new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build())
+                .build())
+            .build());
+        final MpReachNlri mpReachExpected = mpBuilder.build();
+
+        //test parser
+        final MpReachNlriBuilder testBuilder = new MpReachNlriBuilder();
+        testBuilder.setAfi(Ipv6AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv6_ADD_PATH), testBuilder, this.constraint);
+        Assert.assertEquals(mpReachExpected, testBuilder.build());
+
+        //test serializer
+        final ByteBuf output = Unpooled.buffer();
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
+            new Attributes1Builder().setMpReachNlri(mpReachExpected).build()).build(), output);
+        Assert.assertArrayEquals(LU_NLRI_IPv6_ADD_PATH, ByteArray.readAllBytes(output));
+    }
+
     @Test
     public void testMpUnreachNlriIpv6() throws BGPParsingException {
         final LUNlriParser parser = new LUNlriParser();
@@ -191,8 +337,9 @@ public class LUNlriParserTest {
         //test parser
         final MpUnreachNlriBuilder testBuilder = new MpUnreachNlriBuilder();
         testBuilder.setAfi(Ipv6AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
         parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv6), testBuilder);
-        Assert.assertEquals(mpBuilder.build(), mpUnreachExpected);
+        Assert.assertEquals(mpUnreachExpected, testBuilder.build());
 
         //test serializer
         final ByteBuf output = Unpooled.buffer();
@@ -200,4 +347,33 @@ public class LUNlriParserTest {
                 new Attributes2Builder().setMpUnreachNlri(mpUnreachExpected).build()).build(), output);
         Assert.assertArrayEquals(LU_NLRI_IPv6, ByteArray.readAllBytes(output));
     }
+
+    @Test
+    public void testMpUnreachNlriIpv6Constraint() throws BGPParsingException {
+        final LUNlriParser parser = new LUNlriParser();
+        final MpUnreachNlriBuilder mpBuilder = new MpUnreachNlriBuilder();
+        mpBuilder.setAfi(Ipv6AddressFamily.class);
+        mpBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        final CLabeledUnicastDestination lu = new CLabeledUnicastDestinationBuilder().setPathId(PATH_ID).setPrefix(IPv6_PREFIX).setLabelStack
+            (LABEL_STACK).build();
+        mpBuilder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(Lists.newArrayList(lu)).build())
+                .build())
+            .build());
+        final MpUnreachNlri mpUnreachExpected = mpBuilder.build();
+
+        //test parser
+        final MpUnreachNlriBuilder testBuilder = new MpUnreachNlriBuilder();
+        testBuilder.setAfi(Ipv6AddressFamily.class);
+        testBuilder.setSafi(LabeledUnicastSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.copiedBuffer(LU_NLRI_IPv6_ADD_PATH), testBuilder, this.constraint);
+        Assert.assertEquals(mpUnreachExpected, testBuilder.build());
+
+        //test serializer
+        final ByteBuf output = Unpooled.buffer();
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
+            new Attributes2Builder().setMpUnreachNlri(mpUnreachExpected).build()).build(), output);
+        Assert.assertArrayEquals(LU_NLRI_IPv6_ADD_PATH, ByteArray.readAllBytes(output));
+    }
 }