Bug 611 - Update message serialization 01/7301/27
authorMartin Bobak <mbobak@cisco.com>
Tue, 20 May 2014 14:57:08 +0000 (16:57 +0200)
committerMartin Bobak <mbobak@cisco.com>
Fri, 20 Jun 2014 14:00:21 +0000 (16:00 +0200)
- multi protocol attributes serialization for update message

Change-Id: I710b87a67c9f19bd9ed9391dab32ed1522188a05
Signed-off-by: Martin Bobak <mbobak@cisco.com>
bgp/concepts/src/main/java/org/opendaylight/protocol/bgp/concepts/util/NextHopUtil.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/BGPUpdateMessageParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPReachAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/MPUnreachAttributeParser.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/BGPUpdateAttributesSerializationTest.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/NlriRegistry.java
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleNlriRegistry.java
concepts/src/main/java/org/opendaylight/protocol/concepts/Ipv4Util.java
concepts/src/main/java/org/opendaylight/protocol/concepts/Ipv6Util.java

diff --git a/bgp/concepts/src/main/java/org/opendaylight/protocol/bgp/concepts/util/NextHopUtil.java b/bgp/concepts/src/main/java/org/opendaylight/protocol/bgp/concepts/util/NextHopUtil.java
new file mode 100644 (file)
index 0000000..f26a04d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 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.concepts.util;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.concepts.Ipv6Util;
+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.Ipv6NextHopCase;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Utility class for of CNextHop attribute serialization.
+ */
+public class NextHopUtil {
+
+    private NextHopUtil() {
+    }
+
+    public static void serializeNextHop(DataObject attribute, ByteBuf byteAggregator) {
+        serializeNextHop((CNextHop) attribute, byteAggregator);
+    }
+
+    /**
+     * Writes serialized cnextHop attribute ip address as byte value into byteAggregator without serializing attributes
+     * length.
+     *
+     * @param cnextHop
+     * @param byteAggregator
+     */
+    public static void serializeNextHopSimple(CNextHop cnextHop, ByteBuf byteAggregator) {
+        if (cnextHop instanceof Ipv4NextHopCase) {
+            Ipv4NextHopCase nextHop = (Ipv4NextHopCase) cnextHop;
+            serializeIpv4NextHop(nextHop, byteAggregator);
+        } else if (cnextHop instanceof Ipv6NextHopCase) {
+            Ipv6NextHopCase nextHop = (Ipv6NextHopCase) cnextHop;
+            serializeIpv6NextHop(nextHop, byteAggregator);
+        }
+    }
+
+    /**
+     * Writes serialized cnextHop attribute ip address as byte value into byteAggregator with serializing attributes
+     * length.
+     *
+     * @param cnextHop
+     * @param byteAggregator
+     */
+    public static void serializeNextHop(CNextHop cnextHop, ByteBuf byteAggregator) {
+        ByteBuf nextHopBuffer = Unpooled.buffer();
+        serializeNextHopSimple(cnextHop, nextHopBuffer);
+        byteAggregator.writeByte(nextHopBuffer.writerIndex());
+        byteAggregator.writeBytes(nextHopBuffer);
+    }
+
+    /**
+     * Writes nextHopCase attributes ipv4 address as bytes to byteAggregator.
+     *
+     * @param nextHopCase
+     * @param byteAggregator
+     */
+    public static void serializeIpv4NextHop(Ipv4NextHopCase nextHopCase, ByteBuf byteAggregator) {
+        byteAggregator.writeBytes(Ipv4Util.bytesForAddress(nextHopCase.getIpv4NextHop().getGlobal()));
+    }
+
+    /**
+     * Writes nextHopCase attributes ipv6 address as bytes to byteAggregator.
+     *
+     * @param nextHopCase
+     * @param byteAggregator
+     */
+    public static void serializeIpv6NextHop(Ipv6NextHopCase nextHopCase, ByteBuf byteAggregator) {
+        if (nextHopCase.getIpv6NextHop().getGlobal() != null) {
+            byteAggregator.writeBytes(Ipv6Util.bytesForAddress(nextHopCase.getIpv6NextHop().getGlobal()));
+        }
+        if (nextHopCase.getIpv6NextHop().getLinkLocal() != null) {
+            byteAggregator.writeBytes(Ipv6Util.bytesForAddress(nextHopCase.getIpv6NextHop().getLinkLocal()));
+        }
+
+    }
+}
index 90f68664efd440321ae57c65a9075a4645283c0b..be8670e67e02a8d3163d202107adb2f0a720355c 100644 (file)
@@ -59,6 +59,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Origin;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.GracefulRestartCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.MultiprotocolCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
 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.MplsLabeledVpnSubsequentAddressFamily;
@@ -123,8 +125,13 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         final ClusterIdAttributeParser clusterIdAttributeParser = new ClusterIdAttributeParser();
         regs.add(context.registerAttributeParser(ClusterIdAttributeParser.TYPE, clusterIdAttributeParser));
 
-        regs.add(context.registerAttributeParser(MPReachAttributeParser.TYPE, new MPReachAttributeParser(nlriReg)));
-        regs.add(context.registerAttributeParser(MPUnreachAttributeParser.TYPE, new MPUnreachAttributeParser(nlriReg)));
+        MPReachAttributeParser mpReachAttributeParser  = new MPReachAttributeParser(nlriReg);
+        regs.add(context.registerAttributeSerializer(MpReachNlri.class,mpReachAttributeParser));
+        regs.add(context.registerAttributeParser(MPReachAttributeParser.TYPE, mpReachAttributeParser ));
+
+        MPUnreachAttributeParser mpUnreachAttributeParser = new MPUnreachAttributeParser(nlriReg);
+        regs.add(context.registerAttributeSerializer(MpUnreachNlri.class,mpUnreachAttributeParser));
+        regs.add(context.registerAttributeParser(MPUnreachAttributeParser.TYPE, mpUnreachAttributeParser));
 
         final ExtendedCommunitiesAttributeParser extendedCommunitiesAttributeParser = new ExtendedCommunitiesAttributeParser(context.getReferenceCache());
         regs.add(context.registerAttributeSerializer(ExtendedCommunities.class, extendedCommunitiesAttributeParser));
@@ -133,6 +140,7 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerAttributeParser(AS4AggregatorAttributeParser.TYPE, new AS4AggregatorAttributeParser()));
         regs.add(context.registerAttributeParser(AS4PathAttributeParser.TYPE, new AS4PathAttributeParser()));
 
+
         final CapabilityRegistry capReg = context.getCapabilityRegistry();
         final MultiProtocolCapabilityHandler multi = new MultiProtocolCapabilityHandler(afiReg, safiReg);
         regs.add(context.registerCapabilityParser(MultiProtocolCapabilityHandler.CODE, multi));
index ebdf468258c15d02e24229a5e993425d4f916690..c94a78962f2497dd4c493fc67fa511f1b22eea11 100644 (file)
@@ -151,6 +151,7 @@ public class BGPUpdateMessageParser implements MessageParser, MessageSerializer
                 messageBody.writeBytes(prefixBytes);
             }
         }
+
         LOG.trace("Update message serialized to {}", ByteBufUtil.hexDump(messageBody));
         //FIXME: switch to ByteBuf
         bytes.writeBytes(MessageUtil.formatMessage(TYPE, ByteArray.getAllBytes(messageBody)));
index 5407d602984bf5e3962d0c6d73d26874741e6ac6..eb22baf2a4fd6b1733eab020f602356d26daa10d 100644 (file)
@@ -8,24 +8,36 @@
 package org.opendaylight.protocol.bgp.parser.impl.message.update;
 
 import com.google.common.base.Preconditions;
-
 import io.netty.buffer.ByteBuf;
-
+import io.netty.buffer.Unpooled;
+import org.opendaylight.protocol.bgp.parser.AttributeFlags;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.concepts.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.destination.type.DestinationIpv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.destination.type.DestinationIpv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.reach.nlri.AdvertizedRoutes;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
-public final class MPReachAttributeParser implements AttributeParser,AttributeSerializer {
 
-    public static final int TYPE = 14;
+public final class MPReachAttributeParser implements AttributeParser, AttributeSerializer {
 
+    public static final int TYPE = 14;
+    public static final int ATTR_LENGTH = 2;
+    public static final int MAX_ATTR_LENGTH_FOR_SINGLE_BYTE = 127;
     private final NlriRegistry reg;
 
     public MPReachAttributeParser(final NlriRegistry reg) {
@@ -44,6 +56,44 @@ public final class MPReachAttributeParser implements AttributeParser,AttributeSe
 
     @Override
     public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
-        //FIXME: implement this
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        PathAttributes1 pathAttributes1 = pathAttributes.getAugmentation(PathAttributes1.class);
+        if (pathAttributes1 == null) {
+            return;
+        }
+        MpReachNlri mpReachNlri = pathAttributes1.getMpReachNlri();
+        ByteBuf reachBuffer = Unpooled.buffer();
+        this.reg.serializeMpReach(mpReachNlri, reachBuffer);
+
+        serializeAdvertizedRoutes(mpReachNlri.getAdvertizedRoutes(), reachBuffer);
+        if (reachBuffer.writerIndex() > MAX_ATTR_LENGTH_FOR_SINGLE_BYTE) {
+            byteAggregator.writeByte(AttributeFlags.OPTIONAL | AttributeFlags.EXTENDED);
+            byteAggregator.writeByte(TYPE);
+            byteAggregator.writeShort(reachBuffer.writerIndex());
+        } else {
+            byteAggregator.writeByte(AttributeFlags.OPTIONAL);
+            byteAggregator.writeByte(TYPE);
+            byteAggregator.writeByte(reachBuffer.writerIndex());
+        }
+        byteAggregator.writeBytes(reachBuffer);
+
+
+    }
+
+    private void serializeAdvertizedRoutes(AdvertizedRoutes advertizedRoutes, ByteBuf byteAggregator) {
+        DestinationType destinationType = advertizedRoutes.getDestinationType();
+        if (destinationType instanceof DestinationIpv4Case) {
+            DestinationIpv4Case destinationIpv4Case = (DestinationIpv4Case) destinationType;
+            for (Ipv4Prefix ipv4Prefix : destinationIpv4Case.getDestinationIpv4().getIpv4Prefixes()) {
+                byteAggregator.writeByte(Ipv4Util.getPrefixLength(ipv4Prefix.getValue()));
+                byteAggregator.writeBytes(Ipv4Util.bytesForPrefixByPrefixLength(ipv4Prefix));
+            }
+        } else if (destinationType instanceof DestinationIpv6Case) {
+            DestinationIpv6Case destinationIpv6Case = (DestinationIpv6Case) destinationType;
+            for (Ipv6Prefix ipv6Prefix : destinationIpv6Case.getDestinationIpv6().getIpv6Prefixes()) {
+                byteAggregator.writeByte(Ipv4Util.getPrefixLength(ipv6Prefix.getValue()));
+                byteAggregator.writeBytes(Ipv6Util.bytesForPrefixByPrefixLength(ipv6Prefix));
+            }
+        }
     }
 }
index 44085876b84d2adee0d73dee1b06fc769e0184bf..6ac50915baccf06fa30417dbcc86fb8c5b80070c 100644 (file)
@@ -8,23 +8,31 @@
 package org.opendaylight.protocol.bgp.parser.impl.message.update;
 
 import com.google.common.base.Preconditions;
-
 import io.netty.buffer.ByteBuf;
-
+import io.netty.buffer.Unpooled;
+import org.opendaylight.protocol.bgp.parser.AttributeFlags;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.NlriRegistry;
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.concepts.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.destination.type.DestinationIpv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.destination.type.DestinationIpv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 
-public final class MPUnreachAttributeParser implements AttributeParser,AttributeSerializer {
-
+public final class MPUnreachAttributeParser implements AttributeParser, AttributeSerializer {
     public static final int TYPE = 15;
+    public static final int MAX_ATTR_LENGTH_FOR_SINGLE_BYTE = 127;
 
     private final NlriRegistry reg;
 
@@ -44,6 +52,44 @@ public final class MPUnreachAttributeParser implements AttributeParser,Attribute
 
     @Override
     public void serializeAttribute(DataObject attribute, ByteBuf byteAggregator) {
-        //FIME: implement this
+        PathAttributes pathAttributes = (PathAttributes) attribute;
+        PathAttributes2 pathAttributes2 = pathAttributes.getAugmentation(PathAttributes2.class);
+        if (pathAttributes2 == null) {
+            return;
+        }
+        MpUnreachNlri mpUnreachNlri = pathAttributes2.getMpUnreachNlri();
+        ByteBuf unreachBuffer = Unpooled.buffer();
+        this.reg.serializeMpUnReach(mpUnreachNlri, unreachBuffer);
+
+        if (mpUnreachNlri.getWithdrawnRoutes() != null) {
+            if (mpUnreachNlri.getWithdrawnRoutes().getDestinationType() instanceof DestinationIpv4Case) {
+                DestinationIpv4Case destinationIpv4Case = (DestinationIpv4Case) mpUnreachNlri.getWithdrawnRoutes().getDestinationType();
+                if (destinationIpv4Case.getDestinationIpv4().getIpv4Prefixes() != null) {
+                    for (Ipv4Prefix ipv4Prefix : destinationIpv4Case.getDestinationIpv4().getIpv4Prefixes()) {
+                        unreachBuffer.writeByte(Ipv4Util.getPrefixLength(ipv4Prefix.getValue()));
+                        unreachBuffer.writeBytes(Ipv4Util.bytesForPrefixByPrefixLength(ipv4Prefix));
+                    }
+                }
+            }
+            if (mpUnreachNlri.getWithdrawnRoutes().getDestinationType() instanceof DestinationIpv6Case) {
+                DestinationIpv6Case destinationIpv6Case = (DestinationIpv6Case) mpUnreachNlri.getWithdrawnRoutes().getDestinationType();
+                if (destinationIpv6Case.getDestinationIpv6().getIpv6Prefixes() != null) {
+                    for (Ipv6Prefix ipv6Prefix : destinationIpv6Case.getDestinationIpv6().getIpv6Prefixes()) {
+                        unreachBuffer.writeByte(Ipv4Util.getPrefixLength(ipv6Prefix.getValue()));
+                        unreachBuffer.writeBytes(Ipv6Util.bytesForPrefixByPrefixLength(ipv6Prefix));
+                    }
+                }
+            }
+        }
+        if (unreachBuffer.writerIndex() > MAX_ATTR_LENGTH_FOR_SINGLE_BYTE) {
+            byteAggregator.writeByte(AttributeFlags.OPTIONAL | AttributeFlags.EXTENDED);
+            byteAggregator.writeByte(TYPE);
+            byteAggregator.writeShort(unreachBuffer.writerIndex());
+        } else {
+            byteAggregator.writeByte(AttributeFlags.OPTIONAL);
+            byteAggregator.writeByte(TYPE);
+            byteAggregator.writeByte(unreachBuffer.writerIndex());
+        }
+        byteAggregator.writeBytes(unreachBuffer);
     }
 }
index ad271aaf0454264a77fc5cfb4da6d18069a2fd0b..f8bcdbbdd1cf74418c0f9ae5c5c88ecd46225774 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.protocol.bgp.parser.impl;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertTrue;
 
 import io.netty.buffer.ByteBuf;
@@ -25,14 +26,16 @@ import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AsPath;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Communities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.ExtendedCommunities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.as.path.Segments;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ExtendedCommunity;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
@@ -47,6 +50,7 @@ public class BGPUpdateAttributesSerializationTest {
     static final List<byte[]> inputBytes = new ArrayList<byte[]>();
     private static BGPUpdateMessageParser updateParser = new BGPUpdateMessageParser(ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getAttributeRegistry());
 
+
     private static int COUNTER = 9;//17;
     private static int MAX_SIZE = 300;
 
@@ -120,6 +124,12 @@ public class BGPUpdateAttributesSerializationTest {
         if (left.getOriginatorId() != null) {
             assertEquals(left.getOriginatorId().getValue(), right.getOriginatorId().getValue());
         }
+        if (left.getAugmentation(PathAttributes1.class) != null) {
+            assertNotNull(right.getAugmentation(PathAttributes1.class));
+        }
+        if (left.getAugmentation(PathAttributes2.class) != null) {
+            assertNotNull(right.getAugmentation(PathAttributes2.class));
+        }
     }
 
     private void assertEqualsClusterId(List<ClusterIdentifier> left, List<ClusterIdentifier> right) {
index bf8b497f66d155009627462fa62e736884f77258..92a110dcce0178f39f545c46e1a30ad9ab4f86d2 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 
 public interface NlriRegistry {
     MpReachNlri parseMpReach(final ByteBuf buffer) throws BGPParsingException;
-
     MpUnreachNlri parseMpUnreach(final ByteBuf buffer) throws BGPParsingException;
+    void serializeMpReach(final MpReachNlri mpReachNlri,final ByteBuf byteAggregator);
+    void serializeMpUnReach(final MpUnreachNlri mpUnreachNlri,final ByteBuf byteAggregator);
 }
index ead818296ff0b7e297746066b56fa4a6d8148b20..3824024e77205cd642bdd1fe6af6b818e3bea1f4 100644 (file)
@@ -11,10 +11,12 @@ import com.google.common.base.Preconditions;
 import com.google.common.primitives.UnsignedBytes;
 
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import org.opendaylight.protocol.bgp.concepts.util.NextHopUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
 import org.opendaylight.protocol.bgp.parser.spi.AddressFamilyRegistry;
@@ -32,6 +34,7 @@ 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.SubsequentAddressFamily;
 
 final class SimpleNlriRegistry implements NlriRegistry {
+
     private final ConcurrentMap<BgpTableType, NlriParser> handlers = new ConcurrentHashMap<>();
     private final SubsequentAddressFamilyRegistry safiReg;
     private final AddressFamilyRegistry afiReg;
@@ -41,14 +44,15 @@ final class SimpleNlriRegistry implements NlriRegistry {
         this.safiReg = Preconditions.checkNotNull(safiReg);
     }
 
-    private static BgpTableType createKey(final Class<? extends AddressFamily> afi, final Class<? extends SubsequentAddressFamily> safi) {
+    private static BgpTableType createKey(final Class<? extends AddressFamily> afi,
+                                          final Class<? extends SubsequentAddressFamily> safi) {
         Preconditions.checkNotNull(afi);
         Preconditions.checkNotNull(safi);
         return new BgpTableTypeImpl(afi, safi);
     }
 
     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 BgpTableType key = createKey(afi, safi);
         final NlriParser prev = this.handlers.get(key);
         Preconditions.checkState(prev == null, "AFI/SAFI is already bound to parser " + prev);
@@ -95,6 +99,29 @@ final class SimpleNlriRegistry implements NlriRegistry {
         return builder.build();
     }
 
+    @Override
+    public void serializeMpReach(MpReachNlri mpReachNlri, ByteBuf byteAggregator) {
+
+        byteAggregator.writeShort(this.afiReg.numberForClass(mpReachNlri.getAfi()));
+        byteAggregator.writeByte(this.safiReg.numberForClass(mpReachNlri.getSafi()));
+
+        ByteBuf nextHopBuffer = Unpooled.buffer();
+        NextHopUtil.serializeNextHopSimple(mpReachNlri.getCNextHop(), nextHopBuffer);
+
+        byteAggregator.writeByte(nextHopBuffer.writerIndex());
+        byteAggregator.writeBytes(nextHopBuffer);
+
+        //TODO how to calculate number of SNPAs Subnetwork Points of Attachment and serialize SNPAs ?
+        byteAggregator.writeByte(0);
+    }
+
+    @Override
+    public void serializeMpUnReach(MpUnreachNlri mpUnreachNlri, ByteBuf byteAggregator) {
+
+        byteAggregator.writeShort(this.afiReg.numberForClass(mpUnreachNlri.getAfi()));
+        byteAggregator.writeByte(this.safiReg.numberForClass(mpUnreachNlri.getSafi()));
+    }
+
     @Override
     public MpReachNlri parseMpReach(final ByteBuf buffer) throws BGPParsingException {
         final MpReachNlriBuilder builder = new MpReachNlriBuilder();
index eeae25905bdb052cd78c4e3b0efa73f051752359..5c1adec02119a1ff1f9c806c796fbfd0c4da016b 100644 (file)
@@ -86,6 +86,17 @@ public final class Ipv4Util {
         return bits / 8;
     }
 
+    /**
+     * Converts Ipv4Prefix to byte array of length equal to prefix length value.
+     *
+     * @param ipv4Prefix Ipv4Prefix to be converted
+     * @return byte array
+     */
+    public static byte[] bytesForPrefixByPrefixLength(Ipv4Prefix ipv4Prefix) {
+        return ByteArray.subByte(bytesForPrefix(ipv4Prefix), 0,
+                getPrefixLengthBytes(ipv4Prefix.getValue()));
+    }
+
     /**
      * Converts Ipv4Prefix to byte array.
      *
index e1b0460149c0ba5a17d3fe718625058ea345d9ad..6bce00f7ce615bab23549748b5dba1265bdb8e4d 100644 (file)
@@ -12,14 +12,12 @@ import com.google.common.collect.Lists;
 import com.google.common.net.InetAddresses;
 import com.google.common.primitives.Bytes;
 import com.google.common.primitives.UnsignedBytes;
-
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
@@ -70,6 +68,19 @@ public final class Ipv6Util {
         return a.getAddress();
     }
 
+
+    /**
+     * Converts Ipv6Prefix to byte array of (prefix bit size/8) size.
+     *
+     * @param ipv6Prefix Ipv6Prefix to be converted
+     * @return byte array
+     */
+    public static byte[] bytesForPrefixByPrefixLength(Ipv6Prefix ipv6Prefix) {
+        return ByteArray.subByte(Ipv6Util.bytesForPrefix(ipv6Prefix), 0,
+                Ipv4Util.getPrefixLengthBytes(ipv6Prefix.getValue()));
+    }
+
+
     /**
      * Converts Ipv6Prefix to byte array.
      *