BUG-5785 Support for dissemination of L3VPN flow spec II 75/39875/8
authorKevin Wang <kevixw@gmail.com>
Mon, 6 Jun 2016 08:49:42 +0000 (01:49 -0700)
committerMilos Fabian <milfabia@cisco.com>
Mon, 13 Jun 2016 06:59:56 +0000 (06:59 +0000)
- New NLRI parser for flowspec L3vpn

Change-Id: I6fe6985a46a2b1c2d9dc91dea6bd10282c0dc351
Signed-off-by: Kevin Wang <kevixw@gmail.com>
16 files changed:
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecNlriParser.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/BGPActivator.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecActivator.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParser.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParser.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv4/FlowspecIpv4NlriParserHelper.java [new file with mode: 0644]
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv6/FlowspecIpv6NlriParserHelper.java [new file with mode: 0644]
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java [new file with mode: 0644]
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4NlriParser.java [new file with mode: 0644]
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6NlriParser.java [new file with mode: 0644]
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/ActivatorTest.java
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java [new file with mode: 0644]
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv6NlriParserTest.java [new file with mode: 0644]
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParserTest.java
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParserTest.java

index 2e056354108ca745bf2f2015357967689db95828..541266784bad47de95140cad14b30a379da0c878 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.protocol.bgp.flowspec;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -80,7 +79,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 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.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
@@ -93,17 +94,18 @@ 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.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSerializer {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractFlowspecNlriParser.class);
 
     @VisibleForTesting
     static final NodeIdentifier FLOWSPEC_NID = new NodeIdentifier(Flowspec.QNAME);
     @VisibleForTesting
-    protected static final NodeIdentifier FLOWSPEC_TYPE_NID = new NodeIdentifier(FlowspecType.QNAME);
-    @VisibleForTesting
-    static final NodeIdentifier DEST_PREFIX_NID = new NodeIdentifier(QName.create(DestinationPrefixCase.QNAME, "destination-prefix").intern());
-    @VisibleForTesting
-    static final NodeIdentifier SOURCE_PREFIX_NID = new NodeIdentifier(QName.create(SourcePrefixCase.QNAME, "source-prefix").intern());
+    static final NodeIdentifier FLOWSPEC_TYPE_NID = new NodeIdentifier(FlowspecType.QNAME);
+    public static final NodeIdentifier DEST_PREFIX_NID = new NodeIdentifier(QName.create(DestinationPrefixCase.QNAME, "destination-prefix").intern());
+    public static final NodeIdentifier SOURCE_PREFIX_NID = new NodeIdentifier(QName.create(SourcePrefixCase.QNAME, "source-prefix").intern());
     @VisibleForTesting
     static final NodeIdentifier PORTS_NID = new NodeIdentifier(Ports.QNAME);
     @VisibleForTesting
@@ -123,9 +125,9 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
     @VisibleForTesting
     static final NodeIdentifier FRAGMENT_NID = new NodeIdentifier(Fragments.QNAME);
     @VisibleForTesting
-    static final NodeIdentifier OP_NID = new NodeIdentifier(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-flowspec","2015-08-07","op"));
+    public static final NodeIdentifier OP_NID = new NodeIdentifier(QName.create(Flowspec.QNAME.getNamespace(), Flowspec.QNAME.getRevision(), "op"));
     @VisibleForTesting
-    static final NodeIdentifier VALUE_NID = new NodeIdentifier(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-flowspec","2015-08-07","value"));
+    public static final NodeIdentifier VALUE_NID = new NodeIdentifier(QName.create(Flowspec.QNAME.getNamespace(), Flowspec.QNAME.getRevision(), "value"));
 
     protected static final int NLRI_LENGTH = 1;
     protected static final int NLRI_LENGTH_EXTENDED = 2;
@@ -135,9 +137,9 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
     /**
      * Add this constant to length value to achieve all ones in the leftmost nibble.
      */
-    private static final int LENGTH_MAGIC = 61440;
-    private static final int MAX_NLRI_LENGTH = 4095;
-    private static final int MAX_NLRI_LENGTH_ONE_BYTE = 240;
+    protected static final int LENGTH_MAGIC = 61440;
+    protected static final int MAX_NLRI_LENGTH = 4095;
+    protected static final int MAX_NLRI_LENGTH_ONE_BYTE = 240;
 
     @VisibleForTesting
     static final String DO_NOT_VALUE = "do-not";
@@ -150,17 +152,35 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
 
     private static final String FLOW_SEPARATOR = " AND ";
 
-    protected abstract void serializeMpReachNlri(final Attributes1 pathAttributes, final ByteBuf byteAggregator);
+    protected AbstractFlowspecNlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
+        this.flowspecTypeRegistry = Preconditions.checkNotNull(flowspecTypeRegistry);
+    }
+
+    protected abstract void serializeMpReachNlri(final DestinationType dstType, final ByteBuf byteAggregator);
 
-    protected abstract void serializeMpUnreachNlri(final Attributes2 pathAttributes, final ByteBuf byteAggregator);
+    protected abstract void serializeMpUnreachNlri(final DestinationType dstType, final ByteBuf byteAggregator);
 
     public abstract void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder);
 
     protected abstract void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer);
 
-    abstract DestinationType createWithdrawnDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId);
+    /**
+     * Create withdrawn destination type
+     *
+     * @param nlriFields a list of NLRI fields to be included in the destination type
+     * @param pathId     associated path id with given NLRI
+     * @return created destination type
+     */
+    protected abstract DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId);
 
-    abstract DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId);
+    /**
+     * Create advertized destination type
+     *
+     * @param nlriFields a list of NLRI fields to be included in the destination type
+     * @param pathId     associated path id with given NLRI
+     * @return created destination type
+     */
+    protected abstract DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId);
 
     @Override
     public final void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
@@ -168,8 +188,20 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         final Attributes pathAttributes = (Attributes) attribute;
         final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class);
         final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class);
-        serializeMpReachNlri(pathAttributes1, byteAggregator);
-        serializeMpUnreachNlri(pathAttributes2, byteAggregator);
+
+        if (pathAttributes1 != null) {
+            final AdvertizedRoutes routes = (pathAttributes1.getMpReachNlri()).getAdvertizedRoutes();
+            if (routes != null) {
+                serializeMpReachNlri(routes.getDestinationType(), byteAggregator);
+            }
+        }
+
+        if (pathAttributes2 != null) {
+            final WithdrawnRoutes routes = pathAttributes2.getMpUnreachNlri().getWithdrawnRoutes();
+            if (routes != null) {
+                serializeMpUnreachNlri(routes.getDestinationType(), byteAggregator);
+            }
+        }
     }
 
     @Override
@@ -182,19 +214,32 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         parseNlri(nlri, builder, null);
     }
 
+    protected void serializeNlri(@Nonnull final Object[] nlriFields, @Nonnull final ByteBuf buffer) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
+        serializeNlri(flowspecList, buffer);
+    }
+
+    protected final void serializeNlri(final List<Flowspec> flowspecList, @Nonnull final ByteBuf buffer) {
+        if (flowspecList != null) {
+            for (final Flowspec flow : flowspecList) {
+                this.flowspecTypeRegistry.serializeFlowspecType(flow.getFlowspecType(), buffer);
+            }
+        }
+    }
+
     /**
      * Serializes Flowspec NLRI to ByteBuf.
-     *  @param flows flowspec NLRI to be serialized
+     *
+     * @param nlriFields NLRI fields to be serialized
      * @param pathId
-     * @param buffer where flowspec NLRI will be serialized
+     * @param buffer     where flowspec NLRI will be serialized
      */
-    public final void serializeNlri(final List<Flowspec> flows, final PathId pathId, final ByteBuf buffer) {
+    protected final void serializeNlri(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId, @Nonnull final ByteBuf buffer) {
         final ByteBuf nlriByteBuf = Unpooled.buffer();
         PathIdUtil.writePathId(pathId, buffer);
 
-        for (final Flowspec flow : flows) {
-            this.flowspecTypeRegistry.serializeFlowspecType(flow.getFlowspecType(), nlriByteBuf);
-        }
+        serializeNlri(nlriFields, nlriByteBuf);
+
         Preconditions.checkState(nlriByteBuf.readableBytes() <= MAX_NLRI_LENGTH, "Maximum length of Flowspec NLRI reached.");
         if (nlriByteBuf.readableBytes() <= MAX_NLRI_LENGTH_ONE_BYTE) {
             buffer.writeByte(nlriByteBuf.readableBytes());
@@ -204,15 +249,16 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         buffer.writeBytes(nlriByteBuf);
     }
 
-    public final String stringNlri(final DataContainerNode<?> flowspec) {
+    public String stringNlri(final DataContainerNode<?> flowspec) {
         return stringNlri(extractFlowspec(flowspec));
     }
 
     public final List<Flowspec> extractFlowspec(final DataContainerNode<?> route) {
+        Preconditions.checkNotNull(route, "Cannot extract flowspec from null route.");
         final List<Flowspec> fsList = new ArrayList<>();
         final Optional<DataContainerChild<? extends PathArgument, ?>> flowspecs = route.getChild(FLOWSPEC_NID);
         if (flowspecs.isPresent()) {
-            for (final UnkeyedListEntryNode flowspec : ((UnkeyedListNode)flowspecs.get()).getValue()) {
+            for (final UnkeyedListEntryNode flowspec : ((UnkeyedListNode) flowspecs.get()).getValue()) {
                 final FlowspecBuilder fsBuilder = new FlowspecBuilder();
                 final Optional<DataContainerChild<?, ?>> flowspecType = flowspec.getChild(FLOWSPEC_TYPE_NID);
                 if (flowspecType.isPresent()) {
@@ -424,15 +470,10 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         return new Fragment(data.contains(DO_NOT_VALUE), data.contains(FIRST_VALUE), data.contains(IS_A_VALUE), data.contains(LAST_VALUE));
     }
 
-    final String stringNlri(final List<Flowspec> flows) {
+    protected final String stringNlri(final List<Flowspec> flows) {
         final StringBuilder buffer = new StringBuilder("all packets ");
         final Joiner joiner = Joiner.on(FLOW_SEPARATOR);
-        joiner.appendTo(buffer, Iterables.transform(flows, new Function<Flowspec, String>() {
-            @Override
-            public String apply(final Flowspec input) {
-                return encodeFlow(input);
-            }
-        }));
+        joiner.appendTo(buffer, Iterables.transform(flows, fs -> encodeFlow(fs)));
         return buffer.toString().replace("  ", " ");
     }
 
@@ -534,17 +575,12 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
      * @param nlri byte representation of NLRI which will be parsed
      * @return list of Flowspec
      */
-    public final List<Flowspec> parseNlri(final ByteBuf nlri) throws BGPParsingException {
+    protected final List<Flowspec> parseNlriFlowspecList(@Nonnull final ByteBuf nlri) throws BGPParsingException {
         if (!nlri.isReadable()) {
             return null;
         }
         final List<Flowspec> fss = new ArrayList<>();
 
-        // length field can be one or two bytes (if needed)
-        // check the length of nlri to see how many bytes we can skip
-        final int length = nlri.readableBytes();
-        nlri.skipBytes(length > MAX_NLRI_LENGTH_ONE_BYTE ? NLRI_LENGTH_EXTENDED : NLRI_LENGTH);
-
         while (nlri.isReadable()) {
             final FlowspecBuilder builder = new FlowspecBuilder();
             builder.setFlowspecType(this.flowspecTypeRegistry.parseFlowspecType(nlri));
@@ -553,19 +589,56 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         return fss;
     }
 
+    /**
+     * This step is used to verify the NLRI length we read from BGP message
+     *
+     * @param nlri
+     */
+    private static final void verifyNlriLength(@Nonnull final ByteBuf nlri) {
+        // length field can be one or two bytes (if needed)
+        // check the length of nlri to see how many bytes we can skip
+        int readableLength = nlri.readableBytes();
+        final int expectedLength;    // read the length from field
+        if (readableLength > MAX_NLRI_LENGTH_ONE_BYTE) {
+            expectedLength = nlri.readUnsignedShort();
+            readableLength -= NLRI_LENGTH_EXTENDED;    // deduct the two bytes of the NLRI length field
+        } else {
+            expectedLength = nlri.readUnsignedByte();
+            readableLength -= NLRI_LENGTH;    // deduct the one byte of the NLRI length field
+        }
+        Preconditions.checkState(readableLength == expectedLength, "NLRI length read from message doesn't match. Length expected (read from NLRI) is %s, length readable is %s", expectedLength, readableLength);
+    }
+
+    /**
+     * Override this function to parse additional NLRI fields
+     *
+     * @param nlri NLRI buffer
+     * @return Parsed additional fields
+     */
+    @Nonnull
+    protected Object[] parseNlri(@Nonnull final ByteBuf nlri) throws BGPParsingException {
+        return new Object[] {parseNlriFlowspecList(nlri)};
+    }
 
     @Override
-    public void parseNlri(@Nonnull final ByteBuf nlri, @Nonnull final MpReachNlriBuilder builder, @Nullable final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+    public final void parseNlri(@Nonnull final ByteBuf nlri, @Nonnull final MpReachNlriBuilder builder, @Nullable final PeerSpecificParserConstraint constraint)
+        throws BGPParsingException {
         if (!nlri.isReadable()) {
             return;
         }
         final PathId pathId = readPathId(nlri, builder.getAfi(), builder.getSafi(), constraint);
-        final List<Flowspec> dst = parseNlri(nlri);
-        builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder()
-            .setDestinationType(createAdvertizedRoutesDestinationType(dst, pathId)).build());
+        verifyNlriLength(nlri);
+        final Object[] nlriFields = parseNlri(nlri);
+        builder.setAdvertizedRoutes(
+            new AdvertizedRoutesBuilder()
+                .setDestinationType(
+                    createAdvertizedRoutesDestinationType(nlriFields, pathId)
+                ).build()
+        );
     }
 
-    private PathId readPathId(final ByteBuf nlri, final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi,
+    @Nullable
+    protected final PathId readPathId(@Nonnull final ByteBuf nlri, final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi,
         final PeerSpecificParserConstraint constraint) {
         if (MultiPathSupportUtil.isTableTypeSupported(constraint, new BgpTableTypeImpl(afi, safi))) {
             return PathIdUtil.readPathId(nlri);
@@ -573,14 +646,21 @@ public abstract class AbstractFlowspecNlriParser implements NlriParser, NlriSeri
         return null;
     }
 
-
     @Override
-    public void parseNlri(@Nonnull final ByteBuf nlri, @Nonnull final MpUnreachNlriBuilder builder, @Nullable final PeerSpecificParserConstraint constraint) throws BGPParsingException {
+    public final void parseNlri(@Nonnull final ByteBuf nlri, @Nonnull final MpUnreachNlriBuilder builder, @Nullable final PeerSpecificParserConstraint constraint)
+        throws BGPParsingException {
         if (!nlri.isReadable()) {
             return;
         }
         final PathId pathId = readPathId(nlri, builder.getAfi(), builder.getSafi(), constraint);
-        final List<Flowspec> dst = parseNlri(nlri);
-        builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(createWithdrawnDestinationType(dst, pathId)).build());
+        verifyNlriLength(nlri);
+        final Object[] nlriFields = parseNlri(nlri);
+        builder.setWithdrawnRoutes(
+            new WithdrawnRoutesBuilder()
+                .setDestinationType(
+                    createWithdrawnDestinationType(nlriFields, pathId)
+                ).build()
+        );
     }
 }
+
index 1dd63ef3fd66efabb73f000eb8df798b627e96c1..a7a244b6f3f3960ba29e62d18dd3d460fb9b2668 100644 (file)
@@ -59,7 +59,7 @@ public abstract class AbstractFlowspecRIBSupport extends MultiPathAbstractRIBSup
     protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
         final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
         final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        return getParser().createAdvertizedRoutesDestinationType(getParser().extractFlowspec(routesCont), pathId);
+        return getParser().createAdvertizedRoutesDestinationType(new Object[] {getParser().extractFlowspec(routesCont)}, pathId);
     }
 
     @Nonnull
@@ -67,7 +67,7 @@ public abstract class AbstractFlowspecRIBSupport extends MultiPathAbstractRIBSup
     protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
         final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
         final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        return getParser().createWithdrawnDestinationType(getParser().extractFlowspec(Iterables.getOnlyElement(routes)), pathId);
+        return getParser().createWithdrawnDestinationType(new Object[] {getParser().extractFlowspec(Iterables.getOnlyElement(routes))}, pathId);
     }
 
     @Override
index 1a229cda9ff66fcc9d006a1600e634577b87cbaa..707fe1e94693cdc1482db16a90ad5399fa149b5a 100644 (file)
@@ -17,6 +17,8 @@ import org.opendaylight.protocol.bgp.flowspec.extended.communities.RedirectIpv6E
 import org.opendaylight.protocol.bgp.flowspec.extended.communities.TrafficActionEcHandler;
 import org.opendaylight.protocol.bgp.flowspec.extended.communities.TrafficMarkingEcHandler;
 import org.opendaylight.protocol.bgp.flowspec.extended.communities.TrafficRateEcHandler;
+import org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv4.FlowspecL3vpnIpv4NlriParser;
+import org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv6.FlowspecL3vpnIpv6NlriParser;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.next.hop.Ipv4NextHopParserSerializer;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.next.hop.Ipv6NextHopParserSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.AbstractBGPExtensionProviderActivator;
@@ -32,6 +34,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.bgp.rib.route.attributes.extended.communities.extended.community.TrafficMarkingExtendedCommunityCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.bgp.rib.route.attributes.extended.communities.extended.community.TrafficRateExtendedCommunityCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv6.routes.FlowspecIpv6Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.ipv4.routes.FlowspecL3vpnIpv4Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.ipv6.routes.FlowspecL3vpnIpv6Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.routes.FlowspecRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
@@ -59,19 +63,39 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerSubsequentAddressFamily(FlowspecSubsequentAddressFamily.class, FLOWSPEC_SAFI));
         regs.add(context.registerSubsequentAddressFamily(FlowspecL3vpnSubsequentAddressFamily.class, FLOWSPEC_L3VPN_SAFI));
 
-        final SimpleFlowspecIpv4NlriParser fsIpv4Handler = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
-        final SimpleFlowspecIpv6NlriParser fsIpv6Handler = new SimpleFlowspecIpv6NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
-
         final Ipv4NextHopParserSerializer ipv4NextHopParser = new Ipv4NextHopParserSerializer();
         final Ipv6NextHopParserSerializer ipv6NextHopParser = new Ipv6NextHopParserSerializer();
 
-        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class,
-                fsIpv4Handler, ipv4NextHopParser, Ipv4NextHopCase.class));
-        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class,
-                fsIpv6Handler, ipv6NextHopParser, Ipv6NextHopCase.class));
+        final SimpleFlowspecIpv4NlriParser fsIpv4Handler = new SimpleFlowspecIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        final SimpleFlowspecIpv6NlriParser fsIpv6Handler = new SimpleFlowspecIpv6NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        regs.add(
+            context.registerNlriParser(
+                Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class, fsIpv4Handler, ipv4NextHopParser, Ipv4NextHopCase.class
+            )
+        );
+        regs.add(
+            context.registerNlriParser(
+                Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class, fsIpv6Handler, ipv6NextHopParser, Ipv6NextHopCase.class
+            )
+        );
         regs.add(context.registerNlriSerializer(FlowspecRoutes.class, fsIpv4Handler));
         regs.add(context.registerNlriSerializer(FlowspecIpv6Routes.class, fsIpv6Handler));
 
+        final FlowspecL3vpnIpv4NlriParser fsL3vpnIpv4Handler = new FlowspecL3vpnIpv4NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+        final FlowspecL3vpnIpv6NlriParser fsL3vpnIpv6Handler = new FlowspecL3vpnIpv6NlriParser(this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+        regs.add(
+            context.registerNlriParser(
+                Ipv4AddressFamily.class, FlowspecL3vpnSubsequentAddressFamily.class, fsL3vpnIpv4Handler, ipv4NextHopParser, Ipv4NextHopCase.class
+            )
+        );
+        regs.add(
+            context.registerNlriParser(
+                Ipv6AddressFamily.class, FlowspecL3vpnSubsequentAddressFamily.class, fsL3vpnIpv6Handler, ipv6NextHopParser, Ipv6NextHopCase.class
+            )
+        );
+        regs.add(context.registerNlriSerializer(FlowspecL3vpnIpv4Routes.class, fsL3vpnIpv4Handler));
+        regs.add(context.registerNlriSerializer(FlowspecL3vpnIpv6Routes.class, fsL3vpnIpv6Handler));
+
         final RedirectAsTwoOctetEcHandler redirect2bHandler = new RedirectAsTwoOctetEcHandler();
         regs.add(context.registerExtendedCommunityParser(redirect2bHandler.getType(true), redirect2bHandler.getSubType(), redirect2bHandler));
         regs.add(context.registerExtendedCommunitySerializer(RedirectExtendedCommunityCase.class, redirect2bHandler));
index 50fc6ae2a517e4d252bf4dc6539d05c9d4b563aa..ac131f5cf657a030cf455e6b4b4b40b524360faf 100644 (file)
@@ -42,29 +42,29 @@ public final class FlowspecActivator implements AutoCloseable {
     public FlowspecActivator(final SimpleFlowspecExtensionProviderContext context) {
         for (SimpleFlowspecExtensionProviderContext.SAFI safi : SimpleFlowspecExtensionProviderContext.SAFI.values()) {
             registerCommonFlowspecTypeHandlers(
-                    SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                    safi,
-                    registrations,
-                    context
+                SimpleFlowspecExtensionProviderContext.AFI.IPV4,
+                safi,
+                registrations,
+                context
             );
             registerIpv4FlowspecTypeHandlers(
-                    SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                    safi,
-                    registrations,
-                    context
+                SimpleFlowspecExtensionProviderContext.AFI.IPV4,
+                safi,
+                registrations,
+                context
             );
 
             registerCommonFlowspecTypeHandlers(
-                    SimpleFlowspecExtensionProviderContext.AFI.IPV6,
-                    safi,
-                    registrations,
-                    context
+                SimpleFlowspecExtensionProviderContext.AFI.IPV6,
+                safi,
+                registrations,
+                context
             );
             registerIpv6FlowspecTypeHandlers(
-                    SimpleFlowspecExtensionProviderContext.AFI.IPV6,
-                    safi,
-                    registrations,
-                    context
+                SimpleFlowspecExtensionProviderContext.AFI.IPV6,
+                safi,
+                registrations,
+                context
             );
         }
     }
@@ -76,10 +76,10 @@ public final class FlowspecActivator implements AutoCloseable {
      * @param safi
      */
     private void registerCommonFlowspecTypeHandlers(
-            final SimpleFlowspecExtensionProviderContext.AFI afi,
-            final SimpleFlowspecExtensionProviderContext.SAFI safi,
-            final List<AutoCloseable> regs,
-            final SimpleFlowspecExtensionProviderContext context
+        final SimpleFlowspecExtensionProviderContext.AFI afi,
+        final SimpleFlowspecExtensionProviderContext.SAFI safi,
+        final List<AutoCloseable> regs,
+        final SimpleFlowspecExtensionProviderContext context
     ) {
         final SimpleFlowspecTypeRegistry flowspecTypeRegistry = context.getFlowspecTypeRegistry(afi, safi);
 
@@ -117,10 +117,10 @@ public final class FlowspecActivator implements AutoCloseable {
     }
 
     protected void registerIpv4FlowspecTypeHandlers(
-            final SimpleFlowspecExtensionProviderContext.AFI afi,
-            final SimpleFlowspecExtensionProviderContext.SAFI safi,
-            final List<AutoCloseable> regs,
-            final SimpleFlowspecExtensionProviderContext context
+        final SimpleFlowspecExtensionProviderContext.AFI afi,
+        final SimpleFlowspecExtensionProviderContext.SAFI safi,
+        final List<AutoCloseable> regs,
+        final SimpleFlowspecExtensionProviderContext context
     ) {
         final SimpleFlowspecTypeRegistry flowspecTypeRegistry = context.getFlowspecTypeRegistry(afi, safi);
 
@@ -142,10 +142,10 @@ public final class FlowspecActivator implements AutoCloseable {
     }
 
     protected void registerIpv6FlowspecTypeHandlers(
-            final SimpleFlowspecExtensionProviderContext.AFI afi,
-            final SimpleFlowspecExtensionProviderContext.SAFI safi,
-            final List<AutoCloseable> regs,
-            final SimpleFlowspecExtensionProviderContext context
+        final SimpleFlowspecExtensionProviderContext.AFI afi,
+        final SimpleFlowspecExtensionProviderContext.SAFI safi,
+        final List<AutoCloseable> regs,
+        final SimpleFlowspecExtensionProviderContext context
     ) {
         final SimpleFlowspecTypeRegistry flowspecTypeRegistry = context.getFlowspecTypeRegistry(afi, safi);
 
index 483f6707722baab5deffff2385308f731739caa3..b6a08f8e6665b5b51d8b2e8b88fd9ddea3a33f50 100644 (file)
  */
 package org.opendaylight.protocol.bgp.flowspec;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
 import io.netty.buffer.ByteBuf;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.opendaylight.protocol.bgp.flowspec.handlers.NumericOneByteOperandParser;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.protocol.bgp.flowspec.ipv4.FlowspecIpv4NlriParserHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.DestinationFlowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv4.DestinationFlowspecBuilder;
 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.multiprotocol.rev130919.Attributes1;
-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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 
 public final class SimpleFlowspecIpv4NlriParser extends AbstractFlowspecNlriParser {
 
-    @VisibleForTesting
-    static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
-
     public SimpleFlowspecIpv4NlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
-        this.flowspecTypeRegistry = flowspecTypeRegistry;
+        super(flowspecTypeRegistry);
     }
 
     @Override
-    protected DestinationType createWithdrawnDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId) {
+    protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
-                .setDestinationFlowspec(
-                        new DestinationFlowspecBuilder()
-                                .setFlowspec(dst)
-                                .setPathId(pathId)
-                                .build()
-                ).build();
+            .setDestinationFlowspec(
+                new DestinationFlowspecBuilder()
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
     }
 
     @Override
-    protected DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId) {
+    protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
-                .setDestinationFlowspec(
-                        new DestinationFlowspecBuilder()
-                                .setFlowspec(dst)
-                                .setPathId(pathId)
-                                .build()
-                ).build();
+            .setDestinationFlowspec(
+                new DestinationFlowspecBuilder()
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
     }
 
     @Override
-    protected void serializeMpReachNlri(final Attributes1 pathAttributes, final ByteBuf byteAggregator) {
-        if (pathAttributes == null) {
-            return;
-        }
-        final AdvertizedRoutes routes = (pathAttributes.getMpReachNlri()).getAdvertizedRoutes();
-        if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) {
-            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) routes.getDestinationType())
-                    .getDestinationFlowspec();
-            serializeNlri(destFlowspec.getFlowspec(), destFlowspec.getPathId(), byteAggregator);
+    protected void serializeMpReachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) {
+            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) dstType)
+                .getDestinationFlowspec();
+            serializeNlri(new Object[] {destFlowspec.getFlowspec()}, destFlowspec.getPathId(), byteAggregator);
         }
     }
 
     @Override
     public void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
-        if (fsType.getChild(DEST_PREFIX_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
-                    new Ipv4Prefix((String) fsType.getChild(DEST_PREFIX_NID).get().getValue())).build());
-        } else if (fsType.getChild(SOURCE_PREFIX_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix((String) fsType.getChild(SOURCE_PREFIX_NID).get().getValue()))
-                    .build());
-        } else if (fsType.getChild(PROTOCOL_IP_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(createProtocolsIps((UnkeyedListNode) fsType.getChild(PROTOCOL_IP_NID).get())).build());
-        }
-    }
-
-    private static List<ProtocolIps> createProtocolsIps(final UnkeyedListNode protocolIpsData) {
-        final List<ProtocolIps> protocolIps = new ArrayList<>();
-
-        for (final UnkeyedListEntryNode node : protocolIpsData.getValue()) {
-            final ProtocolIpsBuilder ipsBuilder = new ProtocolIpsBuilder();
-            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
-            if (opValue.isPresent()) {
-                ipsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
-            }
-            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
-            if (valueNode.isPresent()) {
-                ipsBuilder.setValue((Short) valueNode.get().getValue());
-            }
-            protocolIps.add(ipsBuilder.build());
-        }
-
-        return protocolIps;
+        FlowspecIpv4NlriParserHelper.extractFlowspec(fsType, fsBuilder);
     }
 
     @Override
     protected void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer) {
-        if (value instanceof DestinationPrefixCase) {
-            buffer.append("to ");
-            buffer.append(((DestinationPrefixCase) value).getDestinationPrefix().getValue());
-        } else if (value instanceof SourcePrefixCase) {
-            buffer.append("from ");
-            buffer.append(((SourcePrefixCase) value).getSourcePrefix().getValue());
-        } else if (value instanceof ProtocolIpCase) {
-            buffer.append("where IP protocol ");
-            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(((ProtocolIpCase) value).getProtocolIps()));
-        }
+        FlowspecIpv4NlriParserHelper.buildFlowspecString(value, buffer);
     }
 
     @Override
-    protected void serializeMpUnreachNlri(final Attributes2 pathAttributes, final ByteBuf byteAggregator) {
-        if (pathAttributes == null) {
-            return;
-        }
-        final WithdrawnRoutes routes = pathAttributes.getMpUnreachNlri().getWithdrawnRoutes();
-        if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) {
-            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) routes.getDestinationType())
-                    .getDestinationFlowspec();
-            serializeNlri(destFlowspec.getFlowspec(), destFlowspec.getPathId(), byteAggregator);
+    protected void serializeMpUnreachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) {
+            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) dstType)
+                .getDestinationFlowspec();
+            serializeNlri(new Object[] {destFlowspec.getFlowspec()}, destFlowspec.getPathId(), byteAggregator);
         }
     }
 }
+
index a578df8bbd5636bd675829b56b9c831f2bf0e1e0..3acc478e95ab5363bf873934a8254ee597f14eec 100644 (file)
  */
 package org.opendaylight.protocol.bgp.flowspec;
 
-import com.google.common.base.Optional;
 import io.netty.buffer.ByteBuf;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.opendaylight.protocol.bgp.flowspec.handlers.NumericOneByteOperandParser;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.protocol.bgp.flowspec.ipv6.FlowspecIpv6NlriParserHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabelBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeaders;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeadersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv6.DestinationFlowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv6.DestinationFlowspecBuilder;
 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.multiprotocol.rev130919.Attributes1;
-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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 
 public final class SimpleFlowspecIpv6NlriParser extends AbstractFlowspecNlriParser {
 
-    static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
-    static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
-
     public SimpleFlowspecIpv6NlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
-        this.flowspecTypeRegistry = flowspecTypeRegistry;
+        super(flowspecTypeRegistry);
     }
 
     @Override
-    protected DestinationType createWithdrawnDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId) {
+    protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                .setDestinationFlowspec(
-                        new DestinationFlowspecBuilder()
-                                .setFlowspec(dst)
-                                .setPathId(pathId)
-                                .build()
-                ).build();
+            .setDestinationFlowspec(
+                new DestinationFlowspecBuilder()
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
     }
 
     @Override
-    protected DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId) {
+    protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                .setDestinationFlowspec(
-                        new DestinationFlowspecBuilder()
-                                .setFlowspec(dst)
-                                .setPathId(pathId)
-                                .build()
-                ).build();
-    }
-
-    @Override
-    protected void serializeMpReachNlri(final Attributes1 pathAttributes, final ByteBuf byteAggregator) {
-        if (pathAttributes == null) {
-            return;
-        }
-        final AdvertizedRoutes routes = (pathAttributes.getMpReachNlri()).getAdvertizedRoutes();
-        if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) {
-            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) routes.getDestinationType())
-                    .getDestinationFlowspec();
-            serializeNlri(destFlowspec.getFlowspec(), destFlowspec.getPathId(), byteAggregator);
-        }
+            .setDestinationFlowspec(
+                new DestinationFlowspecBuilder()
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
     }
 
     @Override
     public void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
-        if (fsType.getChild(DEST_PREFIX_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new DestinationIpv6PrefixCaseBuilder()
-                    .setDestinationPrefix(new Ipv6Prefix((String) fsType.getChild(DEST_PREFIX_NID).get().getValue()))
-                    .build());
-        } else if (fsType.getChild(SOURCE_PREFIX_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new SourceIpv6PrefixCaseBuilder()
-                    .setSourcePrefix(new Ipv6Prefix((String) fsType.getChild(SOURCE_PREFIX_NID).get().getValue()))
-                    .build());
-        } else if (fsType.getChild(NEXT_HEADER_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(createNextHeaders((UnkeyedListNode) fsType.getChild(NEXT_HEADER_NID).get())).build());
-        } else if (fsType.getChild(FLOW_LABEL_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(createFlowLabels((UnkeyedListNode) fsType.getChild(FLOW_LABEL_NID).get())).build());
-        }
-    }
-
-    private List<NextHeaders> createNextHeaders(final UnkeyedListNode nextHeadersData) {
-        final List<NextHeaders> nextHeaders = new ArrayList<>();
-
-        for (final UnkeyedListEntryNode node : nextHeadersData.getValue()) {
-            final NextHeadersBuilder nextHeadersBuilder = new NextHeadersBuilder();
-            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
-            if (opValue.isPresent()) {
-                nextHeadersBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
-            }
-            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
-            if (valueNode.isPresent()) {
-                nextHeadersBuilder.setValue((Short) valueNode.get().getValue());
-            }
-            nextHeaders.add(nextHeadersBuilder.build());
-        }
-
-        return nextHeaders;
-    }
-
-    private List<FlowLabel> createFlowLabels(final UnkeyedListNode flowLabelsData) {
-        final List<FlowLabel> flowLabels = new ArrayList<>();
-
-        for (final UnkeyedListEntryNode node : flowLabelsData.getValue()) {
-            final FlowLabelBuilder flowLabelsBuilder = new FlowLabelBuilder();
-            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
-            if (opValue.isPresent()) {
-                flowLabelsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
-            }
-            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
-            if (valueNode.isPresent()) {
-                flowLabelsBuilder.setValue((Long) valueNode.get().getValue());
-            }
-            flowLabels.add(flowLabelsBuilder.build());
-        }
-
-        return flowLabels;
+        FlowspecIpv6NlriParserHelper.extractFlowspec(fsType, fsBuilder);
     }
 
     @Override
     protected void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer) {
-        if (value instanceof DestinationIpv6PrefixCase) {
-            buffer.append("to ");
-            buffer.append(((DestinationIpv6PrefixCase) value).getDestinationPrefix().getValue());
-        } else if (value instanceof SourceIpv6PrefixCase) {
-            buffer.append("from ");
-            buffer.append(((SourceIpv6PrefixCase) value).getSourcePrefix().getValue());
-        } else if (value instanceof NextHeaderCase) {
-            buffer.append("where next header ");
-            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(((NextHeaderCase) value).getNextHeaders()));
-        } else if (value instanceof FlowLabelCase) {
-            buffer.append("where flow label ");
-            buffer.append(stringFlowLabel(((FlowLabelCase) value).getFlowLabel()));
-        }
+        FlowspecIpv6NlriParserHelper.buildFlowspecString(value, buffer);
     }
 
-    private static String stringFlowLabel(final List<FlowLabel> list) {
-        final StringBuilder buffer = new StringBuilder();
-        boolean isFirst = true;
-        for (final FlowLabel item : list) {
-            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(item.getOp(), isFirst));
-            buffer.append(item.getValue());
-            buffer.append(' ');
-            if (isFirst) {
-                isFirst = false;
-            }
+    @Override
+    protected void serializeMpReachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) {
+            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) dstType)
+                .getDestinationFlowspec();
+            serializeNlri(new Object[] {destFlowspec.getFlowspec()}, destFlowspec.getPathId(), byteAggregator);
         }
-        return buffer.toString();
     }
 
     @Override
-    protected void serializeMpUnreachNlri(final Attributes2 pathAttributes, final ByteBuf byteAggregator) {
-        if (pathAttributes == null) {
-            return;
-        }
-        final WithdrawnRoutes routes = (pathAttributes.getMpUnreachNlri()).getWithdrawnRoutes();
-        if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) {
-            final DestinationFlowspec flowspecCase = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) routes.getDestinationType())
-                    .getDestinationFlowspec();
-            serializeNlri(flowspecCase.getFlowspec(), flowspecCase.getPathId(), byteAggregator);
+    protected void serializeMpUnreachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) {
+            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) dstType)
+                .getDestinationFlowspec();
+            serializeNlri(new Object[] {destFlowspec.getFlowspec()}, destFlowspec.getPathId(), byteAggregator);
         }
     }
 }
+
diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv4/FlowspecIpv4NlriParserHelper.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv4/FlowspecIpv4NlriParserHelper.java
new file mode 100644 (file)
index 0000000..4d7b638
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.flowspec.ipv4;
+
+import com.google.common.base.Optional;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecNlriParser;
+import org.opendaylight.protocol.bgp.flowspec.handlers.NumericOneByteOperandParser;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+
+/**
+ * @author Kevin Wang
+ */
+public class FlowspecIpv4NlriParserHelper {
+
+    private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
+
+    private FlowspecIpv4NlriParserHelper() {}
+
+    public static final void extractFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
+        if (fsType.getChild(AbstractFlowspecNlriParser.DEST_PREFIX_NID).isPresent()) {
+            fsBuilder.setFlowspecType(
+                new DestinationPrefixCaseBuilder()
+                    .setDestinationPrefix(
+                        new Ipv4Prefix((String) fsType.getChild(AbstractFlowspecNlriParser.DEST_PREFIX_NID).get().getValue())
+                    ).build()
+            );
+        } else if (fsType.getChild(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).isPresent()) {
+            fsBuilder.setFlowspecType(
+                new SourcePrefixCaseBuilder()
+                    .setSourcePrefix(
+                        new Ipv4Prefix((String) fsType.getChild(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).get().getValue())
+                    ).build()
+            );
+        } else if (fsType.getChild(PROTOCOL_IP_NID).isPresent()) {
+            fsBuilder.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(createProtocolsIps((UnkeyedListNode) fsType.getChild(PROTOCOL_IP_NID).get())).build());
+        }
+    }
+
+    public static final void buildFlowspecString(final FlowspecType value, final StringBuilder buffer) {
+        if (value instanceof DestinationPrefixCase) {
+            buffer.append("to ");
+            buffer.append(((DestinationPrefixCase) value).getDestinationPrefix().getValue());
+        } else if (value instanceof SourcePrefixCase) {
+            buffer.append("from ");
+            buffer.append(((SourcePrefixCase) value).getSourcePrefix().getValue());
+        } else if (value instanceof ProtocolIpCase) {
+            buffer.append("where IP protocol ");
+            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(((ProtocolIpCase) value).getProtocolIps()));
+        }
+    }
+
+    private static final List<ProtocolIps> createProtocolsIps(final UnkeyedListNode protocolIpsData) {
+        final List<ProtocolIps> protocolIps = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : protocolIpsData.getValue()) {
+            final ProtocolIpsBuilder ipsBuilder = new ProtocolIpsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(AbstractFlowspecNlriParser.OP_NID);
+            if (opValue.isPresent()) {
+                ipsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(AbstractFlowspecNlriParser.VALUE_NID);
+            if (valueNode.isPresent()) {
+                ipsBuilder.setValue((Short) valueNode.get().getValue());
+            }
+            protocolIps.add(ipsBuilder.build());
+        }
+
+        return protocolIps;
+    }
+
+}
+
diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv6/FlowspecIpv6NlriParserHelper.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv6/FlowspecIpv6NlriParserHelper.java
new file mode 100644 (file)
index 0000000..3afa897
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.flowspec.ipv6;
+
+import com.google.common.base.Optional;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecNlriParser;
+import org.opendaylight.protocol.bgp.flowspec.handlers.NumericOneByteOperandParser;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabelBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeaders;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeadersBuilder;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+
+public final class FlowspecIpv6NlriParserHelper {
+
+    private static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
+    private static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
+
+    private FlowspecIpv6NlriParserHelper() {}
+
+    public static final void extractFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
+        if (fsType.getChild(AbstractFlowspecNlriParser.DEST_PREFIX_NID).isPresent()) {
+            fsBuilder.setFlowspecType(
+                new DestinationIpv6PrefixCaseBuilder()
+                    .setDestinationPrefix(new Ipv6Prefix((String) fsType.getChild(AbstractFlowspecNlriParser.DEST_PREFIX_NID).get().getValue()))
+                    .build()
+            );
+        } else if (fsType.getChild(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).isPresent()) {
+            fsBuilder.setFlowspecType(
+                new SourceIpv6PrefixCaseBuilder()
+                    .setSourcePrefix(new Ipv6Prefix((String) fsType.getChild(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).get().getValue()))
+                    .build()
+            );
+        } else if (fsType.getChild(NEXT_HEADER_NID).isPresent()) {
+            fsBuilder.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(createNextHeaders((UnkeyedListNode) fsType.getChild(NEXT_HEADER_NID).get())).build());
+        } else if (fsType.getChild(FLOW_LABEL_NID).isPresent()) {
+            fsBuilder.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(createFlowLabels((UnkeyedListNode) fsType.getChild(FLOW_LABEL_NID).get())).build());
+        }
+    }
+
+    public static final void buildFlowspecString(final FlowspecType value, final StringBuilder buffer) {
+        if (value instanceof DestinationIpv6PrefixCase) {
+            buffer.append("to ");
+            buffer.append(((DestinationIpv6PrefixCase) value).getDestinationPrefix().getValue());
+        } else if (value instanceof SourceIpv6PrefixCase) {
+            buffer.append("from ");
+            buffer.append(((SourceIpv6PrefixCase) value).getSourcePrefix().getValue());
+        } else if (value instanceof NextHeaderCase) {
+            buffer.append("where next header ");
+            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(((NextHeaderCase) value).getNextHeaders()));
+        } else if (value instanceof FlowLabelCase) {
+            buffer.append("where flow label ");
+            buffer.append(stringFlowLabel(((FlowLabelCase) value).getFlowLabel()));
+        }
+    }
+
+    private static final List<NextHeaders> createNextHeaders(final UnkeyedListNode nextHeadersData) {
+        final List<NextHeaders> nextHeaders = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : nextHeadersData.getValue()) {
+            final NextHeadersBuilder nextHeadersBuilder = new NextHeadersBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(AbstractFlowspecNlriParser.OP_NID);
+            if (opValue.isPresent()) {
+                nextHeadersBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(AbstractFlowspecNlriParser.VALUE_NID);
+            if (valueNode.isPresent()) {
+                nextHeadersBuilder.setValue((Short) valueNode.get().getValue());
+            }
+            nextHeaders.add(nextHeadersBuilder.build());
+        }
+
+        return nextHeaders;
+    }
+
+    private static final List<FlowLabel> createFlowLabels(final UnkeyedListNode flowLabelsData) {
+        final List<FlowLabel> flowLabels = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : flowLabelsData.getValue()) {
+            final FlowLabelBuilder flowLabelsBuilder = new FlowLabelBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(AbstractFlowspecNlriParser.OP_NID);
+            if (opValue.isPresent()) {
+                flowLabelsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(AbstractFlowspecNlriParser.VALUE_NID);
+            if (valueNode.isPresent()) {
+                flowLabelsBuilder.setValue((Long) valueNode.get().getValue());
+            }
+            flowLabels.add(flowLabelsBuilder.build());
+        }
+
+        return flowLabels;
+    }
+
+    private static final String stringFlowLabel(final List<FlowLabel> list) {
+        final StringBuilder buffer = new StringBuilder();
+        boolean isFirst = true;
+        for (final FlowLabel item : list) {
+            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(item.getOp(), isFirst));
+            buffer.append(item.getValue());
+            buffer.append(' ');
+            if (isFirst) {
+                isFirst = false;
+            }
+        }
+        return buffer.toString();
+    }
+}
+
diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java
new file mode 100644 (file)
index 0000000..2a754fd
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.flowspec.l3vpn;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecNlriParser;
+import org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecTypeRegistry;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Kevin Wang
+ */
+public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNlriParser {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractFlowspecL3vpnNlriParser.class);
+
+    private static final NodeIdentifier RD_NID = new NodeIdentifier(QName.create(Flowspec.QNAME.getNamespace(), Flowspec.QNAME.getRevision(), "route-distinguisher"));
+
+    protected AbstractFlowspecL3vpnNlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
+        super(flowspecTypeRegistry);
+    }
+
+    @Override
+    public String stringNlri(final DataContainerNode<?> flowspec) {
+        final StringBuilder buffer = new StringBuilder();
+        final RouteDistinguisher rd = extractRouteDistinguisher(flowspec);
+        if (rd != null) {
+            buffer.append("[l3vpn with route-distinguisher ").append(rd.getValue()).append("] ");
+        }
+        buffer.append(super.stringNlri(flowspec));
+        return buffer.toString();
+    }
+
+    public static final RouteDistinguisher extractRouteDistinguisher(final DataContainerNode<?> route) {
+        final Optional<DataContainerChild<? extends PathArgument, ?>> rdNode = route.getChild(RD_NID);
+        if (rdNode.isPresent()) {
+            return RouteDistinguisherUtil.parseRouteDistinguisher(rdNode.get().getValue());
+        }
+        return null;
+    }
+
+    /**
+     * For flowspec-l3vpn, there is a route distinguisher field at the beginning of NLRI (8 bytes)
+     *
+     * @param nlri
+     * @return
+     */
+    private static final RouteDistinguisher readRouteDistinguisher(final ByteBuf nlri) {
+        final RouteDistinguisher rd = RouteDistinguisherUtil.parseRouteDistinguisher(nlri);
+        LOG.trace("Route Distinguisher read from NLRI: {}", rd);
+        return rd;
+    }
+
+    @Override
+    protected void serializeNlri(@Nonnull final Object[] nlriFields, @Nonnull final ByteBuf buffer) {
+        final RouteDistinguisher rd = Preconditions.checkNotNull((RouteDistinguisher) nlriFields[0]);
+        RouteDistinguisherUtil.serializeRouteDistinquisher(rd, buffer);
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+        serializeNlri(flowspecList, buffer);
+    }
+
+    @Override
+    @Nonnull
+    protected Object[] parseNlri(@Nonnull final ByteBuf nlri) throws BGPParsingException {
+        return new Object[] {
+            Preconditions.checkNotNull(readRouteDistinguisher(nlri)),
+            parseNlriFlowspecList(nlri)
+        };
+    }
+}
+
diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4NlriParser.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4NlriParser.java
new file mode 100644 (file)
index 0000000..8ad5b9b
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.flowspec.l3vpn.ipv4;
+
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecTypeRegistry;
+import org.opendaylight.protocol.bgp.flowspec.ipv4.FlowspecIpv4NlriParserHelper;
+import org.opendaylight.protocol.bgp.flowspec.l3vpn.AbstractFlowspecL3vpnNlriParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4Builder;
+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.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+
+/**
+ * @author Kevin Wang
+ */
+public final class FlowspecL3vpnIpv4NlriParser extends AbstractFlowspecL3vpnNlriParser {
+
+    public FlowspecL3vpnIpv4NlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
+        super(flowspecTypeRegistry);
+    }
+
+    @Override
+    protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv4(
+                new DestinationFlowspecL3vpnIpv4Builder()
+                    .setRouteDistinguisher(rd)
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
+    }
+
+    @Override
+    protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv4(
+                new DestinationFlowspecL3vpnIpv4Builder()
+                    .setRouteDistinguisher(rd)
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
+    }
+
+    @Override
+    public void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
+        FlowspecIpv4NlriParserHelper.extractFlowspec(fsType, fsBuilder);
+    }
+
+    @Override
+    protected void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer) {
+        FlowspecIpv4NlriParserHelper.buildFlowspecString(value, buffer);
+    }
+
+    @Override
+    protected void serializeMpReachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) {
+            final DestinationFlowspecL3vpnIpv4 destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) dstType)
+                .getDestinationFlowspecL3vpnIpv4();
+            serializeNlri(
+                new Object[] {
+                    destFlowspec.getRouteDistinguisher(),
+                    destFlowspec.getFlowspec()
+                },
+                destFlowspec.getPathId(),
+                byteAggregator
+            );
+        }
+    }
+
+    @Override
+    protected void serializeMpUnreachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) {
+            final DestinationFlowspecL3vpnIpv4 destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) dstType)
+                .getDestinationFlowspecL3vpnIpv4();
+            serializeNlri(
+                new Object[] {
+                    destFlowspec.getRouteDistinguisher(),
+                    destFlowspec.getFlowspec()
+                },
+                destFlowspec.getPathId(),
+                byteAggregator
+            );
+        }
+    }
+}
diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6NlriParser.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6NlriParser.java
new file mode 100644 (file)
index 0000000..c5e3ad1
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.flowspec.l3vpn.ipv6;
+
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecTypeRegistry;
+import org.opendaylight.protocol.bgp.flowspec.ipv6.FlowspecIpv6NlriParserHelper;
+import org.opendaylight.protocol.bgp.flowspec.l3vpn.AbstractFlowspecL3vpnNlriParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6Builder;
+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.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+
+/**
+ * @author Kevin Wang
+ */
+public final class FlowspecL3vpnIpv6NlriParser extends AbstractFlowspecL3vpnNlriParser {
+
+    public FlowspecL3vpnIpv6NlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
+        super(flowspecTypeRegistry);
+    }
+
+    @Override
+    protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv6(
+                new DestinationFlowspecL3vpnIpv6Builder()
+                    .setRouteDistinguisher(rd)
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
+    }
+
+    @Override
+    protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final RouteDistinguisher rd = (RouteDistinguisher) nlriFields[0];
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[1];
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+            .setDestinationFlowspecL3vpnIpv6(
+                new DestinationFlowspecL3vpnIpv6Builder()
+                    .setRouteDistinguisher(rd)
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
+    }
+
+    @Override
+    public void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
+        FlowspecIpv6NlriParserHelper.extractFlowspec(fsType, fsBuilder);
+    }
+
+    @Override
+    protected void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer) {
+        FlowspecIpv6NlriParserHelper.buildFlowspecString(value, buffer);
+    }
+
+    @Override
+    protected void serializeMpReachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) {
+            final DestinationFlowspecL3vpnIpv6 destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) dstType)
+                .getDestinationFlowspecL3vpnIpv6();
+            serializeNlri(
+                new Object[] {
+                    destFlowspec.getRouteDistinguisher(),
+                    destFlowspec.getFlowspec()
+                },
+                destFlowspec.getPathId(),
+                byteAggregator
+            );
+        }
+    }
+
+    @Override
+    protected void serializeMpUnreachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) {
+            final DestinationFlowspecL3vpnIpv6 destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) dstType)
+                .getDestinationFlowspecL3vpnIpv6();
+            serializeNlri(
+                new Object[] {
+                    destFlowspec.getRouteDistinguisher(),
+                    destFlowspec.getFlowspec()
+                },
+                destFlowspec.getPathId(),
+                byteAggregator
+            );
+        }
+    }
+}
index 47b7d7936afe6876e7c58ca22ddd18d652866abf..900987ceea1b84a1c27be330e9b6d41774c9b927 100644 (file)
@@ -12,10 +12,12 @@ import static org.junit.Assert.assertNull;
 import org.junit.Test;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecL3vpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecSubsequentAddressFamily;
 
 public class ActivatorTest {
-
+    private static final int FLOWSPEC_SAFI = 133;
+    private static final int FLOWSPEC_VPN_SAFI = 134;
 
     @Test
     public void testActivator() throws Exception {
@@ -23,9 +25,12 @@ public class ActivatorTest {
         final FlowspecActivator activator = new FlowspecActivator(fs_context);
         final BGPActivator act = new BGPActivator(fs_context, activator);
         final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
-        assertNull(context.getSubsequentAddressFamilyRegistry().classForFamily(133));
+        assertNull(context.getSubsequentAddressFamilyRegistry().classForFamily(FLOWSPEC_SAFI));
+        assertNull(context.getSubsequentAddressFamilyRegistry().classForFamily(FLOWSPEC_VPN_SAFI));
         act.start(context);
-        assertEquals(FlowspecSubsequentAddressFamily.class, context.getSubsequentAddressFamilyRegistry().classForFamily(133));
+        assertEquals(FlowspecSubsequentAddressFamily.class, context.getSubsequentAddressFamilyRegistry().classForFamily(FLOWSPEC_SAFI));
+        assertEquals(FlowspecL3vpnSubsequentAddressFamily.class, context.getSubsequentAddressFamilyRegistry().classForFamily(FLOWSPEC_VPN_SAFI));
         act.close();
     }
 }
+
diff --git a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java
new file mode 100644 (file)
index 0000000..94502a1
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2015 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.flowspec;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+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.flowspec.handlers.AbstractNumericOperandParser;
+import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
+import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
+import org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv4.FlowspecL3vpnIpv4NlriParser;
+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.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.BitmaskOperand;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.Dscp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecL3vpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.Fragment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.NumericOperand;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.DestinationPortCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.DscpCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.IcmpCodeCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.IcmpTypeCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.PacketLengthCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.PacketLengthCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.PortCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.PortCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.SourcePortCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.TcpFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.TcpFlagsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.destination.port._case.DestinationPortsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.dscp._case.Dscps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.dscp._case.DscpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.icmp.code._case.Codes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.icmp.code._case.CodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.icmp.type._case.Types;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.icmp.type._case.TypesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengths;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.packet.length._case.PacketLengthsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.port._case.Ports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.port._case.PortsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePorts;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.source.port._case.SourcePortsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.tcp.flags._case.TcpFlagsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.DestinationPrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.ProtocolIpCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.SourcePrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIps;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv4.flowspec.flowspec.type.protocol.ip._case.ProtocolIpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv4.route.FlowspecRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4Builder;
+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;
+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.Attributes2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+
+public class FlowspecL3vpnIpv4NlriParserTest {
+
+    private static final NodeIdentifier RD_NID = new NodeIdentifier(QName.create(Flowspec.QNAME.getNamespace(), Flowspec.QNAME.getRevision(), "route-distinguisher"));
+    private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
+
+    private static final String ROUTE_DISTINGUISHER = "1.2.3.4:10";
+
+    private static final PathId PATH_ID = new PathId(1L);
+
+    @Mock
+    private PeerSpecificParserConstraint constraint;
+    @Mock
+    private MultiPathSupport muliPathSupport;
+
+    private static final byte[] REACHED_NLRI = new byte[] {
+        0x29,   // NLRI length: 8+33=41
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        0x01, 0x20, 0x0a, 0x00, 0x01, 0x00,
+        0x02, 0x20, 0x01, 0x02, 0x03, 0x04,
+        0x03, (byte) 0x81, 0x06,
+        0x04, 0x03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
+        0x05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
+        0x06, (byte) 0x91, 0x1f, (byte) 0x90
+    };
+
+    private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
+        0x0, 0x0, 0x0, 0x1,
+        0x29,   // NLRI length: 8+33=41
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        0x01, 0x20, 0x0a, 0x00, 0x01, 0x00,
+        0x02, 0x20, 0x01, 0x02, 0x03, 0x04,
+        0x03, (byte) 0x81, 0x06,
+        0x04, 0x03, (byte) 0x89, 0x45, (byte) 0x8b, (byte) 0x91, 0x1f, (byte) 0x90,
+        0x05, 0x12, 0x0f, (byte) 0xf9, (byte) 0x81, (byte) 0xb3,
+        0x06, (byte) 0x91, 0x1f, (byte) 0x90
+    };
+
+    private static final byte[] UNREACHED_NLRI = new byte[] {
+        0x23,   // NLRI length: 8+33=41
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        0x07, 4, 2, (byte) 0x84, 3,
+        0x08, 4, 4, (byte) 0x80, 5,
+        0x09, 0x12, 4, 1, (byte) 0x91, 0x56, (byte) 0xb1,
+        0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
+        0x0b, (byte) 0x82, 0x2a,
+        0x0c, (byte) 0x81, (byte) 0x0e
+    };
+
+    private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
+        0x0, 0x0, 0x0, 0x1,
+        0x23,   // NLRI length: 8+27=35
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        0x07, 4, 2, (byte) 0x84, 3,
+        0x08, 4, 4, (byte) 0x80, 5,
+        0x09, 0x12, 4, 1, (byte) 0x91, 0x56, (byte) 0xb1,
+        0x0a, (byte) 0x94, (byte) 0xde, (byte) 0xad,
+        0x0b, (byte) 0x82, 0x2a,
+        0x0c, (byte) 0x81, (byte) 0x0e
+    };
+
+    private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
+    private final FlowspecActivator fsa = new FlowspecActivator(flowspecContext);
+    private final FlowspecL3vpnIpv4NlriParser FS_PARSER = new FlowspecL3vpnIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+
+    @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 testParseMpReachNlri() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpReachNlriBuilder mp = new MpReachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+        final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("10.0.1.0/32")).build();
+        builder.setFlowspecType(destinationPrefix);
+        fs.add(builder.build());
+        final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
+        builder.setFlowspecType(sourcePrefix);
+        fs.add(builder.build());
+
+        final FlowspecType prots = createProts();
+        builder.setFlowspecType(prots);
+        fs.add(builder.build());
+
+        final PortCase ps = createPorts();
+        builder.setFlowspecType(ps);
+        fs.add(builder.build());
+
+        final FlowspecType dps = createDps();
+        builder.setFlowspecType(dps);
+        fs.add(builder.build());
+
+        final FlowspecType sps = createSps();
+        builder.setFlowspecType(sps);
+        fs.add(builder.build());
+
+        final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+
+        final MpReachNlriBuilder result = new MpReachNlriBuilder();
+        result.setAfi(Ipv4AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result);
+
+        final DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) (result.getAdvertizedRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv4();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        testFlows(flows, destinationPrefix, sourcePrefix, prots, rd, ps, dps, sps);
+
+        mp.setAdvertizedRoutes(
+            new AdvertizedRoutesBuilder().setDestinationType(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+                    .setDestinationFlowspecL3vpnIpv4(
+                        new DestinationFlowspecL3vpnIpv4Builder()
+                            .setRouteDistinguisher(rd)
+                            .setFlowspec(fs)
+                            .build()
+                    ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
+        assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ", FS_PARSER.stringNlri(flows));
+    }
+
+    private void testFlows(
+        final List<Flowspec> flows,
+        final DestinationPrefixCase destinationPrefix,
+        final SourcePrefixCase sourcePrefix,
+        final FlowspecType prots,
+        final RouteDistinguisher rd,
+        final PortCase ps,
+        final FlowspecType dps,
+        final FlowspecType sps
+    ) {
+        assertEquals(6, flows.size());
+        assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
+        assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
+        assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
+        assertEquals(prots, flows.get(2).getFlowspecType());
+        assertEquals(ps, flows.get(3).getFlowspecType());
+        assertEquals(dps, flows.get(4).getFlowspecType());
+        assertEquals(sps, flows.get(5).getFlowspecType());
+    }
+
+    private FlowspecType createSps() {
+        final List<SourcePorts> sports = Lists.newArrayList(new SourcePortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
+        return new SourcePortCaseBuilder().setSourcePorts(sports).build();
+    }
+
+    private FlowspecType createProts() {
+        final List<ProtocolIps> protocols = Lists.newArrayList(new ProtocolIpsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
+        return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
+    }
+
+    private FlowspecType createDps() {
+        final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(new NumericOperand(false, false, false, true, false)).setValue(4089).build(),
+            new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(179).build());
+        return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
+    }
+
+    @Test
+    public void testParseMpReachNlriConstraint() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpReachNlriBuilder mp = new MpReachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+        final DestinationPrefixCase destinationPrefix = new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("10.0.1.0/32")).build();
+        builder.setFlowspecType(destinationPrefix);
+        fs.add(builder.build());
+        final SourcePrefixCase sourcePrefix = new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("1.2.3.4/32")).build();
+        builder.setFlowspecType(sourcePrefix);
+        fs.add(builder.build());
+
+        final FlowspecType prots = createProts();
+        builder.setFlowspecType(prots);
+        fs.add(builder.build());
+
+        final PortCase ps = createPorts();
+        builder.setFlowspecType(ps);
+        fs.add(builder.build());
+
+        final FlowspecType dps = createDps();
+        builder.setFlowspecType(dps);
+        fs.add(builder.build());
+
+        final FlowspecType sps = createSps();
+        builder.setFlowspecType(sps);
+        fs.add(builder.build());
+
+        final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+
+        final MpReachNlriBuilder result = new MpReachNlriBuilder();
+        result.setAfi(Ipv4AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
+
+        final DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) (result.getAdvertizedRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv4();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        testFlows(flows, destinationPrefix, sourcePrefix, prots, rd, ps, dps, sps);
+
+        mp.setAdvertizedRoutes(
+            new AdvertizedRoutesBuilder().setDestinationType(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+                    .setDestinationFlowspecL3vpnIpv4(
+                        new DestinationFlowspecL3vpnIpv4Builder()
+                            .setRouteDistinguisher(rd)
+                            .setPathId(PATH_ID)
+                            .setFlowspec(fs)
+                            .build()
+                    ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build()).build()).build(), buffer);
+        assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ", FS_PARSER.stringNlri(flows));
+    }
+
+    private PortCase createPorts() {
+        final List<Ports> ports = Lists.newArrayList(new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(137).build(),
+            new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(139).build(),
+            new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
+
+        return new PortCaseBuilder().setPorts(ports).build();
+    }
+
+    @Test
+    public void testParseMpUnreachNlri() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+
+        final FlowspecType icmpType = createIcmpType();
+        builder.setFlowspecType(icmpType);
+        fs.add(builder.build());
+
+        final FlowspecType icmpCode = createIcmpCode();
+        builder.setFlowspecType(icmpCode);
+        fs.add(builder.build());
+
+        final TcpFlagsCase tcp = createTcp();
+        builder.setFlowspecType(tcp);
+        fs.add(builder.build());
+
+        final PacketLengthCase packet = createPackets();
+        builder.setFlowspecType(packet);
+        fs.add(builder.build());
+
+        final FlowspecType dscp = createDscp();
+        builder.setFlowspecType(dscp);
+        fs.add(builder.build());
+
+        final FlowspecType fragment = createFragment();
+        builder.setFlowspecType(fragment);
+        fs.add(builder.build());
+
+        final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+
+        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
+        result.setAfi(Ipv4AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result);
+
+        DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) (result.getWithdrawnRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv4();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
+
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+                .setDestinationFlowspecL3vpnIpv4(
+                    new DestinationFlowspecL3vpnIpv4Builder()
+                        .setRouteDistinguisher(rd)
+                        .setFlowspec(fs)
+                        .build()
+                ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        parser.serializeNlri(new Object[] {rd, flows}, null, buffer);
+        assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
+
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
+        assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ", FS_PARSER.stringNlri(flows));
+
+    }
+
+    private FlowspecType createFragment() {
+        final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
+        return new FragmentCaseBuilder().setFragments(fragments).build();
+    }
+
+    private FlowspecType createDscp() {
+        final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder().setOp(new NumericOperand(false, true, false, true, false)).setValue(new Dscp((short) 42)).build());
+        return new DscpCaseBuilder().setDscps(dscps).build();
+    }
+
+    private PacketLengthCase createPackets() {
+        final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder().setOp(new NumericOperand(false, true, false, false, true))
+            .setValue(57005).build());
+        return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
+    }
+
+    private TcpFlagsCase createTcp() {
+        final List<TcpFlags> flags = Lists.newArrayList(new TcpFlagsBuilder().setOp(new BitmaskOperand(false, false, false, true)).setValue(1025).build(),
+            new TcpFlagsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(22193).build());
+        return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
+    }
+
+    private FlowspecType createIcmpCode() {
+        final List<Codes> codes = Lists.newArrayList(new CodesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 4).build(),
+            new CodesBuilder().setOp(new NumericOperand(false, true, false, false, false)).setValue((short) 5).build());
+        return new IcmpCodeCaseBuilder().setCodes(codes).build();
+    }
+
+    private FlowspecType createIcmpType() {
+        final List<Types> types = Lists.newArrayList(new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 2).build(),
+            new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue((short) 3).build());
+        return new IcmpTypeCaseBuilder().setTypes(types).build();
+    }
+
+    private void checkUnreachFlows(final List<Flowspec> flows, final FlowspecType icmpType, final FlowspecType icmpCode, final TcpFlagsCase tcp,
+                                   final PacketLengthCase packet, final FlowspecType dscp, final FlowspecType fragment) {
+        assertEquals(6, flows.size());
+        assertEquals(icmpType, flows.get(0).getFlowspecType());
+        assertEquals(icmpCode, flows.get(1).getFlowspecType());
+        assertEquals(tcp, flows.get(2).getFlowspecType());
+        assertEquals(packet, flows.get(3).getFlowspecType());
+        assertEquals(dscp, flows.get(4).getFlowspecType());
+        assertEquals(fragment, flows.get(5).getFlowspecType());
+    }
+
+    @Test
+    public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+
+        final FlowspecType icmpType = createIcmpType();
+        builder.setFlowspecType(icmpType);
+        fs.add(builder.build());
+
+        final FlowspecType icmpCode = createIcmpCode();
+        builder.setFlowspecType(icmpCode);
+        fs.add(builder.build());
+
+        final TcpFlagsCase tcp = createTcp();
+        builder.setFlowspecType(tcp);
+        fs.add(builder.build());
+
+        final PacketLengthCase packet = createPackets();
+        builder.setFlowspecType(packet);
+        fs.add(builder.build());
+
+        final FlowspecType dscp = createDscp();
+        builder.setFlowspecType(dscp);
+        fs.add(builder.build());
+
+        final FlowspecType fragment = createFragment();
+        builder.setFlowspecType(fragment);
+        fs.add(builder.build());
+
+        final FlowspecL3vpnIpv4NlriParser parser = new FlowspecL3vpnIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN));
+
+        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
+        result.setAfi(Ipv4AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
+
+        DestinationFlowspecL3vpnIpv4 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4Case) (result.getWithdrawnRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv4();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
+
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv4CaseBuilder()
+                .setDestinationFlowspecL3vpnIpv4(
+                    new DestinationFlowspecL3vpnIpv4Builder()
+                        .setRouteDistinguisher(rd)
+                        .setPathId(PATH_ID)
+                        .setFlowspec(fs)
+                        .build()
+                ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        parser.serializeNlri(new Object[] {rd, flows}, PATH_ID, buffer);
+        assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
+
+        parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
+        assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ", FS_PARSER.stringNlri(flows));
+
+    }
+
+    @Test
+    public void testExtractFlowspecDestPrefix() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID).withValue("127.0.0.5/32").build()).build()).build()).build());
+
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("127.0.0.5/32")).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourcePrefix() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).withValue("127.0.0.6/32").build()).build()).build()).build());
+
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32")).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecProtocolIps() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue((short) 100).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue((short) 200).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue((short) 240).build()).build())
+                        .build()).build()).build()).build());
+
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(Lists.newArrayList(
+            new ProtocolIpsBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
+            new ProtocolIpsBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
+            new ProtocolIpsBuilder().setValue((short) 240).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecPorts() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue(100).build()).build())
+                        .build()).build()).build()).build());
+
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new PortCaseBuilder().setPorts(Lists.newArrayList(new PortsBuilder().setValue(100).setOp(new NumericOperand(true, true, false, false, true)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecDestinationPorts() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(1024).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new DestinationPortCaseBuilder().setDestinationPorts(Lists.newArrayList(new DestinationPortsBuilder().setValue(1024).setOp(new NumericOperand(false, true, true, false, false)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourcePorts() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue(8080).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new SourcePortCaseBuilder().setSourcePorts(Lists.newArrayList(new SourcePortsBuilder().setValue(8080).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourceTypes() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue((short) 22).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.newArrayList(new TypesBuilder().setValue((short) 22).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourceCodes() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet()).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue((short) 23).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.newArrayList(new CodesBuilder().setValue((short) 23).setOp(new NumericOperand(false, false, false, false, false)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourceTcpFlags() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue(99).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder().setValue(99).setOp(new BitmaskOperand(true, true, false, false)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecPacketLengths() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue(101).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(Lists.newArrayList(new PacketLengthsBuilder().setValue(101).setOp(new NumericOperand(true, false, false, true, false)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecDscps() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue((short) 15).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder().setValue(new Dscp((short) 15)).setOp(new NumericOperand(true, true, false, true, false)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecFragments() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.OP_NID).withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv4NlriParser.VALUE_NID).withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
+        final List<Flowspec> expected = new ArrayList<>();
+        expected.add(expectedFS.build());
+        assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecRouteDistinguisher() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(
+            Builders.leafBuilder()
+                .withNodeIdentifier(RD_NID)
+                .withValue(
+                    RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER)
+                ).build()
+        );
+
+        RouteDistinguisher rd = RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER);
+        assertEquals(rd, FS_PARSER.extractRouteDistinguisher(entry.build()));
+    }
+}
+
diff --git a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv6NlriParserTest.java b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv6NlriParserTest.java
new file mode 100644 (file)
index 0000000..e53319b
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2015 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.flowspec;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecIpv4NlriParserTest.PATH_ID;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+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.flowspec.handlers.AbstractNumericOperandParser;
+import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
+import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
+import org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv6.FlowspecL3vpnIpv6NlriParser;
+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.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.BitmaskOperand;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecL3vpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.Fragment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.NumericOperand;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.FragmentCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.fragment._case.Fragments;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.flowspec.type.fragment._case.FragmentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabelBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeaders;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeadersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv6.route.FlowspecRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6Builder;
+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;
+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.Attributes2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+
+public class FlowspecL3vpnIpv6NlriParserTest {
+    private static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
+    private static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
+
+    private static final String ROUTE_DISTINGUISHER = "1.2.3.4:10";
+
+    @Mock
+    private PeerSpecificParserConstraint constraint;
+    @Mock
+    private MultiPathSupport muliPathSupport;
+    private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
+    private final FlowspecActivator fsa = new FlowspecActivator(flowspecContext);
+    private final FlowspecL3vpnIpv6NlriParser FS_PARSER = new FlowspecL3vpnIpv6NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+
+    private static final byte[] REACHED_NLRI = new byte[]{
+        0x1B,   // NLRI length: 19+8=27
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        1, 0x28, 0, 1, 2, 3, 4, 5,
+        2, 0x28, 0, 1, 2, 3, 4, 6,
+        03, (byte) 0x81, 06};
+
+    private static final byte[] REACHED_NLRI_ADD_PATH = new byte[]{
+        0x0, 0x0, 0x0, 0x1,
+        0x1B,
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        1, 0x28, 0, 1, 2, 3, 4, 5,
+        2, 0x28, 0, 1, 2, 3, 4, 6,
+        03, (byte) 0x81, 06};
+
+    private static final byte[] UNREACHED_NLRI = new byte[]{
+        0x14,   // NLRI length: 12+8=20
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        0x0c, (byte) 0x81, 0x0e,
+        0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
+    };
+
+    private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[]{
+        0x0, 0x0, 0x0, 0x1,
+        0x14,   // NLRI length: 12+8=20
+        0, 1, 1, 2, 3, 4, 0, 10,    // route distinguisher: 1.2.3.4:10
+        0x0c, (byte) 0x81, 0x0e,
+        0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
+    };
+
+    @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 testParseMpReachNlri() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpReachNlriBuilder mp = new MpReachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+        final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build();
+        builder.setFlowspecType(destinationPrefix);
+        fs.add(builder.build());
+
+        final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build();
+        builder.setFlowspecType(sourcePrefix);
+        fs.add(builder.build());
+
+        final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
+        final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
+        builder.setFlowspecType(headersCase);
+        fs.add(builder.build());
+
+        final MpReachNlriBuilder result = new MpReachNlriBuilder();
+        result.setAfi(Ipv6AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        FS_PARSER.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result);
+
+        DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) (result.getAdvertizedRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv6();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        assertEquals(3, flows.size());
+        assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
+        assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
+        assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
+        assertEquals(headersCase, flows.get(2).getFlowspecType());
+
+        mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+                .setDestinationFlowspecL3vpnIpv6(
+                    new DestinationFlowspecL3vpnIpv6Builder()
+                        .setRouteDistinguisher(rd)
+                        .setFlowspec(fs)
+                        .build()
+                )
+                .build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(), buffer);
+        assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ", FS_PARSER.stringNlri(flows));
+    }
+
+    @Test
+    public void testParseMpReachNlriConstraint() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpReachNlriBuilder mp = new MpReachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+        final DestinationIpv6PrefixCase destinationPrefix = new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build();
+        builder.setFlowspecType(destinationPrefix);
+        fs.add(builder.build());
+
+        final SourceIpv6PrefixCase sourcePrefix = new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build();
+        builder.setFlowspecType(sourcePrefix);
+        fs.add(builder.build());
+
+        final List<NextHeaders> nextheaders = Lists.newArrayList(new NextHeadersBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue((short) 6).build());
+        final NextHeaderCase headersCase = new NextHeaderCaseBuilder().setNextHeaders(nextheaders).build();
+        builder.setFlowspecType(headersCase);
+        fs.add(builder.build());
+
+        final MpReachNlriBuilder result = new MpReachNlriBuilder();
+        result.setAfi(Ipv6AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        FS_PARSER.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
+
+        final DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) (result.getAdvertizedRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv6();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        assertEquals(3, flows.size());
+        assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
+        assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
+        assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
+        assertEquals(headersCase, flows.get(2).getFlowspecType());
+
+        mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+                .setDestinationFlowspecL3vpnIpv6(
+                    new DestinationFlowspecL3vpnIpv6Builder()
+                        .setPathId(PATH_ID)
+                        .setRouteDistinguisher(rd)
+                        .setFlowspec(fs)
+                        .build()
+                ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class, new Attributes1Builder().setMpReachNlri(mp.setAfi(Ipv6AddressFamily.class).build()).build()).build(), buffer);
+        assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets to 102:304:500::/40 AND from 102:304:600::/40 AND where next header equals to 6 ", FS_PARSER.stringNlri(flows));
+    }
+
+    @Test
+    public void testParseMpUnreachNlri() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+
+        final FragmentCase fragment = createFragment();
+        builder.setFlowspecType(fragment);
+        fs.add(builder.build());
+
+        final FlowspecType label = createLabel();
+        builder.setFlowspecType(label);
+        fs.add(builder.build());
+
+        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
+        result.setAfi(Ipv6AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        FS_PARSER.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result);
+
+        final DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) (result.getWithdrawnRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv6();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        assertEquals(2, flows.size());
+        assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
+        assertEquals(fragment, flows.get(0).getFlowspecType());
+        assertEquals(label, flows.get(1).getFlowspecType());
+
+        mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+                .setDestinationFlowspecL3vpnIpv6(
+                    new DestinationFlowspecL3vpnIpv6Builder()
+                        .setRouteDistinguisher(rd)
+                        .setFlowspec(fs)
+                        .build()
+                ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
+
+        assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to 16777222 or equals to 258 ", FS_PARSER.stringNlri(flows));
+    }
+
+    private FragmentCase createFragment() {
+        final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(new Fragment(false, true, true, true)).build());
+        return new FragmentCaseBuilder().setFragments(fragments).build();
+    }
+
+    private FlowspecType createLabel() {
+        final List<FlowLabel> labels = Lists.newArrayList();
+        labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, false, true, false, false)).setValue(new Long(16777222L)).build());
+        labels.add(new FlowLabelBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(new Long(258L)).build());
+        return new FlowLabelCaseBuilder().setFlowLabel(labels).build();
+    }
+
+    @Test
+    public void testParseMpUnreachNlriConstraint() throws BGPParsingException {
+        final List<Flowspec> fs = new ArrayList<>();
+        final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
+
+        final FlowspecBuilder builder = new FlowspecBuilder();
+        final FragmentCase fragment = createFragment();
+
+        builder.setFlowspecType(fragment);
+        fs.add(builder.build());
+
+        final FlowspecType label = createLabel();
+        builder.setFlowspecType(label);
+        fs.add(builder.build());
+
+        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
+        result.setAfi(Ipv6AddressFamily.class);
+        result.setSafi(FlowspecL3vpnSubsequentAddressFamily.class);
+        FS_PARSER.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
+
+        final DestinationFlowspecL3vpnIpv6 flowspecDst = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6Case) (result.getWithdrawnRoutes().getDestinationType()))
+            .getDestinationFlowspecL3vpnIpv6();
+        final List<Flowspec> flows = flowspecDst.getFlowspec();
+        final RouteDistinguisher rd = flowspecDst.getRouteDistinguisher();
+
+        assertEquals(2, flows.size());
+        assertEquals(ROUTE_DISTINGUISHER, new String(rd.getValue()));
+        assertEquals(fragment, flows.get(0).getFlowspecType());
+        assertEquals(label, flows.get(1).getFlowspecType());
+
+        mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecL3vpnIpv6CaseBuilder()
+                .setDestinationFlowspecL3vpnIpv6(
+                    new DestinationFlowspecL3vpnIpv6Builder()
+                        .setRouteDistinguisher(rd)
+                        .setPathId(PATH_ID)
+                        .setFlowspec(fs)
+                        .build()
+                ).build()
+            ).build()
+        );
+
+        final ByteBuf buffer = Unpooled.buffer();
+        FS_PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
+
+        assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
+
+        assertEquals("all packets where fragment does match 'IS FIRST' 'IS LAST' 'IS A' AND where flow label equals to 16777222 or equals to 258 ", FS_PARSER.stringNlri(flows));
+    }
+
+    @Test
+    public void testExtractFlowspecFragments() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
+                        .build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.<Fragments>newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
+        final List<Flowspec> expectedValue = new ArrayList<>();
+        expectedValue.add(expectedFS.build());
+        assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecNextHeaders() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue((short) 100).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue((short) 200).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue((short) 210).build()).build())
+                        .build()).build()).build()).build());
+
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(Lists.<NextHeaders>newArrayList(
+            new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
+            new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
+            new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
+        final List<Flowspec> expectedValue = new ArrayList<>();
+        expectedValue.add(expectedFS.build());
+        assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecFlowLabels() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FLOW_LABEL_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue(100L).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.VALUE_NID).withValue(200L).build()).build())
+                        .build()).build()).build()).build());
+
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(Lists.<FlowLabel>newArrayList(
+            new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
+            new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build())).build());
+        final List<Flowspec> expectedValue = new ArrayList<>();
+        expectedValue.add(expectedFS.build());
+        assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecDestPrefix() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(FlowspecL3vpnIpv6NlriParser.DEST_PREFIX_NID).withValue("102:304:500::/40").build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build());
+        final List<Flowspec> expectedValue = new ArrayList<>();
+        expectedValue.add(expectedFS.build());
+        assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourcePrefix() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
+        entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
+                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID).withValue("102:304:600::/40").build()).build()).build()).build());
+        final FlowspecBuilder expectedFS = new FlowspecBuilder();
+        expectedFS.setFlowspecType(new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build());
+        final List<Flowspec> expectedValue = new ArrayList<>();
+        expectedValue.add(expectedFS.build());
+        assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
+    }
+}
+
index 2b40f85eec69a491aee1bd0f825219c40739f656..4f4aa10c9ee6b784563bc70e642e2dcf35ec52fb 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.protocol.bgp.flowspec;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import io.netty.buffer.ByteBuf;
@@ -87,6 +88,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -94,13 +96,15 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContaine
 
 public class SimpleFlowspecIpv4NlriParserTest {
 
+    private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
+
     static final PathId PATH_ID = new PathId(1L);
     @Mock
     private PeerSpecificParserConstraint constraint;
     @Mock
     private MultiPathSupport muliPathSupport;
 
-    private static final byte[] REACHED_NLRI = new byte[]{
+    private static final byte[] REACHED_NLRI = new byte[] {
         0x21,   // NLRI length: 33
         01, 0x20, 0x0a, 00, 01, 00,
         02, 0x20, 01, 02, 03, 04,
@@ -110,7 +114,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
         06, (byte) 0x91, 0x1f, (byte) 0x90
     };
 
-    private static final byte[] REACHED_NLRI_ADD_PATH = new byte[]{
+    private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
         0x0, 0x0, 0x0, 0x1,
         0x21,   // NLRI length: 33
         01, 0x20, 0x0a, 00, 01, 00,
@@ -121,7 +125,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
         06, (byte) 0x91, 0x1f, (byte) 0x90
     };
 
-    private static final byte[] UNREACHED_NLRI = new byte[]{
+    private static final byte[] UNREACHED_NLRI = new byte[] {
         0x1B,   // NLRI length: 27
         07, 4, 2, (byte) 0x84, 3,
         0x08, 4, 04, (byte) 0x80, 05,
@@ -131,7 +135,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
         0x0c, (byte) 0x81, (byte) 0x0e
     };
 
-    private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[]{
+    private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
         0x0, 0x0, 0x0, 0x1,
         0x1B,   // NLRI length: 27
         07, 4, 2, (byte) 0x84, 3,
@@ -183,14 +187,14 @@ public class SimpleFlowspecIpv4NlriParserTest {
         fs.add(builder.build());
 
         mp.setAdvertizedRoutes(
-                new AdvertizedRoutesBuilder().setDestinationType(
-                        new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
-                                .setDestinationFlowspec(
-                                        new DestinationFlowspecBuilder()
-                                                .setFlowspec(fs)
-                                                .build()
-                                ).build()
-                ).build()
+            new AdvertizedRoutesBuilder().setDestinationType(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
+                    .setDestinationFlowspec(
+                        new DestinationFlowspecBuilder()
+                            .setFlowspec(fs)
+                            .build()
+                    ).build()
+            ).build()
         );
 
         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
@@ -201,8 +205,8 @@ public class SimpleFlowspecIpv4NlriParserTest {
         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) (result.getAdvertizedRoutes().getDestinationType()))
-                .getDestinationFlowspec()
-                .getFlowspec();
+            .getDestinationFlowspec()
+            .getFlowspec();
         testFlows(flows, destinationPrefix, sourcePrefix, prots, prots, ps, dps, sps);
 
         final ByteBuf buffer = Unpooled.buffer();
@@ -234,7 +238,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
 
     private FlowspecType createDps() {
         final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(new NumericOperand(false, false, false, true, false)).setValue(4089).build(),
-                new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(179).build());
+            new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(179).build());
         return new DestinationPortCaseBuilder().setDestinationPorts(destports).build();
     }
 
@@ -268,14 +272,14 @@ public class SimpleFlowspecIpv4NlriParserTest {
         fs.add(builder.build());
 
         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setPathId(PATH_ID)
-                                        .setFlowspec(fs)
-                                        .build()
-                        ).build()
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setPathId(PATH_ID)
+                        .setFlowspec(fs)
+                        .build()
                 ).build()
+            ).build()
         );
 
         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
@@ -286,8 +290,8 @@ public class SimpleFlowspecIpv4NlriParserTest {
         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase) (result.getAdvertizedRoutes().getDestinationType()))
-                .getDestinationFlowspec()
-                .getFlowspec();
+            .getDestinationFlowspec()
+            .getFlowspec();
         testFlows(flows, destinationPrefix, sourcePrefix, prots, prots, ps, dps, sps);
 
         final ByteBuf buffer = Unpooled.buffer();
@@ -299,8 +303,8 @@ public class SimpleFlowspecIpv4NlriParserTest {
 
     private PortCase createPorts() {
         final List<Ports> ports = Lists.newArrayList(new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(137).build(),
-                new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(139).build(),
-                new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
+            new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(139).build(),
+            new PortsBuilder().setOp(new NumericOperand(false, true, true, false, false)).setValue(8080).build());
 
         return new PortCaseBuilder().setPorts(ports).build();
     }
@@ -337,13 +341,13 @@ public class SimpleFlowspecIpv4NlriParserTest {
         fs.add(builder.build());
 
         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setFlowspec(fs)
-                                        .build()
-                        ).build()
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setFlowspec(fs)
+                        .build()
                 ).build()
+            ).build()
         );
 
         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
@@ -354,12 +358,12 @@ public class SimpleFlowspecIpv4NlriParserTest {
         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) (result.getWithdrawnRoutes().getDestinationType()))
-                .getDestinationFlowspec()
-                .getFlowspec();
+            .getDestinationFlowspec()
+            .getFlowspec();
         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
 
         final ByteBuf buffer = Unpooled.buffer();
-        parser.serializeNlri(flows, null, buffer);
+        parser.serializeNlri(new Object[] {flows}, null, buffer);
         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
 
         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
@@ -381,25 +385,25 @@ public class SimpleFlowspecIpv4NlriParserTest {
 
     private PacketLengthCase createPackets() {
         final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder().setOp(new NumericOperand(false, true, false, false, true))
-                .setValue(57005).build());
+            .setValue(57005).build());
         return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
     }
 
     private TcpFlagsCase createTcp() {
         final List<TcpFlags> flags = Lists.newArrayList(new TcpFlagsBuilder().setOp(new BitmaskOperand(false, false, false, true)).setValue(1025).build(),
-                new TcpFlagsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(22193).build());
+            new TcpFlagsBuilder().setOp(new BitmaskOperand(false, true, true, false)).setValue(22193).build());
         return new TcpFlagsCaseBuilder().setTcpFlags(flags).build();
     }
 
     private FlowspecType createIcmpCode() {
         final List<Codes> codes = Lists.newArrayList(new CodesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 4).build(),
-                new CodesBuilder().setOp(new NumericOperand(false, true, false, false, false)).setValue((short) 5).build());
+            new CodesBuilder().setOp(new NumericOperand(false, true, false, false, false)).setValue((short) 5).build());
         return new IcmpCodeCaseBuilder().setCodes(codes).build();
     }
 
     private FlowspecType createIcmpType() {
         final List<Types> types = Lists.newArrayList(new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue((short) 2).build(),
-                new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue((short) 3).build());
+            new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue((short) 3).build());
         return new IcmpTypeCaseBuilder().setTypes(types).build();
     }
 
@@ -446,14 +450,14 @@ public class SimpleFlowspecIpv4NlriParserTest {
         fs.add(builder.build());
 
         mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setPathId(PATH_ID)
-                                        .setFlowspec(fs)
-                                        .build()
-                        ).build()
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setPathId(PATH_ID)
+                        .setFlowspec(fs)
+                        .build()
                 ).build()
+            ).build()
         );
 
         final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
@@ -464,13 +468,13 @@ public class SimpleFlowspecIpv4NlriParserTest {
         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCase) (result.getWithdrawnRoutes().getDestinationType()))
-                .getDestinationFlowspec()
-                .getFlowspec();
+            .getDestinationFlowspec()
+            .getFlowspec();
         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
 
 
         final ByteBuf buffer = Unpooled.buffer();
-        parser.serializeNlri(flows, PATH_ID, buffer);
+        parser.serializeNlri(new Object[] {flows}, PATH_ID, buffer);
         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
 
         parser.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class, new Attributes2Builder().setMpUnreachNlri(mp.build()).build()).build(), buffer);
@@ -485,12 +489,12 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID).withValue("127.0.0.5/32").build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID).withValue("127.0.0.5/32").build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("127.0.0.5/32")).build());
@@ -504,12 +508,12 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).withValue("127.0.0.6/32").build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID).withValue("127.0.0.6/32").build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32")).build());
@@ -523,28 +527,28 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PROTOCOL_IP_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PROTOCOL_IP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue((short) 100).build()).build())
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PROTOCOL_IP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue((short) 200).build()).build())
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PROTOCOL_IP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue((short) 240).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 100).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 200).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 240).build()).build())
+                        .build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(Lists.<ProtocolIps>newArrayList(
-                new ProtocolIpsBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
-                new ProtocolIpsBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
-                new ProtocolIpsBuilder().setValue((short) 240).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
+            new ProtocolIpsBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
+            new ProtocolIpsBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
+            new ProtocolIpsBuilder().setValue((short) 240).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
         expected.add(expectedFS.build());
         assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
@@ -555,16 +559,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PORTS_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PROTOCOL_IP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue(100).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(100).build()).build())
+                        .build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new PortCaseBuilder().setPorts(Lists.<Ports>newArrayList(new PortsBuilder().setValue(100).setOp(new NumericOperand(true, true, false, false, true)).build())).build());
@@ -578,16 +582,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.DEST_PORT_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue(1024).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(1024).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new DestinationPortCaseBuilder().setDestinationPorts(Lists.<DestinationPorts>newArrayList(new DestinationPortsBuilder().setValue(1024).setOp(new NumericOperand(false, true, true, false, false)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -600,16 +604,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PORT_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue(8080).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(8080).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new SourcePortCaseBuilder().setSourcePorts(Lists.<SourcePorts>newArrayList(new SourcePortsBuilder().setValue(8080).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -622,16 +626,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.ICMP_TYPE_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue((short) 22).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 22).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.<Types>newArrayList(new TypesBuilder().setValue((short) 22).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -644,16 +648,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.ICMP_CODE_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet()).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue((short) 23).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet()).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 23).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.<Codes>newArrayList(new CodesBuilder().setValue((short) 23).setOp(new NumericOperand(false, false, false, false, false)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -666,16 +670,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.TCP_FLAGS_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue(99).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(99).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(Lists.<TcpFlags>newArrayList(new TcpFlagsBuilder().setValue(99).setOp(new BitmaskOperand(true, true, false, false)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -688,16 +692,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.PACKET_LENGTHS_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue(101).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(101).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(Lists.<PacketLengths>newArrayList(new PacketLengthsBuilder().setValue(101).setOp(new NumericOperand(true, false, false, true, false)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -710,16 +714,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.DSCP_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue((short) 15).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 15).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.<Dscps>newArrayList(new DscpsBuilder().setValue(new Dscp((short) 15)).setOp(new NumericOperand(true, true, false, true, false)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -732,16 +736,16 @@ public class SimpleFlowspecIpv4NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.FRAGMENT_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.VALUE_NID).withValue(Sets.newHashSet(SimpleFlowspecIpv4NlriParser.DO_NOT_VALUE, SimpleFlowspecIpv4NlriParser.FIRST_VALUE, SimpleFlowspecIpv4NlriParser.IS_A_VALUE, SimpleFlowspecIpv4NlriParser.LAST_VALUE)).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.<Fragments>newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
         final List<Flowspec> expected = new ArrayList<>();
@@ -749,3 +753,4 @@ public class SimpleFlowspecIpv4NlriParserTest {
         assertEquals(expected, FS_PARSER.extractFlowspec(entry.build()));
     }
 }
+
index aaeec26737b5b914eda5e6622ea4fbb62315ce41..c41f51987401a6dadbc3e05ddbff0f501edf5a2e 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.protocol.bgp.flowspec;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecIpv4NlriParserTest.PATH_ID;
+
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import io.netty.buffer.ByteBuf;
@@ -64,12 +65,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
 
 public class SimpleFlowspecIpv6NlriParserTest {
+    private static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
+    private static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
+
     @Mock
     private PeerSpecificParserConstraint constraint;
     @Mock
@@ -78,26 +83,26 @@ public class SimpleFlowspecIpv6NlriParserTest {
     private final FlowspecActivator fsa = new FlowspecActivator(flowspecContext);
     private final SimpleFlowspecIpv6NlriParser FS_PARSER = new SimpleFlowspecIpv6NlriParser(flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
 
-    private static final byte[] REACHED_NLRI = new byte[]{
+    private static final byte[] REACHED_NLRI = new byte[] {
         0x13,
         1, 0x28, 0, 1, 2, 3, 4, 5,
         2, 0x28, 0, 1, 2, 3, 4, 6,
         03, (byte) 0x81, 06};
 
-    private static final byte[] REACHED_NLRI_ADD_PATH = new byte[]{
+    private static final byte[] REACHED_NLRI_ADD_PATH = new byte[] {
         0x0, 0x0, 0x0, 0x1,
         0x13,
         1, 0x28, 0, 1, 2, 3, 4, 5,
         2, 0x28, 0, 1, 2, 3, 4, 6,
         03, (byte) 0x81, 06};
 
-    private static final byte[] UNREACHED_NLRI = new byte[]{
+    private static final byte[] UNREACHED_NLRI = new byte[] {
         0x0c,
         0x0c, (byte) 0x81, 0x0e,
         0x0d, (byte) 0x21, 1, 0, 0, 6, (byte) 0x91, 1, 2
     };
 
-    private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[]{
+    private static final byte[] UNREACHED_NLRI_ADD_PATH = new byte[] {
         0x0, 0x0, 0x0, 0x1,
         0x0c,
         0x0c, (byte) 0x81, 0x0e,
@@ -132,14 +137,14 @@ public class SimpleFlowspecIpv6NlriParserTest {
 
 
         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setFlowspec(fs)
-                                        .build()
-                        )
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setFlowspec(fs)
                         .build()
-                ).build()
+                )
+                .build()
+            ).build()
         );
 
         final MpReachNlriBuilder result = new MpReachNlriBuilder();
@@ -148,7 +153,7 @@ public class SimpleFlowspecIpv6NlriParserTest {
         FS_PARSER.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) (result.getAdvertizedRoutes().getDestinationType()))
-                .getDestinationFlowspec().getFlowspec();
+            .getDestinationFlowspec().getFlowspec();
         assertEquals(3, flows.size());
         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
@@ -182,14 +187,14 @@ public class SimpleFlowspecIpv6NlriParserTest {
 
 
         mp.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setPathId(PATH_ID)
-                                        .setFlowspec(fs)
-                                        .build()
-                        ).build()
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setPathId(PATH_ID)
+                        .setFlowspec(fs)
+                        .build()
                 ).build()
+            ).build()
         );
 
         final MpReachNlriBuilder result = new MpReachNlriBuilder();
@@ -198,7 +203,7 @@ public class SimpleFlowspecIpv6NlriParserTest {
         FS_PARSER.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) (result.getAdvertizedRoutes().getDestinationType()))
-                .getDestinationFlowspec().getFlowspec();
+            .getDestinationFlowspec().getFlowspec();
         assertEquals(3, flows.size());
         assertEquals(destinationPrefix, flows.get(0).getFlowspecType());
         assertEquals(sourcePrefix, flows.get(1).getFlowspecType());
@@ -227,13 +232,13 @@ public class SimpleFlowspecIpv6NlriParserTest {
         fs.add(builder.build());
 
         mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setFlowspec(fs)
-                                        .build()
-                        ).build()
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setFlowspec(fs)
+                        .build()
                 ).build()
+            ).build()
         );
 
         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
@@ -242,7 +247,7 @@ public class SimpleFlowspecIpv6NlriParserTest {
         FS_PARSER.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) (result.getWithdrawnRoutes().getDestinationType()))
-                .getDestinationFlowspec().getFlowspec();
+            .getDestinationFlowspec().getFlowspec();
         assertEquals(2, flows.size());
         assertEquals(fragment, flows.get(0).getFlowspecType());
         assertEquals(label, flows.get(1).getFlowspecType());
@@ -283,14 +288,14 @@ public class SimpleFlowspecIpv6NlriParserTest {
         fs.add(builder.build());
 
         mp.setAfi(Ipv6AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                        .setDestinationFlowspec(
-                                new DestinationFlowspecBuilder()
-                                        .setPathId(PATH_ID)
-                                        .setFlowspec(fs)
-                                        .build()
-                        ).build()
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
+                .setDestinationFlowspec(
+                    new DestinationFlowspecBuilder()
+                        .setPathId(PATH_ID)
+                        .setFlowspec(fs)
+                        .build()
                 ).build()
+            ).build()
         );
 
         final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
@@ -299,7 +304,7 @@ public class SimpleFlowspecIpv6NlriParserTest {
         FS_PARSER.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) (result.getWithdrawnRoutes().getDestinationType()))
-                .getDestinationFlowspec().getFlowspec();
+            .getDestinationFlowspec().getFlowspec();
         assertEquals(2, flows.size());
         assertEquals(fragment, flows.get(0).getFlowspecType());
         assertEquals(label, flows.get(1).getFlowspecType());
@@ -317,16 +322,16 @@ public class SimpleFlowspecIpv6NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.FRAGMENT_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.VALUE_NID).withValue(Sets.newHashSet(SimpleFlowspecIpv6NlriParser.DO_NOT_VALUE, SimpleFlowspecIpv6NlriParser.FIRST_VALUE, SimpleFlowspecIpv6NlriParser.IS_A_VALUE, SimpleFlowspecIpv6NlriParser.LAST_VALUE)).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
+                        .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.<Fragments>newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
         final List<Flowspec> expectedValue = new ArrayList<>();
@@ -339,28 +344,28 @@ public class SimpleFlowspecIpv6NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.NEXT_HEADER_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.NEXT_HEADER_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.VALUE_NID).withValue((short) 100).build()).build())
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.NEXT_HEADER_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.VALUE_NID).withValue((short) 200).build()).build())
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.NEXT_HEADER_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.VALUE_NID).withValue((short) 210).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 100).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 200).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(NEXT_HEADER_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue((short) 210).build()).build())
+                        .build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(Lists.<NextHeaders>newArrayList(
-                new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
-                new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
-                new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
+            new NextHeadersBuilder().setValue((short) 100).setOp(new NumericOperand(true, true, false, false, false)).build(),
+            new NextHeadersBuilder().setValue((short) 200).setOp(new NumericOperand(true, false, false, false, false)).build(),
+            new NextHeadersBuilder().setValue((short) 210).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
         final List<Flowspec> expectedValue = new ArrayList<>();
         expectedValue.add(expectedFS.build());
         assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
@@ -371,24 +376,24 @@ public class SimpleFlowspecIpv6NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.FLOW_LABEL_NID)
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.FLOW_LABEL_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.VALUE_NID).withValue(100L).build()).build())
-                                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.FLOW_LABEL_NID)
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
-                                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.VALUE_NID).withValue(200L).build()).build())
-                                        .build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FLOW_LABEL_NID)
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(100L).build()).build())
+                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FLOW_LABEL_NID)
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID).withValue(Sets.<String>newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
+                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID).withValue(200L).build()).build())
+                        .build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(Lists.<FlowLabel>newArrayList(
-                new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
-                new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build())).build());
+            new FlowLabelBuilder().setValue(100L).setOp(new NumericOperand(true, true, false, false, false)).build(),
+            new FlowLabelBuilder().setValue(200L).setOp(new NumericOperand(true, false, false, false, false)).build())).build());
         final List<Flowspec> expectedValue = new ArrayList<>();
         expectedValue.add(expectedFS.build());
         assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
@@ -399,12 +404,12 @@ public class SimpleFlowspecIpv6NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv6NlriParser.DEST_PREFIX_NID).withValue("102:304:500::/40").build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID).withValue("102:304:500::/40").build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new DestinationIpv6PrefixCaseBuilder().setDestinationPrefix(new Ipv6Prefix("102:304:500::/40")).build());
         final List<Flowspec> expectedValue = new ArrayList<>();
@@ -417,12 +422,12 @@ public class SimpleFlowspecIpv6NlriParserTest {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
         entry.withChild(Builders.unkeyedListBuilder()
+            .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
+            .withChild(Builders.unkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.unkeyedListEntryBuilder()
-                        .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                        .withChild(Builders.choiceBuilder()
-                                .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                                .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID).withValue("102:304:600::/40").build()).build()).build()).build());
+                .withChild(Builders.choiceBuilder()
+                    .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
+                    .withChild(Builders.leafBuilder().withNodeIdentifier(SimpleFlowspecIpv4NlriParser.SOURCE_PREFIX_NID).withValue("102:304:600::/40").build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new SourceIpv6PrefixCaseBuilder().setSourcePrefix(new Ipv6Prefix("102:304:600::/40")).build());
         final List<Flowspec> expectedValue = new ArrayList<>();
@@ -430,3 +435,4 @@ public class SimpleFlowspecIpv6NlriParserTest {
         assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build()));
     }
 }
+