Bug-4827: BGP Add-Path OpenConfig Support
[bgpcep.git] / bgp / openconfig-impl / src / main / java / org / opendaylight / protocol / bgp / openconfig / impl / util / OpenConfigUtil.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.protocol.bgp.openconfig.impl.util;
10
11 import com.google.common.base.Optional;
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.collect.ImmutableMap.Builder;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.function.BiFunction;
19 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
20 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
21 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
22 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
23 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
24 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.UseMultiplePathsBuilder;
25 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ConfigBuilder;
26 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.EbgpBuilder;
27 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.IbgpBuilder;
28 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1;
29 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi1Builder;
30 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2;
31 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.AfiSafi2Builder;
32 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
33 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4LABELLEDUNICAST;
34 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV6LABELLEDUNICAST;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV6UNICAST;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L2VPNEVPN;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.L3VPNIPV4UNICAST;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.EvpnSubsequentAddressFamily;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecSubsequentAddressFamily;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.LabeledUnicastSubsequentAddressFamily;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Ipv4Flow;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Ipv6Flow;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev150930.Linkstate;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56
57 public final class OpenConfigUtil {
58
59     public static final InstanceIdentifier<Bgp> BGP_IID = InstanceIdentifier.create(Bgp.class);
60
61     public static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
62
63     private static final Map<BgpTableType, AfiSafi> TABLETYPE_TO_AFISAFI;
64
65     static {
66         final Builder<BgpTableType, AfiSafi> b = ImmutableMap.builder();
67         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class),
68             new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build());
69         b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class),
70             new AfiSafiBuilder().setAfiSafiName(IPV6UNICAST.class).build());
71         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class),
72             new AfiSafiBuilder().setAfiSafiName(IPV4LABELLEDUNICAST.class).build());
73         b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, LabeledUnicastSubsequentAddressFamily.class),
74             new AfiSafiBuilder().setAfiSafiName(IPV6LABELLEDUNICAST.class).build());
75         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class),
76             new AfiSafiBuilder().setAfiSafiName(L3VPNIPV4UNICAST.class).build());
77         b.put(new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class),
78             new AfiSafiBuilder().setAfiSafiName(Linkstate.class).build());
79         b.put(new BgpTableTypeImpl(Ipv4AddressFamily.class, FlowspecSubsequentAddressFamily.class),
80             new AfiSafiBuilder().setAfiSafiName(Ipv4Flow.class).build());
81         b.put(new BgpTableTypeImpl(Ipv6AddressFamily.class, FlowspecSubsequentAddressFamily.class),
82             new AfiSafiBuilder().setAfiSafiName(Ipv6Flow.class).build());
83         b.put(new BgpTableTypeImpl(L2vpnAddressFamily.class, EvpnSubsequentAddressFamily.class),
84             new AfiSafiBuilder().setAfiSafiName(L2VPNEVPN.class).build());
85         TABLETYPE_TO_AFISAFI = b.build();
86     }
87
88     private OpenConfigUtil() {
89         throw new UnsupportedOperationException();
90     }
91
92     public static Optional<AfiSafi> toAfiSafi(final BgpTableType tableType) {
93         return Optional.fromNullable(TABLETYPE_TO_AFISAFI.get(tableType));
94     }
95
96     public static List<AfiSafi> toAfiSafis(final List<BgpTableType> advertizedTables, final BiFunction<AfiSafi, BgpTableType, AfiSafi> function) {
97         final List<AfiSafi> afiSafis = new ArrayList<>(advertizedTables.size());
98         for (final BgpTableType tableType : advertizedTables) {
99             final Optional<AfiSafi> afiSafiMaybe = toAfiSafi(new BgpTableTypeImpl(tableType.getAfi(), tableType.getSafi()));
100             if (afiSafiMaybe.isPresent()) {
101                 final AfiSafi afiSafi = function.apply(afiSafiMaybe.get(), tableType);
102                 afiSafis.add(afiSafi);
103             }
104         }
105         return afiSafis;
106     }
107
108     public static String getModuleName(final String provider) {
109         return provider.substring(provider.lastIndexOf('=') + 2, provider.length() - 2);
110     }
111
112     public static AfiSafi toNeigborAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Collection<AddressFamilies> addPathCapabilities) {
113         final java.util.Optional<AddressFamilies> addPathMayBe = addPathCapabilities.stream().filter(
114                 af -> af.getAfi() == tableType.getAfi() && af.getSafi() == tableType.getSafi()).findFirst();
115         if (addPathMayBe.isPresent()) {
116             final AfiSafi2 afiSafi3 = new AfiSafi2Builder().setUseMultiplePaths(
117                     new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.UseMultiplePathsBuilder().setConfig(
118                     new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.neighbor.use.multiple.paths.ConfigBuilder()
119                         .setEnabled(true).build()).build()).build();
120             return new AfiSafiBuilder(afiSafi).addAugmentation(AfiSafi2.class, afiSafi3).build();
121         }
122         return afiSafi;
123     }
124
125     public static AfiSafi toGlobalAfiSafiMultiPath(final AfiSafi afiSafi, final BgpTableType tableType, final Map<TablesKey, PathSelectionMode> pathSelectionModes) {
126         final PathSelectionMode pathSelection = pathSelectionModes.get(new TablesKey(tableType.getAfi(), tableType.getSafi()));
127         if (pathSelection == null) {
128             return afiSafi;
129         }
130         final Long maxPaths;
131         if (pathSelection instanceof AddPathBestNPathSelection) {
132             maxPaths = ((AddPathBestNPathSelection) pathSelection).getNBestPaths();
133         } else {
134             maxPaths = null;
135         }
136         final AfiSafi1 afiSafi1 = new AfiSafi1Builder().setUseMultiplePaths(
137                 new UseMultiplePathsBuilder().setConfig(new ConfigBuilder().setEnabled(true).build())
138                     .setEbgp(maxPaths != null ? new EbgpBuilder().setConfig(
139                             new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ebgp.ConfigBuilder()
140                                 .setMaximumPaths(maxPaths)
141                                 .build()).build() : null)
142                     .setIbgp(maxPaths != null ? new IbgpBuilder().setConfig(
143                         new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.use.multiple.paths.use.multiple.paths.ibgp.ConfigBuilder()
144                             .setMaximumPaths(maxPaths).build()).build() : null).build()).build();
145         return new AfiSafiBuilder(afiSafi).addAugmentation(AfiSafi1.class, afiSafi1).build();
146     }
147 }