Bug-4827: BGP Add-Path OpenConfig Support
[bgpcep.git] / bgp / openconfig-impl / src / main / java / org / opendaylight / protocol / bgp / openconfig / impl / util / OpenConfigUtil.java
index ccafcd2320edd0c2a6738610830567363b6d937e..210324126be70112dfc2eeec5e6bc70309f3d1b3 100644 (file)
@@ -12,11 +12,23 @@ import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.function.BiFunction;
+import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
+import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.UseMultiplePathsBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ConfigBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.EbgpBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.IbgpBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1Builder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2Builder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4LABELLEDUNICAST;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
@@ -31,9 +43,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labe
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
 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.multiprotocol.rev130919.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Ipv4Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Ipv6Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Linkstate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
 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;
@@ -79,12 +93,13 @@ public final class OpenConfigUtil {
         return Optional.fromNullable(TABLETYPE_TO_AFISAFI.get(tableType));
     }
 
-    public static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables) {
+    public static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function) {
         final List<AfiSafi> afiSafis = new ArrayList<>(advertizedTables.size());
         for (final BgpTableType tableType : advertizedTables) {
-            final Optional<AfiSafi> afiSafi = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()));
-            if (afiSafi.isPresent()) {
-                afiSafis.add(afiSafi.get());
+            final Optional<AfiSafi> afiSafiMaybe = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()));
+            if (afiSafiMaybe.isPresent()) {
+                final AfiSafi afiSafi = function.apply(afiSafiMaybe.get(), tableType);
+                afiSafis.add(afiSafi);
             }
         }
         return afiSafis;
@@ -93,4 +108,40 @@ public final class OpenConfigUtil {
     public static String getModuleName(final String provider) {
         return provider.substring(provider.lastIndexOf('=') + 2, provider.length() - 2);
     }
+
+    public static AfiSafi toNeigborAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Collection<AddressFamilies> addPathCapabilities) {
+        final java.util.Optional<AddressFamilies> addPathMayBe = addPathCapabilities.stream().filter(
+                af -> af.getAfi() == tableType.getAfi() && af.getSafi() == tableType.getSafi()).findFirst();
+        if (addPathMayBe.isPresent()) {
+            final AfiSafi2 afiSafi3 = new AfiSafi2Builder().setUseMultiplePaths(
+                    new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.UseMultiplePathsBuilder().setConfig(
+                    new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.use.multiple.paths.ConfigBuilder()
+                        .setEnabled(true).build()).build()).build();
+            return new AfiSafiBuilder(afiSafi).addAugmentation(AfiSafi2.class, afiSafi3).build();
+        }
+        return afiSafi;
+    }
+
+    public static AfiSafi toGlobalAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Map<TablesKey, PathSelectionMode> pathSelectionModes) {
+        final PathSelectionMode pathSelection = pathSelectionModes.get(new TablesKey(tableType.getAfi(), tableType.getSafi()));
+        if (pathSelection == null) {
+            return afiSafi;
+        }
+        final Long maxPaths;
+        if (pathSelection instanceof AddPathBestNPathSelection) {
+            maxPaths = ((AddPathBestNPathSelection) pathSelection).getNBestPaths();
+        } else {
+            maxPaths = null;
+        }
+        final AfiSafi1 afiSafi1 = new AfiSafi1Builder().setUseMultiplePaths(
+                new UseMultiplePathsBuilder().setConfig(new ConfigBuilder().setEnabled(true).build())
+                    .setEbgp(maxPaths != null ? new EbgpBuilder().setConfig(
+                            new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ebgp.ConfigBuilder()
+                                .setMaximumPaths(maxPaths)
+                                .build()).build() : null)
+                    .setIbgp(maxPaths != null ? new IbgpBuilder().setConfig(
+                        new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ibgp.ConfigBuilder()
+                            .setMaximumPaths(maxPaths).build()).build() : null).build()).build();
+        return new AfiSafiBuilder(afiSafi).addAugmentation(AfiSafi1.class, afiSafi1).build();
+    }
 }