From f9a57aadf90237a4bcdad079723103f47d99bc7a Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 6 Jun 2016 01:49:42 -0700 Subject: [PATCH] BUG-5785 Support for dissemination of L3VPN flow spec II - New NLRI parser for flowspec L3vpn Change-Id: I6fe6985a46a2b1c2d9dc91dea6bd10282c0dc351 Signed-off-by: Kevin Wang --- .../flowspec/AbstractFlowspecNlriParser.java | 174 +++- .../flowspec/AbstractFlowspecRIBSupport.java | 4 +- .../protocol/bgp/flowspec/BGPActivator.java | 38 +- .../bgp/flowspec/FlowspecActivator.java | 56 +- .../SimpleFlowspecIpv4NlriParser.java | 129 +-- .../SimpleFlowspecIpv6NlriParser.java | 174 +--- .../ipv4/FlowspecIpv4NlriParserHelper.java | 96 +++ .../ipv6/FlowspecIpv6NlriParserHelper.java | 133 +++ .../AbstractFlowspecL3vpnNlriParser.java | 89 ++ .../ipv4/FlowspecL3vpnIpv4NlriParser.java | 105 +++ .../ipv6/FlowspecL3vpnIpv6NlriParser.java | 105 +++ .../protocol/bgp/flowspec/ActivatorTest.java | 11 +- .../FlowspecL3vpnIpv4NlriParserTest.java | 807 ++++++++++++++++++ .../FlowspecL3vpnIpv6NlriParserTest.java | 465 ++++++++++ .../SimpleFlowspecIpv4NlriParserTest.java | 321 +++---- .../SimpleFlowspecIpv6NlriParserTest.java | 178 ++-- 16 files changed, 2316 insertions(+), 569 deletions(-) create mode 100644 bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv4/FlowspecIpv4NlriParserHelper.java create mode 100644 bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv6/FlowspecIpv6NlriParserHelper.java create mode 100644 bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java create mode 100644 bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4NlriParser.java create mode 100644 bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6NlriParser.java create mode 100644 bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java create mode 100644 bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv6NlriParserTest.java diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecNlriParser.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecNlriParser.java index 2e05635410..541266784b 100644 --- a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecNlriParser.java +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecNlriParser.java @@ -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 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 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 flowspecList = (List) nlriFields[0]; + serializeNlri(flowspecList, buffer); + } + + protected final void serializeNlri(final List 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 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 extractFlowspec(final DataContainerNode route) { + Preconditions.checkNotNull(route, "Cannot extract flowspec from null route."); final List fsList = new ArrayList<>(); final Optional> 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> 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 flows) { + protected final String stringNlri(final List flows) { final StringBuilder buffer = new StringBuilder("all packets "); final Joiner joiner = Joiner.on(FLOW_SEPARATOR); - joiner.appendTo(buffer, Iterables.transform(flows, new Function() { - @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 parseNlri(final ByteBuf nlri) throws BGPParsingException { + protected final List parseNlriFlowspecList(@Nonnull final ByteBuf nlri) throws BGPParsingException { if (!nlri.isReadable()) { return null; } final List 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 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 afi, final Class safi, + @Nullable + protected final PathId readPathId(@Nonnull final ByteBuf nlri, final Class afi, final Class 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 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() + ); } } + diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java index 1dd63ef3fd..a7a244b6f3 100644 --- a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java @@ -59,7 +59,7 @@ public abstract class AbstractFlowspecRIBSupport extends MultiPathAbstractRIBSup protected DestinationType buildDestination(@Nonnull final Collection 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 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 diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/BGPActivator.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/BGPActivator.java index 1a229cda9f..707fe1e946 100644 --- a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/BGPActivator.java +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/BGPActivator.java @@ -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)); diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecActivator.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecActivator.java index 50fc6ae2a5..ac131f5cf6 100644 --- a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecActivator.java +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecActivator.java @@ -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 regs, - final SimpleFlowspecExtensionProviderContext context + final SimpleFlowspecExtensionProviderContext.AFI afi, + final SimpleFlowspecExtensionProviderContext.SAFI safi, + final List 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 regs, - final SimpleFlowspecExtensionProviderContext context + final SimpleFlowspecExtensionProviderContext.AFI afi, + final SimpleFlowspecExtensionProviderContext.SAFI safi, + final List 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 regs, - final SimpleFlowspecExtensionProviderContext context + final SimpleFlowspecExtensionProviderContext.AFI afi, + final SimpleFlowspecExtensionProviderContext.SAFI safi, + final List regs, + final SimpleFlowspecExtensionProviderContext context ) { final SimpleFlowspecTypeRegistry flowspecTypeRegistry = context.getFlowspecTypeRegistry(afi, safi); diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParser.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParser.java index 483f670772..b6a08f8e66 100644 --- a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParser.java +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParser.java @@ -7,141 +7,76 @@ */ 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 dst, @Nullable final PathId pathId) { + protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) { + final List flowspecList = (List) 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 dst, @Nullable final PathId pathId) { + protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) { + final List flowspecList = (List) 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 createProtocolsIps(final UnkeyedListNode protocolIpsData) { - final List protocolIps = new ArrayList<>(); - - for (final UnkeyedListEntryNode node : protocolIpsData.getValue()) { - final ProtocolIpsBuilder ipsBuilder = new ProtocolIpsBuilder(); - final Optional> opValue = node.getChild(OP_NID); - if (opValue.isPresent()) { - ipsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set) opValue.get().getValue())); - } - final Optional> 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); } } } + diff --git a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParser.java b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParser.java index a578df8bbd..3acc478e95 100644 --- a/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParser.java +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParser.java @@ -7,184 +7,76 @@ */ 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 dst, @Nullable final PathId pathId) { + protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) { + final List flowspecList = (List) 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 dst, @Nullable final PathId pathId) { + protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) { + final List flowspecList = (List) 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 createNextHeaders(final UnkeyedListNode nextHeadersData) { - final List nextHeaders = new ArrayList<>(); - - for (final UnkeyedListEntryNode node : nextHeadersData.getValue()) { - final NextHeadersBuilder nextHeadersBuilder = new NextHeadersBuilder(); - final Optional> opValue = node.getChild(OP_NID); - if (opValue.isPresent()) { - nextHeadersBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set) opValue.get().getValue())); - } - final Optional> valueNode = node.getChild(VALUE_NID); - if (valueNode.isPresent()) { - nextHeadersBuilder.setValue((Short) valueNode.get().getValue()); - } - nextHeaders.add(nextHeadersBuilder.build()); - } - - return nextHeaders; - } - - private List createFlowLabels(final UnkeyedListNode flowLabelsData) { - final List flowLabels = new ArrayList<>(); - - for (final UnkeyedListEntryNode node : flowLabelsData.getValue()) { - final FlowLabelBuilder flowLabelsBuilder = new FlowLabelBuilder(); - final Optional> opValue = node.getChild(OP_NID); - if (opValue.isPresent()) { - flowLabelsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set) opValue.get().getValue())); - } - final Optional> 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 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 index 0000000000..4d7b6382cd --- /dev/null +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv4/FlowspecIpv4NlriParserHelper.java @@ -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 createProtocolsIps(final UnkeyedListNode protocolIpsData) { + final List protocolIps = new ArrayList<>(); + + for (final UnkeyedListEntryNode node : protocolIpsData.getValue()) { + final ProtocolIpsBuilder ipsBuilder = new ProtocolIpsBuilder(); + final Optional> opValue = node.getChild(AbstractFlowspecNlriParser.OP_NID); + if (opValue.isPresent()) { + ipsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set) opValue.get().getValue())); + } + final Optional> 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 index 0000000000..3afa897f11 --- /dev/null +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/ipv6/FlowspecIpv6NlriParserHelper.java @@ -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 createNextHeaders(final UnkeyedListNode nextHeadersData) { + final List nextHeaders = new ArrayList<>(); + + for (final UnkeyedListEntryNode node : nextHeadersData.getValue()) { + final NextHeadersBuilder nextHeadersBuilder = new NextHeadersBuilder(); + final Optional> opValue = node.getChild(AbstractFlowspecNlriParser.OP_NID); + if (opValue.isPresent()) { + nextHeadersBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set) opValue.get().getValue())); + } + final Optional> 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 createFlowLabels(final UnkeyedListNode flowLabelsData) { + final List flowLabels = new ArrayList<>(); + + for (final UnkeyedListEntryNode node : flowLabelsData.getValue()) { + final FlowLabelBuilder flowLabelsBuilder = new FlowLabelBuilder(); + final Optional> opValue = node.getChild(AbstractFlowspecNlriParser.OP_NID); + if (opValue.isPresent()) { + flowLabelsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set) opValue.get().getValue())); + } + final Optional> 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 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 index 0000000000..2a754fd943 --- /dev/null +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java @@ -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> 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 flowspecList = (List) 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 index 0000000000..8ad5b9be0d --- /dev/null +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4NlriParser.java @@ -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 flowspecList = (List) 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 flowspecList = (List) 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 index 0000000000..c5e3ad18ba --- /dev/null +++ b/bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6NlriParser.java @@ -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 flowspecList = (List) 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 flowspecList = (List) 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 + ); + } + } +} diff --git a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/ActivatorTest.java b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/ActivatorTest.java index 47b7d7936a..900987ceea 100644 --- a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/ActivatorTest.java +++ b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/ActivatorTest.java @@ -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 index 0000000000..94502a10ae --- /dev/null +++ b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java @@ -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 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 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 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 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 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 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 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 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 = 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 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 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 = 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 = 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 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 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 = 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 = 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 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 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 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 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecSourcePrefix() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecProtocolIps() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecPorts() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecDestinationPorts() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecSourcePorts() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecSourceTypes() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecSourceCodes() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecSourceTcpFlags() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecPacketLengths() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecDscps() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecFragments() { + final DataContainerNodeAttrBuilder 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 expected = new ArrayList<>(); + expected.add(expectedFS.build()); + assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecRouteDistinguisher() { + final DataContainerNodeAttrBuilder 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 index 0000000000..e53319bc85 --- /dev/null +++ b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv6NlriParserTest.java @@ -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 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 = 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 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 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 = 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 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 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 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 = 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 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 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 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 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.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.newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build()); + final List expectedValue = new ArrayList<>(); + expectedValue.add(expectedFS.build()); + assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecNextHeaders() { + final DataContainerNodeAttrBuilder 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.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.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.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.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 expectedValue = new ArrayList<>(); + expectedValue.add(expectedFS.build()); + assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecFlowLabels() { + final DataContainerNodeAttrBuilder 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.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.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.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 expectedValue = new ArrayList<>(); + expectedValue.add(expectedFS.build()); + assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecDestPrefix() { + final DataContainerNodeAttrBuilder 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 expectedValue = new ArrayList<>(); + expectedValue.add(expectedFS.build()); + assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); + } + + @Test + public void testExtractFlowspecSourcePrefix() { + final DataContainerNodeAttrBuilder 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 expectedValue = new ArrayList<>(); + expectedValue.add(expectedFS.build()); + assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); + } +} + diff --git a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParserTest.java b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParserTest.java index 2b40f85eec..4f4aa10c9e 100644 --- a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParserTest.java +++ b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv4NlriParserTest.java @@ -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 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 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 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 = 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 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 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 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 = 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 = 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 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 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 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 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.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.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.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.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.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.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.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 expected = new ArrayList<>(); expected.add(expectedFS.build()); assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); @@ -555,16 +559,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new PortsBuilder().setValue(100).setOp(new NumericOperand(true, true, false, false, true)).build())).build()); @@ -578,16 +582,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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 expected = new ArrayList<>(); @@ -600,16 +604,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new SourcePortsBuilder().setValue(8080).setOp(new NumericOperand(true, true, true, true, true)).build())).build()); final List expected = new ArrayList<>(); @@ -622,16 +626,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new TypesBuilder().setValue((short) 22).setOp(new NumericOperand(true, true, true, true, true)).build())).build()); final List expected = new ArrayList<>(); @@ -644,16 +648,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new CodesBuilder().setValue((short) 23).setOp(new NumericOperand(false, false, false, false, false)).build())).build()); final List expected = new ArrayList<>(); @@ -666,16 +670,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new TcpFlagsBuilder().setValue(99).setOp(new BitmaskOperand(true, true, false, false)).build())).build()); final List expected = new ArrayList<>(); @@ -688,16 +692,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new PacketLengthsBuilder().setValue(101).setOp(new NumericOperand(true, false, false, true, false)).build())).build()); final List expected = new ArrayList<>(); @@ -710,16 +714,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new DscpsBuilder().setValue(new Dscp((short) 15)).setOp(new NumericOperand(true, true, false, true, false)).build())).build()); final List expected = new ArrayList<>(); @@ -732,16 +736,16 @@ public class SimpleFlowspecIpv4NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build()); final List expected = new ArrayList<>(); @@ -749,3 +753,4 @@ public class SimpleFlowspecIpv4NlriParserTest { assertEquals(expected, FS_PARSER.extractFlowspec(entry.build())); } } + diff --git a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParserTest.java b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParserTest.java index aaeec26737..c41f519874 100644 --- a/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParserTest.java +++ b/bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/SimpleFlowspecIpv6NlriParserTest.java @@ -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 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 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 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 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 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.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.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.newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build()); final List expectedValue = new ArrayList<>(); @@ -339,28 +344,28 @@ public class SimpleFlowspecIpv6NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.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.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.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.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.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 expectedValue = new ArrayList<>(); expectedValue.add(expectedFS.build()); assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); @@ -371,24 +376,24 @@ public class SimpleFlowspecIpv6NlriParserTest { final DataContainerNodeAttrBuilder 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.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.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.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.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.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 expectedValue = new ArrayList<>(); expectedValue.add(expectedFS.build()); assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); @@ -399,12 +404,12 @@ public class SimpleFlowspecIpv6NlriParserTest { final DataContainerNodeAttrBuilder 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 expectedValue = new ArrayList<>(); @@ -417,12 +422,12 @@ public class SimpleFlowspecIpv6NlriParserTest { final DataContainerNodeAttrBuilder 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 expectedValue = new ArrayList<>(); @@ -430,3 +435,4 @@ public class SimpleFlowspecIpv6NlriParserTest { assertEquals(expectedValue, FS_PARSER.extractFlowspec(entry.build())); } } + -- 2.36.6