BUG-3778: Next Hop needs to be specified in each extension 27/28427/14
authorClaudio D. Gasparini <cgaspari@cisco.com>
Tue, 13 Oct 2015 14:34:04 +0000 (16:34 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 23 Oct 2015 21:21:53 +0000 (21:21 +0000)
Since each NextHop need to be specified for each extension,
we need to enforce users to register his corresponding handlers.
Thus a new registerNlriParser method is created with NexHop
handler and NextHop classes which are handled, as a new parameters.
Previous registerNlriParser method is deprecated.

Change-Id: I7aca6dbc679bf146e9333e7f2d2c9affb75808e8
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
16 files changed:
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/BGPActivator.java
bgp/labeled-unicast/pom.xml
bgp/labeled-unicast/src/main/java/org/opendaylight/protocol/bgp/labeled/unicast/BGPActivator.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/BGPActivator.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/next/hop/LinkstateNextHopParser.java [new file with mode: 0644]
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateRIBSupportTest.java
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/attribute/next/hop/LinkstateNextHopParserTest.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/BGPActivator.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/Ipv4NextHopParserSerializer.java [new file with mode: 0644]
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/Ipv6NextHopParserSerializer.java [new file with mode: 0644]
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/NextHopParserSerializerTest.java [new file with mode: 0644]
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/BGPExtensionProviderContext.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/NextHopParserSerializer.java [new file with mode: 0644]
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleBGPExtensionProviderContext.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleNlriRegistry.java
bgp/parser-spi/src/test/java/org/opendaylight/protocol/bgp/parser/spi/pojo/BgpTestActivator.java

index dc89b09be1f2af5c6f176dd80ed457bc49f979f9..0ac8111cc7048a2a6e83642453d7d299c96ce8e9 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.protocol.bgp.flowspec;
 import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.ExtendedCommunitiesAttributeParser;
+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;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecSubsequentAddressFamily;
@@ -18,6 +20,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.message.rev130919.path.attributes.attributes.ExtendedCommunities;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
 
 public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
@@ -31,8 +35,12 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
         final FSIpv4NlriParser ipv4Handler = new FSIpv4NlriParser();
         final FSIpv6NlriParser ipv6Handler = new FSIpv6NlriParser();
-        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class, ipv4Handler));
-        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class, ipv6Handler));
+        Ipv4NextHopParserSerializer ipv4NextHopParser = new Ipv4NextHopParserSerializer();
+        Ipv6NextHopParserSerializer ipv6NextHopParser = new Ipv6NextHopParserSerializer();
+        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class,
+            ipv4Handler, ipv4NextHopParser, Ipv4NextHopCase.class));
+        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class,
+            ipv6Handler, ipv6NextHopParser, Ipv6NextHopCase.class));
         regs.add(context.registerNlriSerializer(FlowspecRoutes.class, ipv4Handler));
         regs.add(context.registerNlriSerializer(FlowspecIpv6Routes.class, ipv6Handler));
 
index 1b9bda0f6f0733b67ed7b3d15c4752739ec02a77..1d82b77e3a22e3004e00447f8e1f6d6d196ff7b5 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-parser-spi</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-parser-impl</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-rib-api</artifactId>
index fbfa739b85e906f2182eb53c71a272e2f7558478..19ffd894d187f7a7dcf3508dba9dd41ef5dfabac 100644 (file)
@@ -9,12 +9,16 @@ package org.opendaylight.protocol.bgp.labeled.unicast;
 
 import java.util.ArrayList;
 import java.util.List;
+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;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.LabeledUnicastSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.routes.LabeledUnicastRoutes;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
 
 public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
@@ -27,8 +31,12 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
         regs.add(context.registerSubsequentAddressFamily(LabeledUnicastSubsequentAddressFamily.class, LABELED_UNICAST_SAFI));
 
-        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class, luNlriParser));
-        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class, luNlriParser));
+        Ipv4NextHopParserSerializer ipv4NextHopParser = new Ipv4NextHopParserSerializer();
+        Ipv6NextHopParserSerializer ipv6NextHopParser = new Ipv6NextHopParserSerializer();
+        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class,
+            luNlriParser, ipv4NextHopParser, Ipv4NextHopCase.class));
+        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class,
+            luNlriParser, ipv6NextHopParser, Ipv6NextHopCase.class));
 
         regs.add(context.registerNlriSerializer(LabeledUnicastRoutes.class, luNlriParser));
 
index 6b9c17ae9f918efc02308f3aa0b9ef6df9dd7511..9c25bb7af9b984134766b75f600e1094c27362af 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.protocol.bgp.linkstate;
 import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.protocol.bgp.linkstate.attribute.LinkstateAttributeParser;
+import org.opendaylight.protocol.bgp.linkstate.attribute.next.hop.LinkstateNextHopParser;
 import org.opendaylight.protocol.bgp.linkstate.nlri.LinkstateNlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.AbstractBGPExtensionProviderActivator;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
@@ -19,6 +20,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.routes.LinkstateRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
 
 /**
  * Activator for registering linkstate extensions to BGP parser.
@@ -52,10 +55,12 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerAddressFamily(LinkstateAddressFamily.class, LINKSTATE_AFI));
         regs.add(context.registerSubsequentAddressFamily(LinkstateSubsequentAddressFamily.class, LINKSTATE_SAFI));
 
+        LinkstateNextHopParser linkstateNextHopParser = new LinkstateNextHopParser();
         regs.add(context.registerNlriParser(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class,
-                new LinkstateNlriParser(false)));
+            new LinkstateNlriParser(false), linkstateNextHopParser, Ipv4NextHopCase.class, Ipv6NextHopCase.class));
+
         regs.add(context.registerNlriParser(LinkstateAddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class,
-                new LinkstateNlriParser(true)));
+            new LinkstateNlriParser(true), linkstateNextHopParser, Ipv4NextHopCase.class, Ipv6NextHopCase.class));
         regs.add(context.registerNlriSerializer(LinkstateRoutes.class, new LinkstateNlriParser(false)));
 
         regs.add(context.registerAttributeSerializer(Attributes1.class, new LinkstateAttributeParser(this.ianaLinkstateAttributeType, this.rsvpTeObjectRegistry)));
diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/next/hop/LinkstateNextHopParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/next/hop/LinkstateNextHopParser.java
new file mode 100644 (file)
index 0000000..d33d1fa
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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.linkstate.attribute.next.hop;
+
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.bgp.concepts.NextHopUtil;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+
+public class LinkstateNextHopParser implements NextHopParserSerializer {
+    @Override
+    public CNextHop parseNextHop(final ByteBuf buffer) throws BGPParsingException {
+        return NextHopUtil.parseNextHop(buffer);
+    }
+
+    @Override
+    public void serializeNextHop(final CNextHop cNextHop, final ByteBuf byteAggregator) {
+        NextHopUtil.serializeNextHop(cNextHop, byteAggregator);
+    }
+}
\ No newline at end of file
index bf0b4102d7ee588014edda3d6ea61205fe990c56..371d7276ecb2ca59b2899d6af8318b4dfd85b8f0 100644 (file)
@@ -53,9 +53,6 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLe
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
 
-/**
- * Created by cgasparini on 17.6.2015.
- */
 public class LinkstateRIBSupportTest {
 
     private static final Ipv4Address ipv4 = new Ipv4Address("42.42.42.42");
diff --git a/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/attribute/next/hop/LinkstateNextHopParserTest.java b/bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/attribute/next/hop/LinkstateNextHopParserTest.java
new file mode 100644 (file)
index 0000000..8c4b7ce
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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.linkstate.attribute.next.hop;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv6.next.hop._case.Ipv6NextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv6.next.hop._case.Ipv6NextHopBuilder;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+public class LinkstateNextHopParserTest {
+
+    public static final byte[] ipv6B = {0x20, 1, 0x0d, (byte) 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
+    public static final byte[] ipv6lB = {0x20, 1, 0x0d, (byte) 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, (byte) 0xfe, (byte) 0x80, 0, 0, 0, 0, 0, 0, (byte) 0xc0, 1, 0x0b, (byte) 0xff, (byte) 0xfe, 0x7e, 0, 0};
+
+    public static final Ipv6Address ipv6 = new Ipv6Address("2001:db8::1");
+    public static final Ipv6Address ipv6l = new Ipv6Address("fe80::c001:bff:fe7e:0");
+
+    LinkstateNextHopParser linkstateNextHopParser;
+    CNextHop hop;
+    ByteBuf buffer;
+
+    @Before
+    public final void setUp() {
+        linkstateNextHopParser = new LinkstateNextHopParser();
+        buffer = Unpooled.buffer();
+    }
+
+    @Test
+    public void testSerializeIpv4NextHopCase() throws BGPParsingException {
+        final byte[] ipv4B = {42, 42, 42, 42};
+        hop = new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder()
+            .setGlobal(new Ipv4Address("42.42.42.42")).build()).build();
+
+        linkstateNextHopParser.serializeNextHop(hop, buffer);
+        assertArrayEquals(ipv4B, ByteArray.readAllBytes(buffer));
+
+        final CNextHop parsedHop = linkstateNextHopParser.parseNextHop(Unpooled.wrappedBuffer(ipv4B));
+        assertTrue(parsedHop instanceof Ipv4NextHopCase);
+        assertEquals(hop, parsedHop);
+    }
+
+    @Test
+    public void testSerializeIpv6NextHopCase() throws BGPParsingException {
+        hop = new Ipv6NextHopCaseBuilder().setIpv6NextHop(new Ipv6NextHopBuilder().setGlobal(ipv6).setLinkLocal(ipv6l).build()).build();
+        buffer.clear();
+        linkstateNextHopParser.serializeNextHop(hop, buffer);
+        assertArrayEquals(ipv6lB, ByteArray.readAllBytes(buffer));
+
+        final CNextHop parsedHop = linkstateNextHopParser.parseNextHop(Unpooled.wrappedBuffer(ipv6B));
+        assertTrue(parsedHop instanceof Ipv6NextHopCase);
+        final Ipv6NextHop nextHopIpv6 = ((Ipv6NextHopCase) parsedHop).getIpv6NextHop();
+        assertEquals(ipv6, nextHopIpv6.getGlobal());
+        assertNull(nextHopIpv6.getLinkLocal());
+    }
+
+    @Test
+    public void testSerializeNextHopEmpty() {
+        buffer.clear();
+        try {
+            linkstateNextHopParser.serializeNextHop(new CNextHop() {
+                @Override
+                public Class<? extends DataContainer> getImplementedInterface() {
+                    return null;
+                }
+            }, buffer);
+        } catch (final IllegalArgumentException e) {
+            assertEquals("cNextHop is not a Linkstate Ipv6 NextHop object.", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testSerializeNextHopGlobalAddressEmpty() {
+        hop = new Ipv6NextHopCaseBuilder().setIpv6NextHop(new Ipv6NextHopBuilder().setLinkLocal(ipv6l).build()).build();
+        buffer.clear();
+        try {
+            linkstateNextHopParser.serializeNextHop(hop, buffer);
+            fail("Exception should happen");
+        } catch (final IllegalArgumentException e) {
+            assertEquals("Ipv6 Next Hop is missing Global address.", e.getMessage());
+        }
+    }
+}
\ No newline at end of file
index ffea424047f9911fb6a88b5b952fcc7dbe673c91..0d84ca2644e828c699da6a7c8e1ee0f88f408170 100644 (file)
@@ -37,6 +37,8 @@ import org.opendaylight.protocol.bgp.parser.impl.message.update.NextHopAttribute
 import org.opendaylight.protocol.bgp.parser.impl.message.update.OriginAttributeParser;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.OriginatorIdAttributeParser;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.WithdrawnRoutesSerializer;
+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;
 import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
@@ -70,6 +72,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.NextHop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
 
 public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
@@ -92,8 +96,13 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerSubsequentAddressFamily(UnicastSubsequentAddressFamily.class, UNICAST_SAFI));
         regs.add(context.registerSubsequentAddressFamily(MplsLabeledVpnSubsequentAddressFamily.class, VPN_SAFI));
 
-        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv4NlriParser()));
-        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv6NlriParser()));
+        Ipv4NextHopParserSerializer ipv4NextHopParser = new Ipv4NextHopParserSerializer();
+        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class,
+            new Ipv4NlriParser(), ipv4NextHopParser, Ipv4NextHopCase.class));
+
+        Ipv6NextHopParserSerializer ipv6NextHopParser = new Ipv6NextHopParserSerializer();
+        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, new
+            Ipv6NlriParser(), ipv6NextHopParser, Ipv6NextHopCase.class));
 
         this.registerCapabilityParsers(regs, context);
         this.registerAttributeParsers(regs, context);
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/Ipv4NextHopParserSerializer.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/Ipv4NextHopParserSerializer.java
new file mode 100644 (file)
index 0000000..7598dc6
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.parser.impl.message.update.next.hop;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.bgp.concepts.NextHopUtil;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
+import org.opendaylight.protocol.util.Ipv4Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+
+final public class Ipv4NextHopParserSerializer implements NextHopParserSerializer {
+    @Override
+    public CNextHop parseNextHop(final ByteBuf buffer) throws BGPParsingException {
+        Preconditions.checkArgument(buffer.readableBytes() == Ipv4Util.IP4_LENGTH, "Length of byte array for NEXT_HOP should be %s, but is %s", buffer.readableBytes(), Ipv4Util.IP4_LENGTH);
+        return NextHopUtil.parseNextHop(buffer);
+    }
+
+    @Override
+    public void serializeNextHop(final CNextHop cNextHop, final ByteBuf byteAggregator) {
+        Preconditions.checkArgument(cNextHop instanceof Ipv4NextHopCase, "cNextHop is not a Ipv4 NextHop object.");
+        NextHopUtil.serializeNextHop( cNextHop, byteAggregator);
+    }
+}
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/Ipv6NextHopParserSerializer.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/Ipv6NextHopParserSerializer.java
new file mode 100644 (file)
index 0000000..7d8ced5
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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.parser.impl.message.update.next.hop;
+
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.bgp.concepts.NextHopUtil;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+
+final public class Ipv6NextHopParserSerializer implements NextHopParserSerializer {
+    @Override
+    public CNextHop parseNextHop(final ByteBuf buffer) throws BGPParsingException {
+        return NextHopUtil.parseNextHop(buffer);
+
+    }
+
+    @Override
+    public void serializeNextHop(final CNextHop cNextHop, final ByteBuf byteAggregator) {
+        Preconditions.checkArgument(cNextHop instanceof Ipv6NextHopCase, "cNextHop is not a Ipv6 NextHop object.");
+        NextHopUtil.serializeNextHop(cNextHop,byteAggregator);
+    }
+}
diff --git a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/NextHopParserSerializerTest.java b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/message/update/next/hop/NextHopParserSerializerTest.java
new file mode 100644 (file)
index 0000000..8474a11
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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.parser.impl.message.update.next.hop;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv6.next.hop._case.Ipv6NextHopBuilder;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+public class NextHopParserSerializerTest {
+
+    public static final byte[] ipv6lB = {0x20, 1, 0x0d, (byte) 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, (byte) 0xfe, (byte) 0x80, 0, 0, 0, 0, 0, 0, (byte) 0xc0, 1, 0x0b, (byte) 0xff, (byte) 0xfe, 0x7e, 0, 0};
+
+    public static final Ipv6Address ipv6 = new Ipv6Address("2001:db8::1");
+    public static final Ipv6Address ipv6l = new Ipv6Address("fe80::c001:bff:fe7e:0");
+
+    Ipv4NextHopParserSerializer ipv4NextHopParserSerializer;
+    Ipv6NextHopParserSerializer ipv6NextHopParserSerializer;
+    CNextHop hop;
+    ByteBuf buffer;
+
+    @Before
+    public final void setUp() {
+        ipv4NextHopParserSerializer = new Ipv4NextHopParserSerializer();
+        ipv6NextHopParserSerializer = new Ipv6NextHopParserSerializer();
+        buffer = Unpooled.buffer();
+    }
+
+    @Test
+    public void testSerializeIpv4NextHopCase() throws BGPParsingException {
+        final byte[] ipv4B = {42, 42, 42, 42};
+        hop = new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder()
+            .setGlobal(new Ipv4Address("42.42.42.42")).build()).build();
+
+        ipv4NextHopParserSerializer.serializeNextHop(hop, buffer);
+        assertArrayEquals(ipv4B, ByteArray.readAllBytes(buffer));
+
+        final CNextHop parsedHop = ipv4NextHopParserSerializer.parseNextHop(Unpooled.wrappedBuffer(ipv4B));
+        assertTrue(hop instanceof Ipv4NextHopCase);
+        assertEquals(hop, parsedHop);
+    }
+
+    @Test
+    public void testSerializeIpv6LinkNextHopCase() throws BGPParsingException {
+        hop = new Ipv6NextHopCaseBuilder().setIpv6NextHop(new Ipv6NextHopBuilder().setGlobal(ipv6).setLinkLocal(ipv6l).build()).build();
+        buffer.clear();
+        ipv6NextHopParserSerializer.serializeNextHop(hop, buffer);
+        assertArrayEquals(ipv6lB, ByteArray.readAllBytes(buffer));
+
+        final CNextHop parsedHop = ipv6NextHopParserSerializer.parseNextHop(Unpooled.wrappedBuffer(ipv6lB));
+        assertTrue(parsedHop instanceof Ipv6NextHopCase);
+        assertEquals(hop, parsedHop);
+    }
+
+    @Test
+    public void testSerializeIpv4NextHopEmpty() {
+        buffer.clear();
+        try {
+            ipv4NextHopParserSerializer.serializeNextHop(new CNextHop() {
+                @Override
+                public Class<? extends DataContainer> getImplementedInterface() {
+                    return null;
+                }
+            }, buffer);
+        } catch (final IllegalArgumentException e) {
+            assertEquals("cNextHop is not a Ipv4 NextHop object.", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testSerializeIpv6NextHopEmpty() {
+        buffer.clear();
+        try {
+            ipv6NextHopParserSerializer.serializeNextHop(new CNextHop() {
+                @Override
+                public Class<? extends DataContainer> getImplementedInterface() {
+                    return null;
+                }
+            }, buffer);
+        } catch (final IllegalArgumentException e) {
+            assertEquals("cNextHop is not a Ipv6 NextHop object.", e.getMessage());
+        }
+    }
+}
\ No newline at end of file
index 5ea65cba6222dd750c903d0bf33d445db3ec4884..19e137c375b89773cc93b98a6c40f956e7c6f286 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.protocol.util.ReferenceCache;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
@@ -36,8 +37,17 @@ public interface BGPExtensionProviderContext extends BGPExtensionConsumerContext
 
     AutoCloseable registerMessageSerializer(Class<? extends Notification> messageClass, MessageSerializer serializer);
 
+    /**
+     * Each extension requires a specific NextHop handler. Therefore this method has been deprecated  for
+     * the method which enforce user to register it.
+     */
+    @Deprecated
     AutoCloseable registerNlriParser(Class<? extends AddressFamily> afi, Class<? extends SubsequentAddressFamily> safi, NlriParser parser);
 
+    AutoCloseable registerNlriParser(Class<? extends AddressFamily> afi, Class<? extends SubsequentAddressFamily>
+        safi, NlriParser parser, final NextHopParserSerializer nextHopHandler, final Class<? extends CNextHop> cNextHopClass,
+                                     final Class<? extends CNextHop>... cNextHopClassList);
+
     AutoCloseable registerNlriSerializer(Class<? extends DataObject> nlriClass, NlriSerializer serializer);
 
     AutoCloseable registerParameterParser(int parameterType, ParameterParser parser);
diff --git a/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/NextHopParserSerializer.java b/bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/NextHopParserSerializer.java
new file mode 100644 (file)
index 0000000..0cd648b
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * 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.parser.spi;
+
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+
+public interface NextHopParserSerializer {
+    CNextHop parseNextHop(ByteBuf buffer) throws BGPParsingException;
+
+    void serializeNextHop(CNextHop cNextHop, final ByteBuf byteAggregator);
+}
index aedaa78d2b00b7bdf269c4e8e99cdee8155b645a..c973b14c8626aa3779f7266a5aa52af05eba7a9f 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.protocol.bgp.parser.spi.CapabilityParser;
 import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
 import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
@@ -26,6 +27,7 @@ import org.opendaylight.protocol.util.ReferenceCache;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
@@ -97,15 +99,26 @@ public class SimpleBGPExtensionProviderContext extends SimpleBGPExtensionConsume
         return this.getMessageRegistry().registerMessageSerializer(messageClass, serializer);
     }
 
+    /**
+     * Each extension requires a specific NextHop handler. Therefore this method has been deprecated  for
+     * the method which enforce user to register it.
+     */
+    @Deprecated
+    @Override
+    public AutoCloseable registerNlriParser(Class<? extends AddressFamily> afi, Class<? extends SubsequentAddressFamily> safi, NlriParser parser) {
+        return this.getNlriRegistry().registerNlriParser(afi, safi, parser, null, null);
+    }
+
     @Override
     public AutoCloseable registerNlriParser(final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi,
-            final NlriParser parser) {
-        return this.getNlriRegistry().registerNlriParser(afi, safi, parser);
+            final NlriParser parser, final NextHopParserSerializer nextHopParserSerializer, final Class<? extends
+        CNextHop> cNextHopClass, final Class<? extends CNextHop>... cNextHopClassList) {
+        return this.getNlriRegistry().registerNlriParser(afi, safi, parser, nextHopParserSerializer, cNextHopClass);
     }
 
     @Override
     public AutoCloseable registerNlriSerializer(final Class<? extends DataObject> nlriClass, final NlriSerializer serializer) {
-        return this.getNlriRegistry().registerNlriSerializer(nlriClass,serializer);
+        return this.getNlriRegistry().registerNlriSerializer(nlriClass, serializer);
     }
 
     @Override
index 9249c3aa2f8bde8cb2e2fdd20a5c645192775817..bb7e046ca48b180da8a74b267091c6c42af0c283 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.bgp.concepts.NextHopUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
 import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
@@ -29,15 +30,21 @@ 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.MpUnreachNlriBuilder;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 final class SimpleNlriRegistry implements NlriRegistry {
 
     private static final int RESERVED = 1;
     private static final int NEXT_HOP_LENGHT = 1;
+    private static final Logger LOG = LoggerFactory.getLogger(SimpleNlriRegistry.class);
 
     private final ConcurrentMap<BgpTableType, NlriParser> handlers = new ConcurrentHashMap<>();
     private final ConcurrentMap<Class<? extends DataObject>, NlriSerializer> serializers = new ConcurrentHashMap<>();
+    private final ConcurrentMap<BgpTableType, NextHopParserSerializer> nextHopParsers = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Class<? extends CNextHop>, NextHopParserSerializer> nextHopSerializers = new ConcurrentHashMap<>();
     private final SubsequentAddressFamilyRegistry safiReg;
     private final AddressFamilyRegistry afiReg;
 
@@ -53,11 +60,13 @@ final class SimpleNlriRegistry implements NlriRegistry {
         return new BgpTableTypeImpl(afi, safi);
     }
 
-    synchronized AutoCloseable registerNlriSerializer(final Class<? extends DataObject> nlriClass, final NlriSerializer serializer){
+    synchronized AutoCloseable registerNlriSerializer(final Class<? extends DataObject> nlriClass, final
+        NlriSerializer serializer){
         final NlriSerializer prev = this.serializers.get(nlriClass);
         Preconditions.checkState(prev == null, "Serializer already bound to class " + prev);
 
         this.serializers.put(nlriClass, serializer);
+
         final Object lock = this;
         return new AbstractRegistration() {
             @Override
@@ -70,18 +79,36 @@ final class SimpleNlriRegistry implements NlriRegistry {
     }
 
     synchronized AutoCloseable registerNlriParser(final Class<? extends AddressFamily> afi,
-            final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser) {
+                                                         final Class<? extends SubsequentAddressFamily> safi, final NlriParser parser,
+                                                         final NextHopParserSerializer nextHopSerializer, final Class<? extends CNextHop> cNextHopClass,
+                                                         final Class<? extends CNextHop>... cNextHopClassList) {
         final BgpTableType key = createKey(afi, safi);
         final NlriParser prev = this.handlers.get(key);
         Preconditions.checkState(prev == null, "AFI/SAFI is already bound to parser " + prev);
 
         this.handlers.put(key, parser);
+        this.nextHopParsers.put(key,nextHopSerializer);
+
+        if (cNextHopClass != null) {
+            this.nextHopSerializers.put(cNextHopClass, nextHopSerializer);
+            for (Class<? extends CNextHop> cNextHop : cNextHopClassList) {
+                this.nextHopSerializers.put(cNextHop, nextHopSerializer);
+            }
+        }
+
         final Object lock = this;
         return new AbstractRegistration() {
             @Override
             protected void removeRegistration() {
                 synchronized (lock) {
                     SimpleNlriRegistry.this.handlers.remove(key);
+                    SimpleNlriRegistry.this.nextHopParsers.remove(key);
+                    if (cNextHopClass != null) {
+                        SimpleNlriRegistry.this.nextHopSerializers.remove(cNextHopClass);
+                        for (Class<? extends CNextHop> cNextHop : cNextHopClassList) {
+                            SimpleNlriRegistry.this.nextHopSerializers.remove(cNextHop);
+                        }
+                    }
                 }
             }
         };
@@ -119,14 +146,25 @@ final class SimpleNlriRegistry implements NlriRegistry {
 
     @Override
     public void serializeMpReach(final MpReachNlri mpReachNlri, final ByteBuf byteAggregator) {
-        byteAggregator.writeShort(this.afiReg.numberForClass(mpReachNlri.getAfi()));
-        byteAggregator.writeByte(this.safiReg.numberForClass(mpReachNlri.getSafi()));
-
-        if (mpReachNlri.getCNextHop() != null) {
+        final Class<? extends AddressFamily> afi = mpReachNlri.getAfi();
+        final Class<? extends SubsequentAddressFamily> safi = mpReachNlri.getSafi();
+        byteAggregator.writeShort(this.afiReg.numberForClass(afi));
+        byteAggregator.writeByte(this.safiReg.numberForClass(safi));
+
+        final CNextHop cNextHop = mpReachNlri.getCNextHop();
+        if (cNextHop != null) {
+            final NextHopParserSerializer nextHopSerializer = this.nextHopSerializers.get(cNextHop.getImplementedInterface());
             final ByteBuf nextHopBuffer = Unpooled.buffer();
-            NextHopUtil.serializeNextHop(mpReachNlri.getCNextHop(), nextHopBuffer);
+            if (nextHopSerializer == null) {
+                //TODO Remove once deprecated registerNlriParser is removed
+                LOG.warn("NexHop Parser/Serializer for AFI/SAFI ({},{}) not bound", afi, safi);
+                NextHopUtil.serializeNextHop(cNextHop, nextHopBuffer);
+            } else {
+                nextHopSerializer.serializeNextHop(cNextHop, nextHopBuffer);
+            }
             byteAggregator.writeByte(nextHopBuffer.writerIndex());
             byteAggregator.writeBytes(nextHopBuffer);
+
         } else {
             byteAggregator.writeZero(NEXT_HOP_LENGHT);
         }
@@ -147,14 +185,23 @@ final class SimpleNlriRegistry implements NlriRegistry {
     @Override
     public MpReachNlri parseMpReach(final ByteBuf buffer) throws BGPParsingException {
         final MpReachNlriBuilder builder = new MpReachNlriBuilder();
-        builder.setAfi(getAfi(buffer));
-        builder.setSafi(getSafi(buffer));
+        final Class<? extends AddressFamily> afi = getAfi(buffer);
+        final Class<? extends SubsequentAddressFamily> safi = getSafi(buffer);
+        builder.setAfi(afi);
+        builder.setSafi(safi);
 
-        final NlriParser parser = this.handlers.get(createKey(builder.getAfi(), builder.getSafi()));
+        final BgpTableType key = createKey(builder.getAfi(), builder.getSafi());
+        final NlriParser parser = this.handlers.get(key);
 
         final int nextHopLength = buffer.readUnsignedByte();
         if (nextHopLength != 0) {
-            builder.setCNextHop(NextHopUtil.parseNextHop(buffer.readSlice(nextHopLength)));
+            final NextHopParserSerializer nextHopParser = this.nextHopParsers.get(key);
+            if (nextHopParser != null) {
+                builder.setCNextHop(nextHopParser.parseNextHop(buffer.readSlice(nextHopLength)));
+            } else {
+                builder.setCNextHop(NextHopUtil.parseNextHop(buffer.readSlice(nextHopLength)));
+                LOG.warn("NexHop Parser/Serializer for AFI/SAFI ({},{}) not bound",afi,safi);
+            }
         }
         buffer.skipBytes(RESERVED);
 
index a2241d99d97c4035bb438ab9c13c9fe956bb6486..b8009197b936cf9871b6ba4abf71152dcf9a7650 100644 (file)
@@ -25,10 +25,12 @@ import org.opendaylight.protocol.bgp.parser.spi.CapabilityParser;
 import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
 import org.opendaylight.protocol.bgp.parser.spi.MessageParser;
 import org.opendaylight.protocol.bgp.parser.spi.MessageSerializer;
+import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.ParameterParser;
 import org.opendaylight.protocol.bgp.parser.spi.ParameterSerializer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParameters;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
@@ -37,6 +39,11 @@ 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.types.rev130919.Ipv4AddressFamily;
 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.UnicastSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
@@ -70,6 +77,8 @@ public class BgpTestActivator extends AbstractBGPExtensionProviderActivator {
     @Mock
     protected NlriSerializer nlriSerializer;
 
+    protected NextHopParserSerializer nextHopParserSerializer;
+
     @Override
     protected List<AutoCloseable> startImpl(final BGPExtensionProviderContext context) {
         initMock();
@@ -90,8 +99,24 @@ public class BgpTestActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerAddressFamily(Ipv6AddressFamily.class, 2));
         regs.add(context.registerSubsequentAddressFamily(UnicastSubsequentAddressFamily.class, 1));
 
-        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, this.nlriParser));
-        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, this.nlriParser));
+        this.nextHopParserSerializer = new NextHopParserSerializer() {
+            @Override
+            public CNextHop parseNextHop(final ByteBuf buffer) throws BGPParsingException {
+                return new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(new Ipv4Address("127.0.0.1")).build()).build();
+            }
+            @Override
+            public void serializeNextHop(final CNextHop cNextHop, final ByteBuf byteAggregator) {
+                final byte[] mpReachBytes = {
+                    0x7f, 0x00, 0x00, 0x01
+                };
+                byteAggregator.writeBytes(mpReachBytes);
+            }
+        };
+
+        regs.add(context.registerNlriParser(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, this
+            .nlriParser, this.nextHopParserSerializer, Ipv4NextHopCase.class));
+        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, this
+            .nlriParser, this.nextHopParserSerializer, Ipv6NextHopCase.class));
         regs.add(context.registerNlriSerializer(DataObject.class, this.nlriSerializer));
 
         return regs;