MVPN Routes PArser/Serializer 09/72009/4
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Tue, 15 May 2018 08:25:30 +0000 (10:25 +0200)
committerClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Tue, 15 May 2018 11:48:40 +0000 (13:48 +0200)
JIRA: BGPCEP-396
Change-Id: I02535dd90ae1cd3563a44980df016d10ce33ebed
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
23 files changed:
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/NlriActivator.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/AbstractMvpnNlri.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/CMulticastUtil.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/InterASIPmsiADHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/IntraAsIPmsiADHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/LeafADHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/MulticastGroupOpaqueUtil.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SPmsiADHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SharedTreeJoinHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceActiveADHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceTreeJoinHandler.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnParser.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnRegistry.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnSerializer.java [new file with mode: 0644]
bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/pojo/nlri/SimpleMvpnNlriRegistry.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/InterASIPmsiADHandlerTest.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/IntraAsIPmsiADHandlerTest.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/LeafADHandlerTest.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SPmsiADHandlerTest.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SharedTreeJoinHandlerTest.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceActiveADHandlerTest.java [new file with mode: 0644]
bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceTreeJoinHandlerTest.java [new file with mode: 0644]
bgp/parser-api/src/main/java/org/opendaylight/protocol/bgp/parser/AsNumberUtil.java

diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/NlriActivator.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/NlriActivator.java
new file mode 100644 (file)
index 0000000..e899bca
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl;
+
+import java.util.List;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.InterASIPmsiADHandler;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.IntraAsIPmsiADHandler;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.LeafADHandler;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.SPmsiADHandler;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.SharedTreeJoinHandler;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.SourceActiveADHandler;
+import org.opendaylight.protocol.bgp.mvpn.impl.nlri.SourceTreeJoinHandler;
+import org.opendaylight.protocol.bgp.mvpn.spi.pojo.nlri.SimpleMvpnNlriRegistry;
+
+/**
+ * Nlri Registry activator.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class NlriActivator {
+    private NlriActivator() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static void registerNlriParsers(final List<AutoCloseable> regs) {
+        final SimpleMvpnNlriRegistry nlriRegistry = SimpleMvpnNlriRegistry.getInstance();
+
+        final IntraAsIPmsiADHandler intra = new IntraAsIPmsiADHandler();
+        regs.add(nlriRegistry.registerNlriParser(intra));
+        regs.add(nlriRegistry.registerNlriSerializer(intra));
+
+        final InterASIPmsiADHandler inter = new InterASIPmsiADHandler();
+        regs.add(nlriRegistry.registerNlriParser(inter));
+        regs.add(nlriRegistry.registerNlriSerializer(inter));
+
+        final SPmsiADHandler sPmsiADHandler = new SPmsiADHandler();
+        regs.add(nlriRegistry.registerNlriParser(sPmsiADHandler));
+        regs.add(nlriRegistry.registerNlriSerializer(sPmsiADHandler));
+
+        final LeafADHandler leafHandler = new LeafADHandler();
+        regs.add(nlriRegistry.registerNlriParser(leafHandler));
+        regs.add(nlriRegistry.registerNlriSerializer(leafHandler));
+
+        final SourceActiveADHandler activeADHandler = new SourceActiveADHandler();
+        regs.add(nlriRegistry.registerNlriParser(activeADHandler));
+        regs.add(nlriRegistry.registerNlriSerializer(activeADHandler));
+
+        final SharedTreeJoinHandler sharedTreeJoinHandler = new SharedTreeJoinHandler();
+        regs.add(nlriRegistry.registerNlriParser(sharedTreeJoinHandler));
+        regs.add(nlriRegistry.registerNlriSerializer(sharedTreeJoinHandler));
+
+        final SourceTreeJoinHandler sourceTreeJoinHandler = new SourceTreeJoinHandler();
+        regs.add(nlriRegistry.registerNlriParser(sourceTreeJoinHandler));
+        regs.add(nlriRegistry.registerNlriSerializer(sourceTreeJoinHandler));
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/AbstractMvpnNlri.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/AbstractMvpnNlri.java
new file mode 100644 (file)
index 0000000..3a2b09c
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.protocol.bgp.mvpn.spi.nlri.MvpnParser;
+import org.opendaylight.protocol.bgp.mvpn.spi.nlri.MvpnSerializer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.MulticastSourceRdGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.s.pmsi.a.d.grouping.SPmsiADBuilder;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+
+/**
+ * Abstract Mvpn Nlri.
+ *
+ * @author Claudio D. Gasparini
+ */
+abstract class AbstractMvpnNlri<T extends MvpnChoice> implements MvpnSerializer<T>, MvpnParser<T> {
+    static final NodeIdentifier RD_NID = NodeIdentifier.create(QName.create(MvpnChoice.QNAME,
+            "route-distinguisher").intern());
+    static final NodeIdentifier ORI_NID = NodeIdentifier.create(QName.create(MvpnChoice.QNAME,
+            "orig-route-ip").intern());
+    static final NodeIdentifier SOURCE_AS_NID = NodeIdentifier.create(QName.create(MvpnChoice.QNAME,
+            "source-as").intern());
+    static final NodeIdentifier MULTICAST_SOURCE_NID = NodeIdentifier.create(QName.create(MvpnChoice.QNAME,
+            "multicast-source").intern());
+    static final NodeIdentifier MULTICAST_GROUP_NID = NodeIdentifier.create(QName.create(MvpnChoice.QNAME,
+            "multicast-group").intern());
+
+    @Override
+    public final ByteBuf serializeMvpn(final T mvpn, final ByteBuf common) {
+        final ByteBuf output = Unpooled.buffer();
+        final ByteBuf body = serializeBody(mvpn);
+        output.writeByte(getType());
+        output.writeByte(body.readableBytes() + common.readableBytes());
+        output.writeBytes(common);
+        output.writeBytes(body);
+        return output;
+    }
+
+    protected abstract ByteBuf serializeBody(T mvpn);
+
+
+    final MulticastSourceRdGrouping parseRDMulticastSource(final ByteBuf buffer) {
+        final SPmsiADBuilder builder = new SPmsiADBuilder();
+        builder.setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(buffer));
+        final IpAddress address = IpAddressUtil.addressForByteBuf(buffer);
+        builder.setMulticastSource(address);
+        return builder.build();
+    }
+
+    final void serializeRDMulticastSource(final MulticastSourceRdGrouping route, final ByteBuf output) {
+        RouteDistinguisherUtil.serializeRouteDistinquisher(route.getRouteDistinguisher(), output);
+        output.writeBytes(IpAddressUtil.bytesFor(route.getMulticastSource()));
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/CMulticastUtil.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/CMulticastUtil.java
new file mode 100644 (file)
index 0000000..06125ee
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.c.multicast.grouping.CMulticast;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.c.multicast.grouping.CMulticastBuilder;
+
+/**
+ * Common CMulticast Handler.
+ *
+ * @author Claudio D. Gasparini
+ */
+final class CMulticastUtil {
+
+    private CMulticastUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    static CMulticast parseCMulticastGrouping(final ByteBuf buffer) {
+        final CMulticastBuilder builder = new CMulticastBuilder();
+        builder.setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(buffer));
+        builder.setSourceAs(new AsNumber(buffer.readUnsignedInt()));
+        builder.setMulticastSource(IpAddressUtil.addressForByteBuf(buffer));
+        builder.setMulticastGroup(MulticastGroupOpaqueUtil.multicastGroupForByteBuf(buffer));
+        return builder.build();
+    }
+
+
+    static ByteBuf serializeCMulticast(final CMulticast route) {
+        final ByteBuf nlriByteBuf = Unpooled.buffer();
+        RouteDistinguisherUtil.serializeRouteDistinquisher(route.getRouteDistinguisher(), nlriByteBuf);
+        nlriByteBuf.writeInt(route.getSourceAs().getValue().intValue());
+        nlriByteBuf.writeBytes(IpAddressUtil.bytesFor(route.getMulticastSource()));
+        MulticastGroupOpaqueUtil.bytesForMulticastGroup(route.getMulticastGroup(), nlriByteBuf);
+        return nlriByteBuf;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/InterASIPmsiADHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/InterASIPmsiADHandler.java
new file mode 100644 (file)
index 0000000..2e080c2
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.inter.as.i.pmsi.a.d.grouping.InterAsIPmsiAD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.inter.as.i.pmsi.a.d.grouping.InterAsIPmsiADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.InterAsIPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.InterAsIPmsiADCaseBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.2 .
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class InterASIPmsiADHandler extends AbstractMvpnNlri<InterAsIPmsiADCase> {
+    private static final int CONTENT_LENGTH = 12;
+
+    @Override
+    public int getType() {
+        return NlriType.InterAsIPmsiAD.getIntValue();
+    }
+
+    @Override
+    public InterAsIPmsiADCase parseMvpn(final ByteBuf buffer) {
+        Preconditions.checkArgument(buffer.readableBytes() == CONTENT_LENGTH,
+                "Wrong length of array of bytes. Passed: %s ;", buffer);
+        return new InterAsIPmsiADCaseBuilder()
+                .setInterAsIPmsiAD(new InterAsIPmsiADBuilder()
+                        .setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(buffer))
+                        .setSourceAs(new AsNumber(buffer.readUnsignedInt()))
+                        .build())
+                .build();
+    }
+
+    @Override
+    protected ByteBuf serializeBody(final InterAsIPmsiADCase mvpn) {
+        final InterAsIPmsiAD route = mvpn.getInterAsIPmsiAD();
+        final ByteBuf nlriByteBuf = Unpooled.buffer();
+        RouteDistinguisherUtil.serializeRouteDistinquisher(route.getRouteDistinguisher(), nlriByteBuf);
+        nlriByteBuf.writeInt(route.getSourceAs().getValue().intValue());
+        return nlriByteBuf;
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return InterAsIPmsiADCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/IntraAsIPmsiADHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/IntraAsIPmsiADHandler.java
new file mode 100644 (file)
index 0000000..a4ad7e9
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.intra.as.i.pmsi.a.d.grouping.IntraAsIPmsiAD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.intra.as.i.pmsi.a.d.grouping.IntraAsIPmsiADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.IntraAsIPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.IntraAsIPmsiADCaseBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.1.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class IntraAsIPmsiADHandler extends AbstractMvpnNlri<IntraAsIPmsiADCase> {
+
+    private static final int IPV4_CONTENT_LENGTH = 12;
+    private static final int IPV6_CONTENT_LENGTH = 24;
+
+    @Override
+    public int getType() {
+        return NlriType.IntraAsIPmsiAD.getIntValue();
+    }
+
+    @Override
+    public IntraAsIPmsiADCase parseMvpn(final ByteBuf buffer) {
+        Preconditions.checkArgument(buffer.readableBytes() == IPV4_CONTENT_LENGTH
+                        || buffer.readableBytes() == IPV6_CONTENT_LENGTH,
+                "Wrong length of array of bytes. Passed: %s ;", buffer);
+        return new IntraAsIPmsiADCaseBuilder()
+                .setIntraAsIPmsiAD(new IntraAsIPmsiADBuilder()
+                        .setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(buffer))
+                        .setOrigRouteIp(IpAddressUtil.addressForByteBufWOLength(buffer))
+                        .build())
+                .build();
+    }
+
+    @Override
+    protected ByteBuf serializeBody(final IntraAsIPmsiADCase mvpn) {
+        final IntraAsIPmsiAD route = mvpn.getIntraAsIPmsiAD();
+        final ByteBuf nlriByteBuf = Unpooled.buffer();
+        RouteDistinguisherUtil.serializeRouteDistinquisher(route.getRouteDistinguisher(), nlriByteBuf);
+        final ByteBuf orig = IpAddressUtil.bytesWOLengthFor(route.getOrigRouteIp());
+        Preconditions.checkArgument(orig.readableBytes() > 0);
+        nlriByteBuf.writeBytes(orig);
+        return nlriByteBuf;
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return IntraAsIPmsiADCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/LeafADHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/LeafADHandler.java
new file mode 100644 (file)
index 0000000..5a29f08
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.protocol.bgp.mvpn.spi.pojo.nlri.SimpleMvpnNlriRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.LeafAD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.LeafADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.leaf.a.d.LeafADRouteKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.leaf.a.d.leaf.a.d.route.key.InterAsIPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.leaf.a.d.leaf.a.d.route.key.InterAsIPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.leaf.a.d.leaf.a.d.route.key.SPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.leaf.a.d.leaf.a.d.route.key.SPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.LeafADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.LeafADCaseBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.4.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class LeafADHandler extends AbstractMvpnNlri<LeafADCase> {
+    @Override
+    public int getType() {
+        return NlriType.LeafAD.getIntValue();
+    }
+
+    @Override
+    public LeafADCase parseMvpn(final ByteBuf buffer) {
+        final NlriType type = NlriType.forValue(buffer.readUnsignedByte());
+        final short length = buffer.readUnsignedByte();
+        final MvpnChoice key = SimpleMvpnNlriRegistry.getInstance().parseMvpn(type, buffer.readBytes(length));
+        final LeafADRouteKey routeKey;
+        if (type == NlriType.InterAsIPmsiAD) {
+            routeKey = new InterAsIPmsiADCaseBuilder((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
+                    .bgp.mvpn.rev180417.mvpn.mvpn.choice.InterAsIPmsiADCase) key).build();
+        } else {
+            routeKey = new SPmsiADCaseBuilder((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
+                    .mvpn.rev180417.mvpn.mvpn.choice.SPmsiADCase) key).build();
+        }
+        return new LeafADCaseBuilder().setLeafAD(new LeafADBuilder()
+                .setLeafADRouteKey(routeKey)
+                .setOrigRouteIp(IpAddressUtil.addressForByteBufWOLength(buffer)).build())
+                .build();
+    }
+
+    @Override
+    protected ByteBuf serializeBody(final LeafADCase mvpn) {
+        final LeafAD leaf = mvpn.getLeafAD();
+        final ByteBuf nlriByteBuf = Unpooled.buffer();
+        final LeafADRouteKey key = leaf.getLeafADRouteKey();
+        final MvpnChoice keyCase;
+        if (key instanceof InterAsIPmsiADCase) {
+            keyCase = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
+                    .bgp.mvpn.rev180417.mvpn.mvpn.choice.InterAsIPmsiADCaseBuilder((InterAsIPmsiADCase) key).build();
+        } else {
+            keyCase = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn
+                    .mvpn.choice.SPmsiADCaseBuilder((SPmsiADCase) key).build();
+        }
+        nlriByteBuf.writeBytes(SimpleMvpnNlriRegistry.getInstance().serializeMvpn(keyCase, nlriByteBuf));
+        final ByteBuf orig = IpAddressUtil.bytesWOLengthFor(leaf.getOrigRouteIp());
+        Preconditions.checkArgument(orig.readableBytes() > 0);
+        nlriByteBuf.writeBytes(orig);
+        return nlriByteBuf;
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return LeafADCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/MulticastGroupOpaqueUtil.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/MulticastGroupOpaqueUtil.java
new file mode 100644 (file)
index 0000000..932c17e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.protocol.bgp.mvpn.impl.attributes.OpaqueUtil;
+import org.opendaylight.protocol.util.Ipv4Util;
+import org.opendaylight.protocol.util.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.MulticastGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.CGAddressCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.CGAddressCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.LdpMpOpaqueValueCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.LdpMpOpaqueValueCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.c.g.address._case.CGAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.ldp.mp.opaque.value._case.LdpMpOpaqueValueBuilder;
+
+/**
+ * Multicast Group  with Opaque values Utility.
+ *
+ * @author Claudio D. Gasparini
+ */
+final class MulticastGroupOpaqueUtil {
+    private MulticastGroupOpaqueUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    static MulticastGroup multicastGroupForByteBuf(final ByteBuf buffer) {
+        final short multicastGroupLength = buffer.readUnsignedByte();
+        if (multicastGroupLength == Ipv4Util.IP4_BITS_LENGTH) {
+            return new CGAddressCaseBuilder().setCGAddress(new CGAddressBuilder()
+                    .setCGAddress(new IpAddress(Ipv4Util.addressForByteBuf(buffer)))
+                    .build()).build();
+        } else if (multicastGroupLength == Ipv6Util.IPV6_BITS_LENGTH) {
+            return new CGAddressCaseBuilder().setCGAddress(new CGAddressBuilder()
+                    .setCGAddress(new IpAddress(Ipv6Util.addressForByteBuf(buffer))).build()).build();
+        } else {
+            return new LdpMpOpaqueValueCaseBuilder()
+                    .setLdpMpOpaqueValue(new LdpMpOpaqueValueBuilder(OpaqueUtil.parseOpaque(buffer)).build()).build();
+        }
+    }
+
+    static void bytesForMulticastGroup(final MulticastGroup group, final ByteBuf nlriByteBuf) {
+        if (group instanceof CGAddressCase) {
+            nlriByteBuf.writeBytes(IpAddressUtil.bytesFor(((CGAddressCase) group).getCGAddress().getCGAddress()));
+        } else {
+            OpaqueUtil.serializeOpaque(((LdpMpOpaqueValueCase) group).getLdpMpOpaqueValue(), nlriByteBuf);
+        }
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SPmsiADHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SPmsiADHandler.java
new file mode 100644 (file)
index 0000000..185fa01
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.s.pmsi.a.d.grouping.SPmsiAD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.s.pmsi.a.d.grouping.SPmsiADBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.3.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class SPmsiADHandler extends AbstractMvpnNlri<SPmsiADCase> {
+
+    @Override
+    public int getType() {
+        return NlriType.SPmsiAD.getIntValue();
+    }
+
+    @Override
+    public SPmsiADCase parseMvpn(final ByteBuf buffer) {
+        final SPmsiADBuilder builder = new SPmsiADBuilder(parseRDMulticastSource(buffer));
+        builder.setMulticastGroup(MulticastGroupOpaqueUtil.multicastGroupForByteBuf(buffer));
+        builder.setOrigRouteIp(IpAddressUtil.addressForByteBufWOLength(buffer));
+        return new SPmsiADCaseBuilder().setSPmsiAD(builder.build()).build();
+    }
+
+    @Override
+    protected ByteBuf serializeBody(final SPmsiADCase mvpn) {
+        final SPmsiAD route = mvpn.getSPmsiAD();
+        final ByteBuf nlriByteBuf = Unpooled.buffer();
+        serializeRDMulticastSource(route, nlriByteBuf);
+        MulticastGroupOpaqueUtil.bytesForMulticastGroup(route.getMulticastGroup(), nlriByteBuf);
+        nlriByteBuf.writeBytes(IpAddressUtil.bytesWOLengthFor(route.getOrigRouteIp()));
+        return nlriByteBuf;
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return SPmsiADCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SharedTreeJoinHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SharedTreeJoinHandler.java
new file mode 100644 (file)
index 0000000..68f095e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SharedTreeJoinCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SharedTreeJoinCaseBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.6.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class SharedTreeJoinHandler extends AbstractMvpnNlri<SharedTreeJoinCase> {
+    @Override
+    public int getType() {
+        return NlriType.SharedTreeJoin.getIntValue();
+    }
+
+    @Override
+    public SharedTreeJoinCase parseMvpn(final ByteBuf buffer) {
+        return new SharedTreeJoinCaseBuilder().setCMulticast(CMulticastUtil.parseCMulticastGrouping(buffer)).build();
+    }
+
+    @Override
+    protected ByteBuf serializeBody(final SharedTreeJoinCase mvpn) {
+        return CMulticastUtil.serializeCMulticast(mvpn.getCMulticast());
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return SharedTreeJoinCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceActiveADHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceActiveADHandler.java
new file mode 100644 (file)
index 0000000..cdd0043
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.bgp.concepts.IpAddressUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceActiveADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceActiveADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.source.active.a.d.grouping.SourceActiveAD;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.source.active.a.d.grouping.SourceActiveADBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.5.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class SourceActiveADHandler extends AbstractMvpnNlri<SourceActiveADCase> {
+    @Override
+    public int getType() {
+        return NlriType.SourceActiveAD.getIntValue();
+    }
+
+    @Override
+    public SourceActiveADCase parseMvpn(final ByteBuf buffer) {
+        final SourceActiveADBuilder builder = new SourceActiveADBuilder(parseRDMulticastSource(buffer));
+        builder.setMulticastGroup(IpAddressUtil.addressForByteBuf(buffer));
+        return new SourceActiveADCaseBuilder().setSourceActiveAD(builder.build()).build();
+    }
+
+
+    @Override
+    protected ByteBuf serializeBody(final SourceActiveADCase mvpn) {
+        final SourceActiveAD route = mvpn.getSourceActiveAD();
+        final ByteBuf nlriByteBuf = Unpooled.buffer();
+        serializeRDMulticastSource(route, nlriByteBuf);
+        nlriByteBuf.writeBytes(IpAddressUtil.bytesFor(route.getMulticastGroup()));
+        return nlriByteBuf;
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return SourceActiveADCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceTreeJoinHandler.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceTreeJoinHandler.java
new file mode 100644 (file)
index 0000000..7e08717
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceTreeJoinCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceTreeJoinCaseBuilder;
+
+/**
+ * https://tools.ietf.org/html/rfc6514#section-4.6.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class SourceTreeJoinHandler extends AbstractMvpnNlri<SourceTreeJoinCase> {
+    @Override
+    public int getType() {
+        return NlriType.SourceTreeJoin.getIntValue();
+    }
+
+    @Override
+
+    public SourceTreeJoinCase parseMvpn(final ByteBuf buffer) {
+        return new SourceTreeJoinCaseBuilder().setCMulticast(CMulticastUtil.parseCMulticastGrouping(buffer)).build();
+    }
+
+    @Override
+    protected ByteBuf serializeBody(final SourceTreeJoinCase mvpn) {
+        return CMulticastUtil.serializeCMulticast(mvpn.getCMulticast());
+    }
+
+    @Override
+    public Class<? extends MvpnChoice> getClazz() {
+        return SourceTreeJoinCase.class;
+    }
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnParser.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnParser.java
new file mode 100644 (file)
index 0000000..ed40761
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.spi.nlri;
+
+import io.netty.buffer.ByteBuf;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+
+public interface MvpnParser<T extends MvpnChoice> {
+    /**
+     * Decode input buffer to BGP Mvpn.
+     *
+     * @param buffer encoded Mvpn body in Bytebuf
+     * @return Mvpn
+     */
+    @Nonnull
+    T parseMvpn(@Nonnull ByteBuf buffer);
+
+    /**
+     * Returns NlriType handled by parser.
+     *
+     * @return NlriType
+     */
+    int getType();
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnRegistry.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnRegistry.java
new file mode 100644 (file)
index 0000000..60899a3
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.spi.nlri;
+
+import io.netty.buffer.ByteBuf;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+
+public interface MvpnRegistry {
+    /**
+     * Decode input buffer to BGP Mvpn.
+     *
+     * @param type   Nlri Type
+     * @param buffer encoded MvpnChoice body in Bytebuf
+     * @return MvpnChoice
+     */
+    @Nullable
+    MvpnChoice parseMvpn(@Nonnull NlriType type, @Nonnull ByteBuf buffer);
+
+    /**
+     * Encode input BGP mvpn to output buffer.
+     *
+     * @param mvpn   MvpnChoice
+     * @param common encoded common mvpn
+     * @return encoded MvpnChoice body in Bytebuf
+     */
+    @Nonnull
+    ByteBuf serializeMvpn(@Nonnull MvpnChoice mvpn, @Nonnull ByteBuf common);
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnSerializer.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/nlri/MvpnSerializer.java
new file mode 100644 (file)
index 0000000..71ea5ba
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.spi.nlri;
+
+import io.netty.buffer.ByteBuf;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+
+public interface MvpnSerializer<T extends MvpnChoice> {
+    /**
+     * Serialize mvpn.
+     *
+     * @param mvpn   mvpn
+     * @param buffer Encode common mvpn parts to output buffer
+     * @return Encode mvpn to output buffer
+     */
+    @Nonnull
+    ByteBuf serializeMvpn(@Nonnull T mvpn, @Nonnull ByteBuf buffer);
+
+    /**
+     * returns class of MvpnChoice handled by serializer.
+     *
+     * @return MvpnChoice Class
+     */
+    Class<? extends MvpnChoice> getClazz();
+}
diff --git a/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/pojo/nlri/SimpleMvpnNlriRegistry.java b/bgp/mvpn/src/main/java/org/opendaylight/protocol/bgp/mvpn/spi/pojo/nlri/SimpleMvpnNlriRegistry.java
new file mode 100644 (file)
index 0000000..a9a156d
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.spi.pojo.nlri;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.mvpn.spi.nlri.MvpnParser;
+import org.opendaylight.protocol.bgp.mvpn.spi.nlri.MvpnRegistry;
+import org.opendaylight.protocol.bgp.mvpn.spi.nlri.MvpnSerializer;
+import org.opendaylight.protocol.concepts.HandlerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.MvpnChoice;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * Mvpn Nlri Registry.
+ *
+ * @author Claudio D. Gasparini
+ */
+public final class SimpleMvpnNlriRegistry implements MvpnRegistry {
+    private static final SimpleMvpnNlriRegistry SINGLETON = new SimpleMvpnNlriRegistry();
+    private final HandlerRegistry<DataContainer, MvpnParser, MvpnSerializer> handlers = new HandlerRegistry<>();
+
+    private SimpleMvpnNlriRegistry() {
+    }
+
+    public static SimpleMvpnNlriRegistry getInstance() {
+        return SINGLETON;
+    }
+
+    public <T extends MvpnChoice> AutoCloseable registerNlriParser(
+            final MvpnParser<T> parser) {
+        return this.handlers.registerParser(parser.getType(), parser);
+    }
+
+    public <T extends MvpnChoice> AutoCloseable registerNlriSerializer(
+            final MvpnSerializer<T> serializer) {
+        return this.handlers.registerSerializer(serializer.getClazz(), serializer);
+    }
+
+    public MvpnChoice parseMvpn(final NlriType type, final ByteBuf nlriBuf) {
+        Preconditions.checkArgument(nlriBuf != null && nlriBuf.isReadable(),
+                "Array of bytes is mandatory. Can't be null or empty.");
+        final MvpnParser parser = this.handlers.getParser(type.getIntValue());
+        if (parser == null) {
+            return null;
+        }
+        return parser.parseMvpn(nlriBuf);
+    }
+
+    public ByteBuf serializeMvpn(final MvpnChoice mvpn, final ByteBuf nlriBuf) {
+        final MvpnSerializer serializer = this.handlers.getSerializer(mvpn.getImplementedInterface());
+        if (serializer == null) {
+            return nlriBuf;
+        }
+        return serializer.serializeMvpn(mvpn, nlriBuf);
+    }
+}
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/InterASIPmsiADHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/InterASIPmsiADHandlerTest.java
new file mode 100644 (file)
index 0000000..42c40da
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.inter.as.i.pmsi.a.d.grouping.InterAsIPmsiADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.InterAsIPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.InterAsIPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public final class InterASIPmsiADHandlerTest {
+
+    private static final byte[] INTER_AS = new byte[]{
+        0, 1,
+        1, 2, 3, 4, 1, 2,
+        0, 0, 0, 1
+    };
+    private static final byte[] INTER_AS_TYPE_LENGTH = new byte[]{
+        2, 12,
+        0, 1,
+        1, 2, 3, 4, 1, 2,
+        0, 0, 0, 1
+    };
+
+    private final InterAsIPmsiADCase expected = new InterAsIPmsiADCaseBuilder()
+            .setInterAsIPmsiAD(new InterAsIPmsiADBuilder()
+                    .setSourceAs(new AsNumber(1L))
+                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                    .build()
+            ).build();
+    private InterASIPmsiADHandler handler = new InterASIPmsiADHandler();
+
+
+    @Test
+    public void testInterASIPmsiADParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(INTER_AS)));
+    }
+
+    @Test
+    public void testInterASIPmsiADSerializer() {
+        final ByteBuf buff = Unpooled.buffer(INTER_AS_TYPE_LENGTH.length);
+        assertArrayEquals(INTER_AS_TYPE_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buff)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.InterAsIPmsiAD.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(InterAsIPmsiADCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/IntraAsIPmsiADHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/IntraAsIPmsiADHandlerTest.java
new file mode 100644 (file)
index 0000000..bc174c1
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.intra.as.i.pmsi.a.d.grouping.IntraAsIPmsiADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.IntraAsIPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.IntraAsIPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public class IntraAsIPmsiADHandlerTest {
+    private static final byte[] INTRA_AS = new byte[]{
+        0, 1, 1, 2, 3, 4, 1, 2,
+        1, 0, 0, 1
+    };
+    private static final byte[] INTRA_AS_TYPE_LENGTH = new byte[]{
+        1, 12,
+        0, 1, 1, 2, 3, 4, 1, 2,
+        1, 0, 0, 1
+    };
+
+    private final IntraAsIPmsiADCase expected = new IntraAsIPmsiADCaseBuilder()
+            .setIntraAsIPmsiAD(new IntraAsIPmsiADBuilder()
+                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                    .setOrigRouteIp(new IpAddress(new Ipv4Address("1.0.0.1")))
+                    .build()).build();
+    private IntraAsIPmsiADHandler handler = new IntraAsIPmsiADHandler();
+
+    @Test
+    public void testIntraASIPmsiADParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(INTRA_AS)));
+    }
+
+    @Test
+    public void testIntraASIPmsiADSerializer() {
+        final ByteBuf buff = Unpooled.buffer(INTRA_AS_TYPE_LENGTH.length);
+        assertArrayEquals(INTRA_AS_TYPE_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buff)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.IntraAsIPmsiAD.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(IntraAsIPmsiADCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/LeafADHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/LeafADHandlerTest.java
new file mode 100644 (file)
index 0000000..e08d614
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.mvpn.impl.NlriActivator;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.inter.as.i.pmsi.a.d.grouping.InterAsIPmsiADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.LeafADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.leaf.a.d.grouping.leaf.a.d.leaf.a.d.route.key.InterAsIPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.LeafADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.LeafADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public class LeafADHandlerTest {
+    private static final byte[] LEAF_AD = new byte[]{
+        2, 12,
+        0, 1,
+        1, 2, 3, 4, 1, 2,
+        0, 0, 0, 1,
+        1, 0, 0, 1,
+    };
+    private static final byte[] LEAF_AD_LENGTH = new byte[]{
+        4, 18,
+        2, 12,
+        0, 1,
+        1, 2, 3, 4, 1, 2,
+        0, 0, 0, 1,
+        1, 0, 0, 1,
+    };
+
+    private final LeafADCase expected = new LeafADCaseBuilder().setLeafAD(new LeafADBuilder()
+            .setLeafADRouteKey(
+                    new InterAsIPmsiADCaseBuilder().setInterAsIPmsiAD(
+                            new InterAsIPmsiADBuilder()
+                                    .setSourceAs(new AsNumber(1L))
+                                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                                    .build()
+                    ).build())
+            .setOrigRouteIp(new IpAddress(new Ipv4Address("1.0.0.1"))).build())
+            .build();
+    private LeafADHandler handler = new LeafADHandler();
+
+    @Before
+    public void setUp() {
+        NlriActivator.registerNlriParsers(new ArrayList<>());
+    }
+
+    @Test
+    public void testParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(LEAF_AD)));
+    }
+
+    @Test
+    public void testSerializer() {
+        final ByteBuf buffer = Unpooled.buffer(LEAF_AD_LENGTH.length);
+        assertArrayEquals(LEAF_AD_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buffer)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.LeafAD.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(LeafADCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SPmsiADHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SPmsiADHandlerTest.java
new file mode 100644 (file)
index 0000000..b4594d9
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.CGAddressCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.c.g.address._case.CGAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SPmsiADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SPmsiADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.s.pmsi.a.d.grouping.SPmsiADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public final class SPmsiADHandlerTest {
+    private static final byte[] SP_MSI_AD = new byte[]{
+        0, 1, 1, 2, 3, 4, 1, 2,
+        32, 10, 0, 0, 10,
+        32, 12, 0, 0, 12,
+        1, 0, 0, 1
+    };
+    private static final byte[] SP_MSI_AD_LENGTH = new byte[]{
+        3, 22,
+        0, 1, 1, 2, 3, 4, 1, 2,
+        32, 10, 0, 0, 10,
+        32, 12, 0, 0, 12,
+        1, 0, 0, 1
+    };
+
+    private final SPmsiADCase expected = new SPmsiADCaseBuilder()
+            .setSPmsiAD(new SPmsiADBuilder()
+                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                    .setMulticastSource(new IpAddress(new Ipv4Address("10.0.0.10")))
+                    .setMulticastGroup(new CGAddressCaseBuilder().setCGAddress(new CGAddressBuilder()
+                            .setCGAddress(new IpAddress(new Ipv4Address("12.0.0.12"))).build()).build())
+                    .setOrigRouteIp(new IpAddress(new Ipv4Address("1.0.0.1")))
+                    .build()).build();
+    private SPmsiADHandler handler = new SPmsiADHandler();
+
+    @Test
+    public void testIntraASIPmsiADParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(SP_MSI_AD)));
+    }
+
+    @Test
+    public void testIntraASIPmsiADSerializer() {
+        final ByteBuf buffer = Unpooled.buffer(SP_MSI_AD_LENGTH.length);
+        assertArrayEquals(SP_MSI_AD_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buffer)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.SPmsiAD.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(SPmsiADCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SharedTreeJoinHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SharedTreeJoinHandlerTest.java
new file mode 100644 (file)
index 0000000..98e802c
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.c.multicast.grouping.CMulticastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.CGAddressCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.c.g.address._case.CGAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SharedTreeJoinCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SharedTreeJoinCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public final class SharedTreeJoinHandlerTest {
+    private static final byte[] SHARED_TREE = new byte[]{
+        0, 1, 1, 2, 3, 4, 1, 2,
+        0, 0, 0, 10,
+        32, 1, 0, 0, 1,
+        32, 2, 0, 0, 2,
+    };
+    private static final byte[] SHARED_TREE_LENGTH = new byte[]{
+        6, 22,
+        0, 1, 1, 2, 3, 4, 1, 2,
+        0, 0, 0, 10,
+        32, 1, 0, 0, 1,
+        32, 2, 0, 0, 2,
+    };
+
+    private final SharedTreeJoinCase expected = new SharedTreeJoinCaseBuilder()
+            .setCMulticast(new CMulticastBuilder()
+                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                    .setSourceAs(new AsNumber(10L))
+                    .setMulticastSource(new IpAddress(new Ipv4Address("1.0.0.1")))
+                    .setMulticastGroup(new CGAddressCaseBuilder().setCGAddress(
+                            new CGAddressBuilder().setCGAddress(new IpAddress(new Ipv4Address("2.0.0.2")))
+                                    .build()).build()).build()).build();
+    private SharedTreeJoinHandler handler = new SharedTreeJoinHandler();
+
+    @Test
+    public void testParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(SHARED_TREE)));
+    }
+
+    @Test
+    public void testSerializer() {
+        final ByteBuf buffer = Unpooled.buffer(SHARED_TREE_LENGTH.length);
+        assertArrayEquals(SHARED_TREE_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buffer)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.SharedTreeJoin.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(SharedTreeJoinCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceActiveADHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceActiveADHandlerTest.java
new file mode 100644 (file)
index 0000000..21c7746
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceActiveADCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceActiveADCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.source.active.a.d.grouping.SourceActiveADBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public final class SourceActiveADHandlerTest {
+    private static final byte[] SOURCE_ACTIVE = new byte[]{
+        0, 1, 1, 2, 3, 4, 1, 2,
+        32, 1, 0, 0, 1,
+        32, 2, 0, 0, 2,
+    };
+    private static final byte[] SOURCE_ACTIVE_LENGTH = new byte[]{
+        5, 18,
+        0, 1, 1, 2, 3, 4, 1, 2,
+        32, 1, 0, 0, 1,
+        32, 2, 0, 0, 2,
+    };
+
+    private final SourceActiveADCase expected = new SourceActiveADCaseBuilder()
+            .setSourceActiveAD(new SourceActiveADBuilder()
+                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                    .setMulticastSource(new IpAddress(new Ipv4Address("1.0.0.1")))
+                    .setMulticastGroup(new IpAddress(new Ipv4Address("2.0.0.2")))
+                    .build())
+            .build();
+    private SourceActiveADHandler handler = new SourceActiveADHandler();
+
+    @Test
+    public void testParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(SOURCE_ACTIVE)));
+    }
+
+    @Test
+    public void testSerializer() {
+        final ByteBuf buff = Unpooled.buffer(SOURCE_ACTIVE_LENGTH.length);
+        assertArrayEquals(SOURCE_ACTIVE_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buff)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.SourceActiveAD.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(SourceActiveADCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
diff --git a/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceTreeJoinHandlerTest.java b/bgp/mvpn/src/test/java/org/opendaylight/protocol/bgp/mvpn/impl/nlri/SourceTreeJoinHandlerTest.java
new file mode 100644 (file)
index 0000000..99f3440
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.mvpn.impl.nlri;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.c.multicast.grouping.CMulticastBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.CGAddressCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.multicast.group.opaque.grouping.multicast.group.c.g.address._case.CGAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceTreeJoinCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mvpn.rev180417.mvpn.mvpn.choice.SourceTreeJoinCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+
+public final class SourceTreeJoinHandlerTest {
+    private static final byte[] SHARED_TREE = new byte[]{
+        0, 1, 1, 2, 3, 4, 1, 2,
+        0, 0, 0, 10,
+        32, 1, 0, 0, 1,
+        32, 2, 0, 0, 2,
+    };
+    private static final byte[] SHARED_TREE_LENGTH = new byte[]{
+        7, 22,
+        0, 1, 1, 2, 3, 4, 1, 2,
+        0, 0, 0, 10,
+        32, 1, 0, 0, 1,
+        32, 2, 0, 0, 2,
+    };
+
+    private final SourceTreeJoinCase expected = new SourceTreeJoinCaseBuilder()
+            .setCMulticast(new CMulticastBuilder()
+                    .setRouteDistinguisher(new RouteDistinguisher(new RdIpv4("1.2.3.4:258")))
+                    .setSourceAs(new AsNumber(10L))
+                    .setMulticastSource(new IpAddress(new Ipv4Address("1.0.0.1")))
+                    .setMulticastGroup(new CGAddressCaseBuilder().setCGAddress(
+                            new CGAddressBuilder().setCGAddress(new IpAddress(new Ipv4Address("2.0.0.2")))
+                                    .build()).build()).build()).build();
+    private final SourceTreeJoinHandler handler = new SourceTreeJoinHandler();
+
+    @Test
+    public void testParser() {
+        assertEquals(this.expected, this.handler.parseMvpn(Unpooled.copiedBuffer(SHARED_TREE)));
+    }
+
+    @Test
+    public void testSerializer() {
+        final ByteBuf buffer = Unpooled.buffer(SHARED_TREE_LENGTH.length);
+        assertArrayEquals(SHARED_TREE_LENGTH, ByteArray.getAllBytes(this.handler.serializeMvpn(this.expected, buffer)));
+    }
+
+    @Test
+    public void testGetType() {
+        assertEquals(NlriType.SourceTreeJoin.getIntValue(), this.handler.getType());
+    }
+
+    @Test
+    public void testGetClazz() {
+        assertEquals(SourceTreeJoinCase.class, this.handler.getClazz());
+    }
+}
\ No newline at end of file
index 5b6dd246830da11188614342c38dfacc88a90c07..9581754438fdc4df23b566d6f229dda1fb4aaebc 100644 (file)
@@ -8,10 +8,15 @@
 package org.opendaylight.protocol.bgp.parser;
 
 import java.util.List;
+import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Open;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.open.message.BgpParameters;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.open.message.bgp.parameters.OptionalCapabilities;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 
 public final class AsNumberUtil {
 
@@ -25,6 +30,7 @@ public final class AsNumberUtil {
      * @param open remote BGP open message
      * @return AsNumber
      */
+    @Nonnull
     public static AsNumber advertizedAsNumber(final Open open) {
         // Look for AS4 capability very defensively
         final List<BgpParameters> params = open.getBgpParameters();
@@ -40,4 +46,19 @@ public final class AsNumberUtil {
         // Fallback to whatever is in the header
         return new AsNumber(open.getMyAsNumber().longValue());
     }
+
+    /**
+     * Extract AS from Container Node.
+     *
+     * @param dtc route container
+     * @param nid as node identifier
+     * @return as number
+     */
+    public static AsNumber extractAS(final DataContainerNode<?> dtc, final NodeIdentifier nid) {
+        final NormalizedNode<?, ?> as = NormalizedNodes.findNode(dtc, nid).orElse(null);
+        if (as != null) {
+            return new AsNumber((Long) as.getValue());
+        }
+        return null;
+    }
 }