BUG-4592: Route Refresh Capability Config subystem 76/35876/7
authorIveta Halanova <ihalanov@cisco.com>
Mon, 7 Mar 2016 13:39:48 +0000 (14:39 +0100)
committerIveta Halanova <ihalanov@cisco.com>
Thu, 10 Mar 2016 08:56:33 +0000 (09:56 +0100)
Added possibility to advertize RR Capability in open messge
and to configure this capability in ODL for peer.
Created Util class for common afi, safi handling with MP and with CParameters constant.
Updated and added tests.

Change-Id: Iabe3d96d49368be6870d4fffd207ca15021dcfd0
Signed-off-by: Iveta Halanova <ihalanov@cisco.com>
bgp/parser-api/src/main/java/org/opendaylight/protocol/bgp/parser/MultiprotocolCapabilitiesUtil.java [new file with mode: 0644]
bgp/parser-api/src/main/yang/bgp-multiprotocol.yang
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/open/RouteRefreshCapabilityHandler.java [new file with mode: 0644]
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/RouteRefreshCapabilityHandlerTest.java [new file with mode: 0644]
bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModule.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPSessionStats.java
bgp/rib-impl/src/main/yang/odl-bgp-rib-impl-cfg.yang
bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModuleTest.java

diff --git a/bgp/parser-api/src/main/java/org/opendaylight/protocol/bgp/parser/MultiprotocolCapabilitiesUtil.java b/bgp/parser-api/src/main/java/org/opendaylight/protocol/bgp/parser/MultiprotocolCapabilitiesUtil.java
new file mode 100644 (file)
index 0000000..b6ada64
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2016 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;
+
+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.open.message.bgp.parameters.optional.capabilities.CParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.RouteRefreshCapabilityBuilder;
+
+public final class MultiprotocolCapabilitiesUtil {
+
+    public static final CParameters RR_CAPABILITY = new CParametersBuilder().addAugmentation(CParameters1.class,
+        new CParameters1Builder().setRouteRefreshCapability(new RouteRefreshCapabilityBuilder().build()).build()).build();
+
+    // move common functionality will be added
+}
index c3eacbd5b9d69e830d7be5d1be8e6caa746c6f78..5480bd6ed8d0b1a870017b6b7d9adf0846eb417a 100644 (file)
@@ -109,6 +109,10 @@ module bgp-multiprotocol {
                 }
             }
         }
+        container route-refresh-capability {
+            presence "Route refresh capability";
+            reference "http://tools.ietf.org/html/rfc2918";
+        }
     }
 
     augment "/bgp-msg:update/bgp-msg:attributes" {
index d78f8a3fd0d0f2f5ed6eb8739500e04ea094d439..71c0a34ec0801359e4db2c9a14bf9cb38d1b457b 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.protocol.bgp.parser.impl.message.open.BgpExtendedMessage
 import org.opendaylight.protocol.bgp.parser.impl.message.open.CapabilityParameterParser;
 import org.opendaylight.protocol.bgp.parser.impl.message.open.GracefulCapabilityHandler;
 import org.opendaylight.protocol.bgp.parser.impl.message.open.MultiProtocolCapabilityHandler;
+import org.opendaylight.protocol.bgp.parser.impl.message.open.RouteRefreshCapabilityHandler;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.AS4AggregatorAttributeParser;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.AS4PathAttributeParser;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.AdvertizedRoutesSerializer;
@@ -75,6 +76,7 @@ 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.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.AddPathCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.GracefulRestartCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.MultiprotocolCapability;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.RouteRefreshCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
@@ -141,6 +143,10 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
         regs.add(context.registerCapabilityParser(AddPathCapabilityHandler.CODE, addPath));
         regs.add(context.registerCapabilitySerializer(AddPathCapability.class, addPath));
 
+        final RouteRefreshCapabilityHandler routeRefresh = new RouteRefreshCapabilityHandler();
+        regs.add(context.registerCapabilityParser(RouteRefreshCapabilityHandler.CODE, routeRefresh));
+        regs.add(context.registerCapabilitySerializer(RouteRefreshCapability.class, routeRefresh));
+
         final As4CapabilityHandler as4 = new As4CapabilityHandler();
         regs.add(context.registerCapabilityParser(As4CapabilityHandler.CODE, as4));
         regs.add(context.registerCapabilitySerializer(As4BytesCapability.class, as4));
@@ -242,51 +248,51 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
     private void registerExtendedCommunities(final List<AutoCloseable> regs, final BGPExtensionProviderContext context) {
         final AsTwoOctetSpecificEcHandler twoOctetSpecificEcHandler = new AsTwoOctetSpecificEcHandler();
         regs.add(context.registerExtendedCommunityParser(twoOctetSpecificEcHandler.getType(true), twoOctetSpecificEcHandler.getSubType(),
-                twoOctetSpecificEcHandler));
+            twoOctetSpecificEcHandler));
         regs.add(context.registerExtendedCommunityParser(twoOctetSpecificEcHandler.getType(false), twoOctetSpecificEcHandler.getSubType(),
-                twoOctetSpecificEcHandler));
+            twoOctetSpecificEcHandler));
         regs.add(context.registerExtendedCommunitySerializer(AsSpecificExtendedCommunityCase.class, twoOctetSpecificEcHandler));
 
         final Ipv4SpecificEcHandler ipv4SpecificEcHandler = new Ipv4SpecificEcHandler();
         regs.add(context.registerExtendedCommunityParser(ipv4SpecificEcHandler.getType(true), ipv4SpecificEcHandler.getSubType(),
-                ipv4SpecificEcHandler));
+            ipv4SpecificEcHandler));
         regs.add(context.registerExtendedCommunityParser(ipv4SpecificEcHandler.getType(false), ipv4SpecificEcHandler.getSubType(),
-                ipv4SpecificEcHandler));
+            ipv4SpecificEcHandler));
         regs.add(context.registerExtendedCommunitySerializer(Inet4SpecificExtendedCommunityCase.class, ipv4SpecificEcHandler));
 
         final OpaqueEcHandler opaqueEcHandler = new OpaqueEcHandler();
         regs.add(context.registerExtendedCommunityParser(opaqueEcHandler.getType(true), opaqueEcHandler.getSubType(),
-                opaqueEcHandler));
+            opaqueEcHandler));
         regs.add(context.registerExtendedCommunityParser(opaqueEcHandler.getType(false), opaqueEcHandler.getSubType(),
-                opaqueEcHandler));
+            opaqueEcHandler));
         regs.add(context.registerExtendedCommunitySerializer(OpaqueExtendedCommunityCase.class, opaqueEcHandler));
 
         final RouteOriginAsTwoOctetEcHandler routeOriginAS2bEcHandler = new RouteOriginAsTwoOctetEcHandler();
         regs.add(context.registerExtendedCommunityParser(routeOriginAS2bEcHandler.getType(true), routeOriginAS2bEcHandler.getSubType(),
-                routeOriginAS2bEcHandler));
+            routeOriginAS2bEcHandler));
         regs.add(context.registerExtendedCommunityParser(routeOriginAS2bEcHandler.getType(false), routeOriginAS2bEcHandler.getSubType(),
-                routeOriginAS2bEcHandler));
+            routeOriginAS2bEcHandler));
         regs.add(context.registerExtendedCommunitySerializer(RouteOriginExtendedCommunityCase.class, routeOriginAS2bEcHandler));
 
         final RouteTargetAsTwoOctetEcHandler routeTargetAS2bEcHandler = new RouteTargetAsTwoOctetEcHandler();
         regs.add(context.registerExtendedCommunityParser(routeTargetAS2bEcHandler.getType(true), routeTargetAS2bEcHandler.getSubType(),
-                routeTargetAS2bEcHandler));
+            routeTargetAS2bEcHandler));
         regs.add(context.registerExtendedCommunityParser(routeTargetAS2bEcHandler.getType(false), routeTargetAS2bEcHandler.getSubType(),
-                routeTargetAS2bEcHandler));
+            routeTargetAS2bEcHandler));
         regs.add(context.registerExtendedCommunitySerializer(RouteTargetExtendedCommunityCase.class, routeTargetAS2bEcHandler));
 
         final RouteOriginIpv4EcHandler routeOriginIpv4EcHandler = new RouteOriginIpv4EcHandler();
         regs.add(context.registerExtendedCommunityParser(routeOriginIpv4EcHandler.getType(true), routeOriginIpv4EcHandler.getSubType(),
-                routeOriginIpv4EcHandler));
+            routeOriginIpv4EcHandler));
         regs.add(context.registerExtendedCommunityParser(routeOriginIpv4EcHandler.getType(false), routeOriginIpv4EcHandler.getSubType(),
-                routeOriginIpv4EcHandler));
+            routeOriginIpv4EcHandler));
         regs.add(context.registerExtendedCommunitySerializer(RouteOriginIpv4Case.class, routeOriginIpv4EcHandler));
 
         final RouteTargetIpv4EcHandler routeTargetIpv4EcHandler = new RouteTargetIpv4EcHandler();
         regs.add(context.registerExtendedCommunityParser(routeTargetIpv4EcHandler.getType(true), routeTargetIpv4EcHandler.getSubType(),
-                routeTargetIpv4EcHandler));
+            routeTargetIpv4EcHandler));
         regs.add(context.registerExtendedCommunityParser(routeTargetIpv4EcHandler.getType(false), routeTargetIpv4EcHandler.getSubType(),
-                routeTargetIpv4EcHandler));
+            routeTargetIpv4EcHandler));
         regs.add(context.registerExtendedCommunitySerializer(RouteTargetIpv4Case.class, routeTargetIpv4EcHandler));
     }
 }
diff --git a/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/RouteRefreshCapabilityHandler.java b/bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/open/RouteRefreshCapabilityHandler.java
new file mode 100644 (file)
index 0000000..4400b51
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 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.open;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.MultiprotocolCapabilitiesUtil;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityParser;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilitySerializer;
+import org.opendaylight.protocol.bgp.parser.spi.CapabilityUtil;
+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.multiprotocol.rev130919.CParameters1;
+
+public class RouteRefreshCapabilityHandler implements CapabilityParser, CapabilitySerializer {
+
+    // https://tools.ietf.org/html/rfc2918#section-2
+    public static final int CODE = 2;
+
+    @Override
+    public void serializeCapability(final CParameters capability, final ByteBuf byteAggregator) {
+        if (capability == null || (capability.getAugmentation(CParameters1.class) == null) ||
+            (capability.getAugmentation(CParameters1.class).getRouteRefreshCapability() == null) ) {
+            return;
+        }
+        CapabilityUtil.formatCapability(CODE, Unpooled.EMPTY_BUFFER, byteAggregator);
+    }
+
+    @Override
+    public CParameters parseCapability(final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException {
+        return MultiprotocolCapabilitiesUtil.RR_CAPABILITY;
+    }
+
+}
diff --git a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/RouteRefreshCapabilityHandlerTest.java b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/RouteRefreshCapabilityHandlerTest.java
new file mode 100644 (file)
index 0000000..64b1bb5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 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;
+
+import static org.junit.Assert.assertEquals;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.bgp.parser.impl.message.open.RouteRefreshCapabilityHandler;
+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.open.message.bgp.parameters.optional.capabilities.CParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.RouteRefreshCapabilityBuilder;
+
+public class RouteRefreshCapabilityHandlerTest {
+
+    private static final RouteRefreshCapabilityHandler HANDLER = new RouteRefreshCapabilityHandler();
+
+    private static final byte[] WRONG_BYTES = new byte[] {1, 2};
+    private static final byte[] OK_BYTES = new byte[] {0};
+    private static final byte[] CAP_BYTES = new byte[] {2, 0};
+
+    @Test
+    public void testRRCapHandler() throws BGPDocumentedException, BGPParsingException {
+        final CParameters expectedParams = new CParametersBuilder().addAugmentation(CParameters1.class,new CParameters1Builder().setRouteRefreshCapability(
+            new RouteRefreshCapabilityBuilder().build()).build()).build();
+        assertEquals(expectedParams, HANDLER.parseCapability(Unpooled.copiedBuffer(OK_BYTES)));
+        assertEquals(expectedParams, HANDLER.parseCapability(Unpooled.copiedBuffer(WRONG_BYTES)));
+
+        final ByteBuf byteAggregator = Unpooled.buffer(2);
+        HANDLER.serializeCapability(expectedParams, byteAggregator);
+        assertEquals(Unpooled.copiedBuffer(CAP_BYTES), byteAggregator);
+
+        final CParameters missingCap = new CParametersBuilder().addAugmentation(CParameters1.class,new CParameters1Builder().setRouteRefreshCapability(
+            null).build()).build();
+        final ByteBuf byteAggregator2 = Unpooled.buffer(0);
+        HANDLER.serializeCapability(missingCap, byteAggregator2);
+        assertEquals(Unpooled.copiedBuffer(new byte[]{}), byteAggregator2);
+    }
+}
index f89dc0d7d6f052cae92cb7804eca54748aa03292..619043c13cc1e6ef861fd851a5dad5cea2281e19 100644 (file)
@@ -32,6 +32,7 @@ import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenconfigMapper;
 import org.opendaylight.protocol.bgp.openconfig.spi.InstanceConfigurationIdentifier;
 import org.opendaylight.protocol.bgp.openconfig.spi.pojo.BGPPeerInstanceConfiguration;
+import org.opendaylight.protocol.bgp.parser.MultiprotocolCapabilitiesUtil;
 import org.opendaylight.protocol.bgp.rib.impl.BGPPeer;
 import org.opendaylight.protocol.bgp.rib.impl.StrictBGPPeerRegistry;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
@@ -193,6 +194,10 @@ public final class BGPPeerModule extends org.opendaylight.controller.config.yang
         caps.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class,
             new CParameters1Builder().setGracefulRestartCapability(new GracefulRestartCapabilityBuilder().build()).build()).build()).build());
 
+        if (getRouteRefresh()) {
+            caps.add(new OptionalCapabilitiesBuilder().setCParameters(MultiprotocolCapabilitiesUtil.RR_CAPABILITY).build());
+        }
+
         if (!getAddPathDependency().isEmpty()) {
             final List<AddressFamilies> addPathFamilies = filterAddPathDependency(getAddPathDependency());
             caps.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class,
index 012a415eef995bd477047af00e9d41b3150ba90c..442c8203e4b54ad8a65139f6f42d52b90e4b31ba 100644 (file)
@@ -193,6 +193,10 @@ final class BGPSessionStats {
                             if (cParam.getBgpExtendedMessageCapability() != null) {
                                 pref.setBgpExtendedMessageCapability(true);
                             }
+                            if (cParam.getAugmentation(CParameters1.class) != null &&
+                                cParam.getAugmentation(CParameters1.class).getRouteRefreshCapability() != null) {
+                                pref.setRouteRefreshCapability(true);
+                            }
                         }
                     }
                 }
@@ -231,6 +235,10 @@ final class BGPSessionStats {
                             cParam.getAugmentation(CParameters1.class).getAddPathCapability() != null) {
                         pref.setAddPathCapability(true);
                     }
+                    if (cParam.getAugmentation(CParameters1.class) != null &&
+                        cParam.getAugmentation(CParameters1.class).getRouteRefreshCapability() != null) {
+                        pref.setRouteRefreshCapability(true);
+                    }
                     if (cParam.getBgpExtendedMessageCapability() != null) {
                         pref.setBgpExtendedMessageCapability(true);
                     }
index 6d872e8eb6d137eec5a1036f8514fe7516586046..52ba0c1459481187bd8e24f915ed32f6bf271025 100644 (file)
@@ -373,6 +373,11 @@ module odl-bgp-rib-impl-cfg {
                 }
             }
 
+            leaf route-refresh {
+                type boolean;
+                default "true";
+            }
+
             leaf remote-as {
                 description
                     "Expected remote AS number. If not present, it is assumed
@@ -501,6 +506,12 @@ module odl-bgp-rib-impl-cfg {
             default "false";
         }
 
+        leaf route-refresh-capability {
+            reference "https://tools.ietf.org/html/rfc2918";
+            type boolean;
+            default "false";
+        }
+
         list advertized-table-types {
             description "The BGP Table-type capabilities advertized by the BGP peer.";
             leaf afi {
index 5db6e35be7b68c2f7098c2057084e64dc22ac916..b298f620bb90914ea85d19df683b6a02fcf0c7dc 100644 (file)
@@ -159,6 +159,7 @@ public class BGPPeerModuleTest extends AbstractRIBImplModuleTest {
         mxBean.setHost(host);
         mxBean.setPort(port);
         mxBean.setAdvertizedTable(Collections.<ObjectName>emptyList());
+        mxBean.setRouteRefresh(false);
         {
             final ObjectName ribON = createRIBImplModuleInstance(transaction);
             mxBean.setRib(ribON);