b33c722c55461f6554d9529d30dcade7057a8e9b
[bgpcep.git] / bgp / openconfig-impl / src / main / java / org / opendaylight / protocol / bgp / openconfig / impl / BGPOpenConfigMappingServiceImpl.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;
10
11 import static org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil.APPLICATION_PEER_GROUP_NAME;
12
13 import com.google.common.base.Optional;
14 import java.math.BigDecimal;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.stream.Collectors;
21 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
22 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
23 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
24 import org.opendaylight.protocol.bgp.openconfig.impl.util.OpenConfigUtil;
25 import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigMappingService;
26 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
27 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborAddPathsConfig;
28 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.AfiSafisBuilder;
29 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base.ConfigBuilder;
30 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflectorBuilder;
31 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
32 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TransportBuilder;
33 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
34 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborBuilder;
35 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.NeighborKey;
36 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
37 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroupBuilder;
38 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroupKey;
39 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
40 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.BgpBuilder;
41 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
42 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
43 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.NeighborsBuilder;
44 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.PeerGroups;
45 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.PeerGroupsBuilder;
46 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.CommunityType;
47 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.PeerType;
48 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolBuilder;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
51 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.SendReceive;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamilies;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.add.path.capability.AddressFamiliesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi1;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.AfiSafi2;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config1;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config1Builder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Protocol1Builder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRibId;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.SimpleRoutingPolicy;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.BgpId;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.rfc2385.cfg.rev160324.Rfc2385Key;
74
75 public final class BGPOpenConfigMappingServiceImpl implements BGPOpenConfigMappingService {
76
77     private static final PeerGroup APP_PEER_GROUP = new PeerGroupBuilder().setPeerGroupName(APPLICATION_PEER_GROUP_NAME)
78             .setKey(new PeerGroupKey(APPLICATION_PEER_GROUP_NAME)).build();
79     private static final PeerGroups PEER_GROUPS = new PeerGroupsBuilder().setPeerGroup(Collections.singletonList(APP_PEER_GROUP)).build();
80     private static final BigDecimal DEFAULT_KEEP_ALIVE = BigDecimal.valueOf(30);
81     private static final BigDecimal DEFAULT_MINIMUM_ADV_INTERVAL = BigDecimal.valueOf(30);
82
83     @Override
84     public List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis) {
85         return afiSafis.stream()
86                 .map(afiSafi -> OpenConfigUtil.toBgpTableType(afiSafi.getAfiSafiName()))
87                 .filter(Optional::isPresent)
88                 .map(Optional::get)
89                 .collect(Collectors.toList());
90     }
91
92     @Override
93     public Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis) {
94         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
95         for (final AfiSafi afiSafi : afiSafis) {
96             final BgpNeighborAddPathsConfig afiSafi2 = afiSafi.getAugmentation(AfiSafi2.class);
97             final Optional<BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(afiSafi.getAfiSafiName());
98             if (afiSafi2 != null && bgpTableType.isPresent()) {
99                 final Short sendMax = afiSafi2.getSendMax();
100                 final PathSelectionMode selectionMode;
101                 if (sendMax > 1) {
102                     selectionMode = new AddPathBestNPathSelection(sendMax.longValue());
103                 } else {
104                     selectionMode = new AllPathSelection();
105                 }
106                 pathSelectionModes.put(bgpTableType.get(), selectionMode);
107             }
108         }
109         return pathSelectionModes;
110     }
111
112     @Override
113     public boolean isApplicationPeer(final Neighbor neighbor) {
114         return OpenConfigUtil.isAppNeighbor(neighbor);
115     }
116
117     @Override
118     public PeerRole toPeerRole(final Neighbor neighbor) {
119         return OpenConfigUtil.toPeerRole(neighbor);
120     }
121
122     @Override
123     public List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis) {
124         final List<AddressFamilies> addPathCapability = new ArrayList<>();
125         for (final AfiSafi afiSafi : afiSafis) {
126             final BgpNeighborAddPathsConfig afiSafi1 = afiSafi.getAugmentation(AfiSafi1.class);
127             final Optional<BgpTableType> bgpTableType = OpenConfigUtil.toBgpTableType(afiSafi.getAfiSafiName());
128             if (afiSafi1 != null && bgpTableType.isPresent()) {
129                 final AddressFamiliesBuilder builder = new AddressFamiliesBuilder(bgpTableType.get());
130                 builder.setSendReceive(toSendReceiveMode(afiSafi1));
131                 addPathCapability.add(builder.build());
132             }
133         }
134         return addPathCapability;
135     }
136
137     private static SendReceive toSendReceiveMode(final BgpNeighborAddPathsConfig addPath) {
138         if (addPath.isReceive() && addPath.getSendMax() != null) {
139             return SendReceive.Both;
140         }
141         if (addPath.getSendMax() != null) {
142             return SendReceive.Send;
143         }
144         return SendReceive.Receive;
145     }
146
147     @Override
148     public Protocol fromRib(final BgpId bgpId, final ClusterIdentifier clusterIdentifier, final RibId ribId,
149             final AsNumber localAs, final List<BgpTableType> localTables,
150             final Map<TablesKey, PathSelectionMode> pathSelectionStrategies) {
151         final Bgp bgp = toGlobalConfiguration(bgpId, clusterIdentifier, localAs, localTables, pathSelectionStrategies);
152         final ProtocolBuilder protocolBuilder = new ProtocolBuilder();
153         protocolBuilder.setIdentifier(BGP.class);
154         protocolBuilder.setName(ribId.getValue());
155         protocolBuilder.setKey(new ProtocolKey(protocolBuilder.getIdentifier(), protocolBuilder.getName()));
156         return protocolBuilder.addAugmentation(Protocol1.class, new Protocol1Builder().setBgp(bgp).build()).build();
157     }
158
159     private static Bgp toGlobalConfiguration(final BgpId bgpId, final ClusterIdentifier clusterIdentifier,
160             final AsNumber localAs, final List<BgpTableType> localTables,
161             final Map<TablesKey, PathSelectionMode> pathSelectionStrategies) {
162         final BgpBuilder bgpBuilder = new BgpBuilder();
163         bgpBuilder.setNeighbors(new NeighborsBuilder().build());
164         bgpBuilder.setPeerGroups(PEER_GROUPS);
165         final Global global = new GlobalBuilder().setAfiSafis(new AfiSafisBuilder().setAfiSafi(OpenConfigUtil.toAfiSafis(localTables,
166                 (afiSafi, tableType) -> OpenConfigUtil.toGlobalAfiSafiAddPath(afiSafi, tableType, pathSelectionStrategies))).build())
167                 .setConfig(new ConfigBuilder().setAs(localAs).setRouterId(bgpId).build()).build();
168         bgpBuilder.setGlobal(global);
169         return bgpBuilder.build();
170     }
171
172     @Override
173     public Neighbor fromBgpPeer(final List<AddressFamilies> addPathCapabilities,
174             final List<BgpTableType> advertisedTables, final Integer holdTimer, final IpAddress ipAddress,
175             final Boolean isActive, final Rfc2385Key password, final PortNumber portNumber, final Integer retryTimer,
176             final AsNumber remoteAs, final PeerRole peerRole, final SimpleRoutingPolicy simpleRoutingPolicy) {
177         final NeighborBuilder neighborBuilder = new NeighborBuilder();
178         neighborBuilder.setNeighborAddress(ipAddress);
179         neighborBuilder.setKey(new NeighborKey(ipAddress));
180         neighborBuilder.setAfiSafis(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder().setAfiSafi(OpenConfigUtil.toAfiSafis(advertisedTables,
181                 (afiSafi, tableType) -> OpenConfigUtil.toNeighborAfiSafiAddPath(afiSafi, tableType, addPathCapabilities))).build());
182         neighborBuilder.setTransport(new TransportBuilder().setConfig(
183                 new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.transport.ConfigBuilder()
184                 .setPassiveMode(!isActive)
185                 .setMtuDiscovery(Boolean.FALSE)
186                 .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config2.class,
187                         new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev160614.Config2Builder()
188                 .setRemotePort(portNumber).build())
189                 .build()).build());
190         neighborBuilder.setConfig(
191                 new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
192                 .setAuthPassword(password != null ? password.getValue() : null)
193                 .setPeerAs(remoteAs)
194                 .setPeerType(toPeerTye(peerRole))
195                 .setSendCommunity(CommunityType.NONE)
196                 .setRouteFlapDamping(Boolean.FALSE)
197                 .build());
198         neighborBuilder.setTimers(new TimersBuilder().setConfig(
199                 new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.timers.ConfigBuilder()
200                 .setHoldTime(BigDecimal.valueOf(holdTimer))
201                 .setConnectRetry(BigDecimal.valueOf(retryTimer))
202                 .setKeepaliveInterval(DEFAULT_KEEP_ALIVE)
203                 .setMinimumAdvertisementInterval(DEFAULT_MINIMUM_ADV_INTERVAL)
204                 .build()).build());
205         neighborBuilder.setRouteReflector(new RouteReflectorBuilder().setConfig(
206                 new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.route.reflector.ConfigBuilder()
207                 .setRouteReflectorClient(peerRole == PeerRole.RrClient).build()).build());
208         return neighborBuilder.build();
209     }
210
211     private static PeerType toPeerTye(final PeerRole peerRole) {
212         switch (peerRole) {
213         case Ibgp:
214         case RrClient:
215             return PeerType.INTERNAL;
216         case Ebgp:
217             return PeerType.EXTERNAL;
218         case Internal:
219             break;
220         default:
221             break;
222         }
223         return null;
224     }
225
226     @Override
227     public Neighbor fromApplicationPeer(final ApplicationRibId applicationRibId, final BgpId bgpId) {
228         final NeighborBuilder neighborBuilder = new NeighborBuilder();
229         neighborBuilder.setNeighborAddress(new IpAddress(new Ipv4Address(bgpId.getValue())));
230         neighborBuilder.setKey(new NeighborKey(neighborBuilder.getNeighborAddress()));
231         neighborBuilder.setConfig(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder()
232         .setDescription(applicationRibId.getValue())
233         .addAugmentation(Config1.class, new Config1Builder().setPeerGroup(APPLICATION_PEER_GROUP_NAME).build())
234         .build());
235
236         return neighborBuilder.build();
237     }
238
239 }