2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.itm.rpc;
10 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
11 import static org.opendaylight.serviceutils.tools.rpc.FutureRpcResults.fromListenableFuture;
12 import static org.opendaylight.yangtools.yang.common.RpcResultBuilder.failed;
14 import com.google.common.base.Objects;
15 import com.google.common.util.concurrent.FluentFuture;
16 import com.google.common.util.concurrent.FutureCallback;
17 import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture;
19 import com.google.common.util.concurrent.MoreExecutors;
20 import com.google.common.util.concurrent.SettableFuture;
21 import java.math.BigInteger;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
28 import java.util.Optional;
29 import java.util.concurrent.ExecutionException;
30 import java.util.stream.Collectors;
31 import javax.annotation.PostConstruct;
32 import javax.annotation.PreDestroy;
33 import javax.inject.Inject;
34 import javax.inject.Singleton;
35 import org.eclipse.jdt.annotation.NonNull;
36 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
37 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
38 import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
39 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
40 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
41 import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
42 import org.opendaylight.genius.itm.cache.OfTepStateCache;
43 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
44 import org.opendaylight.genius.itm.cache.TunnelStateCache;
45 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
46 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelDeleteWorker;
47 import org.opendaylight.genius.itm.globals.ITMConstants;
48 import org.opendaylight.genius.itm.impl.ItmUtils;
49 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
50 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
51 import org.opendaylight.genius.mdsalutil.ActionInfo;
52 import org.opendaylight.genius.mdsalutil.MDSALUtil;
53 import org.opendaylight.genius.mdsalutil.MatchInfo;
54 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
55 import org.opendaylight.genius.mdsalutil.NwConstants;
56 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
57 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
58 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
59 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
60 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
61 import org.opendaylight.mdsal.binding.api.DataBroker;
62 import org.opendaylight.mdsal.binding.util.Datastore;
63 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
64 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
65 import org.opendaylight.mdsal.binding.util.RetryingManagedNewTransactionRunner;
66 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
67 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
68 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
69 import org.opendaylight.mdsal.common.api.ReadFailedException;
70 import org.opendaylight.serviceutils.tools.rpc.FutureRpcResults;
71 import org.opendaylight.serviceutils.tools.rpc.FutureRpcResults.LogLevel;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepsState;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTeps;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpns;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVteps;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVtepsBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVtepsKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointOutput;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceInput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceOutput;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceInput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceOutput;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsInput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsOutput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsInput;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsOutput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceInput;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceOutput;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceInput;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceOutput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnEndpointIpsInput;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnEndpointIpsOutput;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnEndpointIpsOutputBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoInput;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoOutput;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoOutputBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInput;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutputBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutputBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInput;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutput;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutputBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpInput;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpOutput;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpOutputBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInput;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeInput;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutput;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutputBuilder;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetWatchPortForTunnelInput;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetWatchPortForTunnelOutput;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInput;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutputBuilder;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalInput;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutput;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutputBuilder;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointOutput;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsInput;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsOutput;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInput;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsOutput;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.SetBfdParamOnTunnelInput;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.SetBfdParamOnTunnelOutput;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.get.dpn.info.output.Computes;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.get.dpn.info.output.ComputesBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
170 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
171 import org.opendaylight.yangtools.yang.common.OperationFailedException;
172 import org.opendaylight.yangtools.yang.common.RpcError;
173 import org.opendaylight.yangtools.yang.common.RpcResult;
174 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
175 import org.opendaylight.yangtools.yang.common.Uint16;
176 import org.opendaylight.yangtools.yang.common.Uint64;
177 import org.slf4j.Logger;
178 import org.slf4j.LoggerFactory;
181 public class ItmManagerRpcService implements ItmRpcService {
183 private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
185 private final DataBroker dataBroker;
186 private final IMdsalApiManager mdsalManager;
187 private final DPNTEPsInfoCache dpnTEPsInfoCache;
188 private final ItmExternalTunnelAddWorker externalTunnelAddWorker;
189 private final SingleTransactionDataBroker singleTransactionDataBroker;
190 private final IInterfaceManager interfaceManager;
191 private final InterfaceManagerService interfaceManagerService;
192 private final DpnTepStateCache dpnTepStateCache;
193 private final TunnelStateCache tunnelStateCache;
194 private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
195 private final DirectTunnelUtils directTunnelUtils;
196 private final ManagedNewTransactionRunner txRunner;
197 private final RetryingManagedNewTransactionRunner retryingTxRunner;
198 private final ItmConfig itmConfig;
199 private final OfDpnTepConfigCache ofDpnTepConfigCache;
200 private final OfTepStateCache ofTepStateCache;
203 public ItmManagerRpcService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
204 final ItmConfig itmConfig, final DPNTEPsInfoCache dpnTEPsInfoCache,
205 final IInterfaceManager interfaceManager, final DpnTepStateCache dpnTepStateCache,
206 final TunnelStateCache tunnelStateCache,
207 final InterfaceManagerService interfaceManagerService,
208 final OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
209 final DirectTunnelUtils directTunnelUtils, OfDpnTepConfigCache ofDpnTepConfigCache,
210 OfTepStateCache ofTepStateCache) {
211 this.dataBroker = dataBroker;
212 this.mdsalManager = mdsalManager;
213 this.dpnTEPsInfoCache = dpnTEPsInfoCache;
214 this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig, dpnTEPsInfoCache);
215 this.singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
216 this.interfaceManager = interfaceManager;
217 this.interfaceManagerService = interfaceManagerService;
218 this.dpnTepStateCache = dpnTepStateCache;
219 this.tunnelStateCache = tunnelStateCache;
220 this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
221 this.directTunnelUtils = directTunnelUtils;
222 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
223 this.retryingTxRunner = new RetryingManagedNewTransactionRunner(dataBroker);
224 this.itmConfig = itmConfig;
225 this.ofDpnTepConfigCache = ofDpnTepConfigCache;
226 this.ofTepStateCache = ofTepStateCache;
230 public void start() {
231 LOG.info("ItmManagerRpcService Started");
235 public void close() {
236 LOG.info("ItmManagerRpcService Closed");
240 public ListenableFuture<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(
241 GetTunnelInterfaceNameInput input) {
242 RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
243 Uint64 sourceDpn = input.getSourceDpid();
244 Uint64 destinationDpn = input.getDestinationDpid();
245 Optional<InternalTunnel> optTunnel = Optional.empty();
247 if (interfaceManager.isItmOfTunnelsEnabled()) {
248 //Destination DPN Id is not relevant in OF Tunnel scenario and so is ignored
250 Optional<OfDpnTep> dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava());
251 if (dpnstep.isPresent()) {
252 resultBld = RpcResultBuilder.success();
253 resultBld.withResult(new GetTunnelInterfaceNameOutputBuilder()
254 .setInterfaceName(dpnstep.get().getOfPortName())).build();
255 return Futures.immediateFuture(resultBld.build());
257 LOG.error("OF tunnel is not available in ITM for source dpn {}", sourceDpn);
258 resultBld = RpcResultBuilder.failed();
259 return Futures.immediateFuture(resultBld.build());
261 } catch (ReadFailedException e) {
262 LOG.error("ReadFailedException: cache read failed for source dpn {} reason: {}", sourceDpn,
264 resultBld = RpcResultBuilder.failed();
265 return Futures.immediateFuture(resultBld.build());
268 if (interfaceManager.isItmDirectTunnelsEnabled()) {
269 DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getDpnTepInterface(sourceDpn, destinationDpn);
270 if (interfaceInfo != null) {
271 resultBld = RpcResultBuilder.success();
272 resultBld.withResult(new GetTunnelInterfaceNameOutputBuilder()
273 .setInterfaceName(interfaceInfo.getTunnelName())).build();
274 return Futures.immediateFuture(resultBld.build());
277 if (ItmUtils.isTunnelAggregationUsed(input.getTunnelType())) {
278 optTunnel = ItmUtils.getInternalTunnelFromDS(sourceDpn, destinationDpn,
279 TunnelTypeLogicalGroup.class, dataBroker);
280 LOG.debug("MULTIPLE_VxLAN_TUNNELS: getTunnelInterfaceName {}", optTunnel);
282 if (!optTunnel.isPresent()) {
283 optTunnel = ItmUtils.getInternalTunnelFromDS(sourceDpn, destinationDpn, input.getTunnelType(), dataBroker);
285 if (optTunnel.isPresent()) {
286 InternalTunnel tunnel = optTunnel.get();
287 GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
288 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
289 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
290 output.setInterfaceName(tunnelInterfaces.get(0));
291 resultBld = RpcResultBuilder.success();
292 resultBld.withResult(output.build());
294 resultBld = failed();
298 resultBld = failed();
300 return Futures.immediateFuture(resultBld.build());
304 public ListenableFuture<RpcResult<GetEgressActionsForTunnelOutput>>
305 getEgressActionsForTunnel(GetEgressActionsForTunnelInput input) {
306 String tunnelName = input.getIntfName();
307 if (tunnelName == null) {
308 return Futures.immediateFuture(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
309 .withError(RpcError.ErrorType.APPLICATION,
310 "tunnel name not set for GetEgressActionsForTunnel call").build());
312 if (tunnelName.startsWith("of")
313 || (interfaceManager.isItmDirectTunnelsEnabled() && dpnTepStateCache.isInternal(tunnelName))) {
314 return fromListenableFuture(LOG, input, () -> getEgressActionsForInternalTunnels(input.getIntfName(),
315 input.getTunnelKey() != null ? input.getTunnelKey().toJava() : null,
316 input.getActionKey())).onFailureLogLevel(LogLevel.ERROR).build();
318 // Re-direct the RPC to Interface Manager
319 // From the rpc input and get the output and copy to output
320 org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
321 .GetEgressActionsForInterfaceInputBuilder inputIfmBuilder =
322 new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
323 .GetEgressActionsForInterfaceInputBuilder().setIntfName(input.getIntfName())
324 .setTunnelKey(input.getTunnelKey()).setActionKey(input.getActionKey());
325 SettableFuture<RpcResult<GetEgressActionsForTunnelOutput>> settableFuture = SettableFuture.create();
326 Futures.addCallback(interfaceManagerService.getEgressActionsForInterface(inputIfmBuilder.build()),
327 new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
328 .interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput>() {
330 public void onSuccess(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs
331 .rev160406.@NonNull GetEgressActionsForInterfaceOutput result) {
332 GetEgressActionsForTunnelOutputBuilder output =
333 new GetEgressActionsForTunnelOutputBuilder().setAction(result.getAction());
334 settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>success()
335 .withResult(output.build()).build());
339 public void onFailure(Throwable throwable) {
340 LOG.debug("RPC Call to Get egress actions failed for interface {}", tunnelName);
341 String errMsg = String.format("RPC call to get egress actions failed for interface %s",
343 settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
344 .withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
346 } ,MoreExecutors.directExecutor());
347 return settableFuture;
352 public ListenableFuture<RpcResult<GetTunnelTypeOutput>> getTunnelType(GetTunnelTypeInput input) {
353 String tunnelName = input.getIntfName();
354 if (tunnelName == null) {
355 return Futures.immediateFuture(RpcResultBuilder.<GetTunnelTypeOutput>failed()
356 .withError(RpcError.ErrorType.APPLICATION,
357 "tunnel name not set for getTunnelType call").build());
360 if (!dpnTepStateCache.isInternal(tunnelName) || !interfaceManager.isItmDirectTunnelsEnabled()) {
361 org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
362 .GetTunnelTypeInputBuilder inputBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight
363 .genius.interfacemanager.rpcs.rev160406.GetTunnelTypeInputBuilder()
364 .setIntfName(input.getIntfName());
365 SettableFuture<RpcResult<GetTunnelTypeOutput>> settableFuture = SettableFuture.create();
366 Futures.addCallback(interfaceManagerService.getTunnelType(inputBuilder.build()),
367 new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
368 .interfacemanager.rpcs.rev160406.GetTunnelTypeOutput>() {
370 public void onSuccess(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs
371 .rev160406.@NonNull GetTunnelTypeOutput result) {
372 GetTunnelTypeOutputBuilder output = new GetTunnelTypeOutputBuilder()
373 .setTunnelType(result.getTunnelType());
374 settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>success()
375 .withResult(output.build()).build());
379 public void onFailure(Throwable throwable) {
380 LOG.debug("RPC Call to Get tunnel type failed for interface {}", tunnelName);
381 String errMsg = String.format("RPC to Get tunnel type failed for interface %s",
383 settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>failed()
384 .withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
386 },MoreExecutors.directExecutor());
387 return settableFuture;
389 LOG.debug("get tunnel type from ITM for interface name {}", input.getIntfName());
390 return FutureRpcResults.fromBuilder(LOG, input, () -> {
391 DpnTepInterfaceInfo ifInfo = dpnTepStateCache.getTunnelFromCache(input.getIntfName());
392 return new GetTunnelTypeOutputBuilder().setTunnelType(ifInfo.getTunnelType());
398 public ListenableFuture<RpcResult<SetBfdParamOnTunnelOutput>> setBfdParamOnTunnel(
399 SetBfdParamOnTunnelInput input) {
400 final Uint64 srcDpnId = Uint64.valueOf(input.getSourceNode());
401 final Uint64 destDpnId = Uint64.valueOf(input.getDestinationNode());
402 LOG.debug("setBfdParamOnTunnel srcDpnId: {}, destDpnId: {}", srcDpnId, destDpnId);
403 final SettableFuture<RpcResult<SetBfdParamOnTunnelOutput>> result = SettableFuture.create();
404 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
405 enableBFD(tx, srcDpnId, destDpnId, input.isMonitoringEnabled(), input.getMonitoringInterval().toJava());
406 enableBFD(tx, destDpnId, srcDpnId, input.isMonitoringEnabled(), input.getMonitoringInterval().toJava());
409 future.addCallback(new FutureCallback<Object>() {
411 public void onSuccess(Object voidInstance) {
412 result.set(RpcResultBuilder.<SetBfdParamOnTunnelOutput>success().build());
416 public void onFailure(Throwable error) {
417 String msg = "Unable to remove external tunnel from DPN";
418 LOG.error("remove ext tunnel failed. {}.", msg, error);
419 result.set(RpcResultBuilder.<SetBfdParamOnTunnelOutput>failed()
420 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
422 }, MoreExecutors.directExecutor());
426 private void enableBFD(TypedWriteTransaction<Datastore.Configuration> tx, Uint64 srcDpnId, Uint64 destDpnId,
427 final Boolean enabled, final Integer interval) throws ReadFailedException {
428 DpnTepInterfaceInfo dpnTepInterfaceInfo = dpnTepStateCache.getDpnTepInterface(srcDpnId, destDpnId);
429 RemoteDpnsBuilder remoteDpnsBuilder = new RemoteDpnsBuilder();
430 remoteDpnsBuilder.withKey(new RemoteDpnsKey(destDpnId)).setDestinationDpnId(destDpnId)
431 .setTunnelName(dpnTepInterfaceInfo.getTunnelName()).setInternal(dpnTepInterfaceInfo.isInternal())
432 .setMonitoringEnabled(enabled);
433 if (enabled && interval != null) {
434 remoteDpnsBuilder.setMonitoringInterval(interval);
436 RemoteDpns remoteDpn = remoteDpnsBuilder.build();
437 Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(srcDpnId);
438 LOG.debug("setBfdParamOnTunnel TunnelName: {}, ovsBridgeRefEntry: {}", dpnTepInterfaceInfo.getTunnelName(),
440 directTunnelUtils.updateBfdConfiguration(srcDpnId, remoteDpn, ovsBridgeRefEntry);
441 InstanceIdentifier<RemoteDpns> iid = InstanceIdentifier.builder(DpnTepsState.class)
442 .child(DpnsTeps.class, new DpnsTepsKey(srcDpnId))
443 .child(RemoteDpns.class,
444 new RemoteDpnsKey(destDpnId)).build();
445 tx.mergeParentStructureMerge(iid, remoteDpn);
449 public ListenableFuture<RpcResult<RemoveExternalTunnelEndpointOutput>> removeExternalTunnelEndpoint(
450 RemoveExternalTunnelEndpointInput input) {
451 //Ignore the Futures for now
452 final SettableFuture<RpcResult<RemoveExternalTunnelEndpointOutput>> result = SettableFuture.create();
453 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
454 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
456 ItmExternalTunnelDeleteWorker.deleteTunnels(meshedDpnList, input.getDestinationIp(),
457 input.getTunnelType(), tx);
458 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
459 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
463 future.addCallback(new FutureCallback<Object>() {
464 @Override public void onSuccess(Object voidInstance) {
465 result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>success().build());
468 @Override public void onFailure(Throwable error) {
469 String msg = "Unable to delete DcGatewayIp " + input.getDestinationIp()
470 + " in datastore and tunnel type " + input.getTunnelType();
471 LOG.error("Unable to delete DcGatewayIp {} in datastore and tunnel type {}", input.getDestinationIp(),
472 input.getTunnelType());
473 result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>failed()
474 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
476 }, MoreExecutors.directExecutor());
481 public ListenableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> removeExternalTunnelFromDpns(
482 RemoveExternalTunnelFromDpnsInput input) {
483 //Ignore the Futures for now
484 final SettableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
485 List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dpnTEPsInfoCache, input.getDpnId());
486 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
487 tx -> ItmExternalTunnelDeleteWorker.deleteTunnels(cfgDpnList, input.getDestinationIp(),
488 input.getTunnelType(), tx));
490 future.addCallback(new FutureCallback<Object>() {
492 public void onSuccess(Object voidInstance) {
493 result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>success().build());
497 public void onFailure(Throwable error) {
498 String msg = "Unable to remove external tunnel from DPN";
499 LOG.error("remove ext tunnel failed. {}.", msg, error);
500 result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>failed()
501 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
503 }, MoreExecutors.directExecutor());
508 public ListenableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> buildExternalTunnelFromDpns(
509 BuildExternalTunnelFromDpnsInput input) {
510 //Ignore the Futures for now
511 final SettableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
512 FluentFuture<?> extTunnelResultList =
513 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
514 tx -> externalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(input.getDpnId(),
515 input.getDestinationIp(),input.getTunnelType(), tx));
517 extTunnelResultList.addCallback(new FutureCallback<Object>() {
519 public void onSuccess(Object voidInstance) {
520 result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>success().build());
524 public void onFailure(Throwable error) {
525 String msg = "Unable to create ext tunnel";
526 LOG.error("create ext tunnel failed. {}.", msg, error);
527 result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>failed()
528 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
530 }, MoreExecutors.directExecutor());
535 public ListenableFuture<RpcResult<AddExternalTunnelEndpointOutput>> addExternalTunnelEndpoint(
536 AddExternalTunnelEndpointInput input) {
537 // TODO Auto-generated method stub
539 //Ignore the Futures for now
540 final SettableFuture<RpcResult<AddExternalTunnelEndpointOutput>> result = SettableFuture.create();
541 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
542 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
543 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
544 DcGatewayIp dcGatewayIp =
545 new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp())
546 .setTunnnelType(input.getTunnelType()).build();
548 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
550 externalTunnelAddWorker.buildTunnelsToExternalEndPoint(meshedDpnList, input.getDestinationIp(),
551 input.getTunnelType(), tx);
552 tx.mergeParentStructurePut(extPath, dcGatewayIp);
555 future.addCallback(new FutureCallback<Object>() {
556 @Override public void onSuccess(Object voidInstance) {
557 result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>success().build());
560 @Override public void onFailure(Throwable error) {
562 "Unable to create DcGatewayIp {} in datastore for ip " + input.getDestinationIp() + "and "
563 + "tunnel type " + input.getTunnelType();
565 LOG.error("Unable to create DcGatewayIp in datastore for ip {} and tunnel type {}",
566 input.getDestinationIp() , input.getTunnelType());
567 result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>failed()
568 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
570 }, MoreExecutors.directExecutor());
575 public ListenableFuture<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
576 GetExternalTunnelInterfaceNameInput input) {
577 SettableFuture.create();
578 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
579 String sourceNode = input.getSourceNode();
580 String dstNode = input.getDestinationNode();
581 if (interfaceManager.isItmOfTunnelsEnabled()) {
582 Optional<OfDpnTep> tepDetail;
584 tepDetail = ofDpnTepConfigCache.get(new BigInteger(sourceNode));
585 } catch (ReadFailedException e) {
586 LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for "
587 + "source dpn {} reason: {}", sourceNode, e.getMessage());
588 resultBld = failed();
589 return Futures.immediateFuture(resultBld.build());
591 if (tepDetail.isPresent()) {
592 GetExternalTunnelInterfaceNameOutputBuilder output =
593 new GetExternalTunnelInterfaceNameOutputBuilder()
594 .setInterfaceName(tepDetail.get().getOfPortName());
595 resultBld = RpcResultBuilder.success();
596 resultBld.withResult(output.build());
597 return Futures.immediateFuture(resultBld.build());
599 LOG.error("OF tunnel interface is not available in config DS for source dpn {}", sourceNode);
600 resultBld = failed();
601 return Futures.immediateFuture(resultBld.build());
604 ExternalTunnelKey externalTunnelKey = new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType());
605 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
606 ExternalTunnelList.class)
607 .child(ExternalTunnel.class, externalTunnelKey);
608 ExternalTunnel exTunnel =
609 ItmUtils.getExternalTunnelbyExternalTunnelKey(externalTunnelKey, path, this.dataBroker);
610 if (exTunnel != null) {
611 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder();
612 output.setInterfaceName(exTunnel.getTunnelInterfaceName());
613 resultBld = RpcResultBuilder.success();
614 resultBld.withResult(output.build());
616 resultBld = failed();
619 return Futures.immediateFuture(resultBld.build());
623 public ListenableFuture<RpcResult<CreateTerminatingServiceActionsOutput>>
624 createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
625 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}",
626 input.getDpnId() , input.getServiceId(), input.getInstruction());
627 final SettableFuture<RpcResult<CreateTerminatingServiceActionsOutput>> result = SettableFuture.create();
628 Uint16 serviceId = input.getServiceId();
629 final List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
631 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
632 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, serviceId), 5,
633 "ITM Flow Entry :" + serviceId, 0, 0,
634 Uint64.fromLongBits(ITMConstants.COOKIE_ITM.longValue() + serviceId.toJava()), mkMatches,
635 input.getInstruction());
637 ListenableFuture<?> installFlowResult = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
638 tx -> mdsalManager.addFlow(tx, input.getDpnId(), terminatingServiceTableFlow));
639 Futures.addCallback(installFlowResult, new FutureCallback<Object>() {
642 public void onSuccess(Object voidInstance) {
643 result.set(RpcResultBuilder.<CreateTerminatingServiceActionsOutput>success().build());
647 public void onFailure(Throwable error) {
648 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
649 LOG.error("create terminating service actions failed. {}", msg, error);
650 result.set(RpcResultBuilder.<CreateTerminatingServiceActionsOutput>failed()
651 .withError(RpcError.ErrorType.APPLICATION, msg, error)
654 }, MoreExecutors.directExecutor());
655 // result.set(RpcResultBuilder.<Void>success().build());
660 public ListenableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>>
661 removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
662 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}",
663 input.getDpnId(), input.getServiceId());
664 final SettableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>> result = SettableFuture.create();
666 ListenableFuture<?> removeFlowResult = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
667 tx -> mdsalManager.removeFlow(tx, input.getDpnId(),
668 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, input.getServiceId()),
669 NwConstants.INTERNAL_TUNNEL_TABLE));
670 Futures.addCallback(removeFlowResult, new FutureCallback<Object>() {
673 public void onSuccess(Object voidInstance) {
674 result.set(RpcResultBuilder.<RemoveTerminatingServiceActionsOutput>success().build());
678 public void onFailure(Throwable error) {
679 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
680 LOG.error("remove terminating service actions failed. {}", msg, error);
681 result.set(RpcResultBuilder.<RemoveTerminatingServiceActionsOutput>failed()
682 .withError(RpcError.ErrorType.APPLICATION, msg, error)
685 }, MoreExecutors.directExecutor());
686 //result.set(RpcResultBuilder.<Void>success().build());
691 public List<MatchInfo> getTunnelMatchesForServiceId(Uint16 serviceId) {
692 final List<MatchInfo> mkMatches = new ArrayList<>();
695 mkMatches.add(new MatchTunnelId(Uint64.valueOf(serviceId)));
700 private String getFlowRef(long termSvcTable, Uint16 svcId) {
701 return String.valueOf(termSvcTable) + svcId;
705 public ListenableFuture<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
706 GetInternalOrExternalInterfaceNameInput input) {
707 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = failed();
708 Uint64 srcDpn = input.getSourceDpid();
709 IpAddress dstIp = input.getDestinationIp();
710 if (interfaceManager.isItmOfTunnelsEnabled()) {
711 Optional<OfDpnTep> tepDetail;
713 tepDetail = ofDpnTepConfigCache.get(srcDpn.toJava());
714 } catch (ReadFailedException e) {
715 LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for "
716 + "source dpn {} reason: {}", srcDpn, e.getMessage());
717 return Futures.immediateFuture(resultBld.build());
719 if (tepDetail.isPresent()) {
720 GetInternalOrExternalInterfaceNameOutputBuilder output =
721 new GetInternalOrExternalInterfaceNameOutputBuilder()
722 .setInterfaceName(tepDetail.get().getOfPortName());
723 resultBld = RpcResultBuilder.success();
724 resultBld.withResult(output.build());
725 return Futures.immediateFuture(resultBld.build());
727 LOG.error("OF tunnel interface is not available in config DS for source dpn {}", srcDpn);
728 return Futures.immediateFuture(resultBld.build());
731 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
732 .child(ExternalTunnel.class,
733 new ExternalTunnelKey(dstIp.stringValue(), srcDpn.toString(), input.getTunnelType()));
735 Optional<ExternalTunnel> optExtTunnel = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
737 if (optExtTunnel != null && optExtTunnel.isPresent()) {
738 ExternalTunnel extTunnel = optExtTunnel.get();
739 GetInternalOrExternalInterfaceNameOutputBuilder output =
740 new GetInternalOrExternalInterfaceNameOutputBuilder()
741 .setInterfaceName(extTunnel.getTunnelInterfaceName());
742 resultBld = RpcResultBuilder.success();
743 resultBld.withResult(output.build()) ;
745 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
747 // Look for external tunnels if not look for internal tunnel
748 for (DPNTEPsInfo teps : meshedDpnList) {
749 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
750 if (dstIp.equals(firstEndPt.getIpAddress())) {
751 Optional<InternalTunnel> optTunnel = Optional.empty();
752 if (interfaceManager.isItmDirectTunnelsEnabled()) {
753 DpnTepInterfaceInfo interfaceInfo =
754 dpnTepStateCache.getDpnTepInterface(srcDpn, teps.getDPNID());
755 if (interfaceInfo != null) {
756 resultBld = RpcResultBuilder.success();
757 resultBld.withResult(new GetInternalOrExternalInterfaceNameOutputBuilder()
758 .setInterfaceName(interfaceInfo.getTunnelName())).build();
759 return Futures.immediateFuture(resultBld.build());
763 if (ItmUtils.isTunnelAggregationUsed(input.getTunnelType())) {
764 optTunnel = ItmUtils.getInternalTunnelFromDS(srcDpn, teps.getDPNID(),
765 TunnelTypeLogicalGroup.class, dataBroker);
766 LOG.debug("MULTIPLE_VxLAN_TUNNELS: getInternalOrExternalInterfaceName {}", optTunnel);
768 if (!optTunnel.isPresent()) {
769 optTunnel = ItmUtils.getInternalTunnelFromDS(srcDpn, teps.getDPNID(),
770 input.getTunnelType(), dataBroker);
772 if (optTunnel.isPresent()) {
773 InternalTunnel tunnel = optTunnel.get();
774 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
775 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
776 GetInternalOrExternalInterfaceNameOutputBuilder
778 new GetInternalOrExternalInterfaceNameOutputBuilder()
779 .setInterfaceName(tunnelInterfaces.get(0));
780 resultBld = RpcResultBuilder.success();
781 resultBld.withResult(output.build());
783 LOG.error("No tunnel interface found between source DPN {} ans destination IP {}", srcDpn,
788 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
793 return Futures.immediateFuture(resultBld.build());
796 @SuppressWarnings("checkstyle:IllegalCatch")
798 public ListenableFuture<RpcResult<DeleteL2GwDeviceOutput>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
799 final SettableFuture<RpcResult<DeleteL2GwDeviceOutput>> result = SettableFuture.create();
800 boolean foundVxlanTzone = false;
802 final IpAddress hwIp = input.getIpAddress();
803 final String nodeId = input.getNodeId();
804 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
805 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
806 containerPath, dataBroker);
807 if (transportZonesOptional.isPresent()) {
808 TransportZones transportZones = transportZonesOptional.get();
809 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
810 LOG.error("No teps configured");
811 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
812 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
815 for (TransportZone tzone : transportZones.getTransportZone()) {
816 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
819 foundVxlanTzone = true;
820 String transportZone = tzone.getZoneName();
821 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
822 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier
823 .builder(TransportZones.class)
824 .child(TransportZone.class,
825 new TransportZoneKey(transportZone))
826 .child(DeviceVteps.class, deviceVtepKey)
828 FluentFuture<?> future =
829 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(path));
830 future.addCallback(new FutureCallback<Object>() {
831 @Override public void onSuccess(Object voidInstance) {
832 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>success().build());
835 @Override public void onFailure(Throwable error) {
836 String msg = String.format("Unable to delete HwVtep %s from datastore", nodeId);
837 LOG.error("Unable to delete HwVtep {}, {} from datastore", nodeId, hwIp);
838 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
839 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
841 }, MoreExecutors.directExecutor());
844 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
845 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
849 if (!foundVxlanTzone) {
850 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
851 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
856 } catch (Exception e) {
857 RpcResultBuilder<DeleteL2GwDeviceOutput> resultBuilder = RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
858 .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
859 return Futures.immediateFuture(resultBuilder.build());
863 @SuppressWarnings("checkstyle:IllegalCatch")
865 public ListenableFuture<RpcResult<AddL2GwDeviceOutput>> addL2GwDevice(AddL2GwDeviceInput input) {
867 final SettableFuture<RpcResult<AddL2GwDeviceOutput>> result = SettableFuture.create();
868 boolean foundVxlanTzone = false;
870 final IpAddress hwIp = input.getIpAddress();
871 final String nodeId = input.getNodeId();
872 //iterate through all transport zones and put TORs under vxlan
873 //if no vxlan tzone is cnfigured, return an error.
874 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
875 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
876 containerPath, dataBroker);
877 if (transportZonesOptional.isPresent()) {
878 TransportZones transportZones = transportZonesOptional.get();
879 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
880 LOG.error("No transportZone configured");
881 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
882 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
885 for (TransportZone tzone : transportZones.getTransportZone()) {
886 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
889 String transportZone = tzone.getZoneName();
890 foundVxlanTzone = true;
891 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
892 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier
893 .builder(TransportZones.class)
894 .child(TransportZone.class,
895 new TransportZoneKey(transportZone))
896 .child(DeviceVteps.class, deviceVtepKey)
898 DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey).setIpAddress(hwIp)
899 .setNodeId(nodeId).setTopologyId(input.getTopologyId()).build();
900 //TO DO: add retry if it fails
901 FluentFuture<?> future = retryingTxRunner
902 .callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
903 tx -> tx.mergeParentStructurePut(path, deviceVtep));
905 future.addCallback(new FutureCallback<Object>() {
907 @Override public void onSuccess(Object voidInstance) {
908 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>success().build());
911 @Override public void onFailure(Throwable error) {
912 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
913 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
914 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
915 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
917 }, MoreExecutors.directExecutor());
921 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
922 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
926 if (!foundVxlanTzone) {
927 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
928 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
933 } catch (Exception e) {
934 RpcResultBuilder<AddL2GwDeviceOutput> resultBuilder = RpcResultBuilder.<AddL2GwDeviceOutput>failed()
935 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
936 return Futures.immediateFuture(resultBuilder.build());
941 public ListenableFuture<RpcResult<GetWatchPortForTunnelOutput>> getWatchPortForTunnel(
942 GetWatchPortForTunnelInput input) {
943 throw new UnsupportedOperationException("TODO");
946 public ListenableFuture<RpcResult<GetTepIpOutput>> getTepIp(GetTepIpInput input) {
947 RpcResultBuilder<GetTepIpOutput> resultBld;
948 Uint64 sourceDpn = input.getDpnId();
949 Optional<OfDpnTep> dpnstep;
951 dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava());
952 } catch (ReadFailedException e) {
953 LOG.error("ReadFailedException: OF tunnel is not available in ITM for source dpn {} reason: {}",sourceDpn,
955 resultBld = RpcResultBuilder.failed();
956 return Futures.immediateFuture(resultBld.build());
958 if (dpnstep.isPresent()) {
959 resultBld = RpcResultBuilder.success();
960 resultBld.withResult(new GetTepIpOutputBuilder()
961 .setTepIp(dpnstep.get().getTepIp())).build();
962 return Futures.immediateFuture(resultBld.build());
964 LOG.error("OF tunnel is not available in ITM for source dpn {}",sourceDpn);
965 resultBld = RpcResultBuilder.failed();
966 return Futures.immediateFuture(resultBld.build());
970 @SuppressWarnings("checkstyle:IllegalCatch")
972 public ListenableFuture<RpcResult<AddL2GwMlagDeviceOutput>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input) {
974 final SettableFuture<RpcResult<AddL2GwMlagDeviceOutput>> result = SettableFuture.create();
976 final IpAddress hwIp = input.getIpAddress();
977 final List<String> nodeId = input.getNodeId();
978 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
979 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
980 containerPath, dataBroker);
981 if (transportZonesOptional.isPresent()) {
982 TransportZones transportZones = transportZonesOptional.get();
983 if (transportZones.getTransportZone() == null || transportZones.getTransportZone()
985 LOG.error("No teps configured");
986 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
987 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
990 for (TransportZone tzone : transportZones.getTransportZone()) {
991 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
994 String transportZone = tzone.getZoneName();
995 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
996 InstanceIdentifier<DeviceVteps> path =
997 InstanceIdentifier.builder(TransportZones.class)
998 .child(TransportZone.class, new TransportZoneKey(transportZone))
999 .child(DeviceVteps.class, deviceVtepKey).build();
1000 DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey)
1002 .setNodeId(nodeId.get(0)).setTopologyId(input.getTopologyId()).build();
1003 LOG.trace("writing hWvtep{}", deviceVtep);
1004 FluentFuture<?> future =
1005 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
1007 tx.mergeParentStructurePut(path, deviceVtep);
1008 if (nodeId.size() == 2) {
1009 LOG.trace("second node-id {}", nodeId.get(1));
1010 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp,
1012 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier
1013 .builder(TransportZones.class)
1014 .child(TransportZone.class, new TransportZoneKey(transportZone))
1015 .child(DeviceVteps.class, deviceVtepKey2).build();
1016 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder()
1017 .withKey(deviceVtepKey2)
1018 .setIpAddress(hwIp).setNodeId(nodeId.get(1))
1019 .setTopologyId(input.getTopologyId()).build();
1020 LOG.trace("writing {}", deviceVtep2);
1021 tx.mergeParentStructurePut(path2, deviceVtep2);
1024 future.addCallback(new FutureCallback<Object>() {
1026 public void onSuccess(Object voidInstance) {
1027 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>success().build());
1031 public void onFailure(Throwable error) {
1033 .format("Unable to write HwVtep %s to datastore", nodeId);
1034 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
1035 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
1036 .withError(RpcError.ErrorType.APPLICATION, msg, error)
1039 }, MoreExecutors.directExecutor());
1043 } catch (RuntimeException e) {
1044 RpcResultBuilder<AddL2GwMlagDeviceOutput> resultBuilder = RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
1045 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
1046 return Futures.immediateFuture(resultBuilder.build());
1050 @SuppressWarnings("checkstyle:IllegalCatch")
1052 public ListenableFuture<RpcResult<DeleteL2GwMlagDeviceOutput>> deleteL2GwMlagDevice(
1053 DeleteL2GwMlagDeviceInput input) {
1054 final SettableFuture<RpcResult<DeleteL2GwMlagDeviceOutput>> result = SettableFuture.create();
1056 final IpAddress hwIp = input.getIpAddress();
1057 final List<String> nodeId = input.getNodeId();
1058 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
1059 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1060 containerPath, dataBroker);
1061 if (transportZonesOptional.isPresent()) {
1062 TransportZones tzones = transportZonesOptional.get();
1063 if (tzones.getTransportZone() == null || tzones.getTransportZone().isEmpty()) {
1064 LOG.error("No teps configured");
1065 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed()
1066 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
1069 String transportZone = tzones.getTransportZone().get(0).getZoneName();
1070 FluentFuture<?> future =
1071 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
1073 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
1074 InstanceIdentifier<DeviceVteps> path =
1075 InstanceIdentifier.builder(TransportZones.class)
1076 .child(TransportZone.class, new TransportZoneKey(transportZone))
1077 .child(DeviceVteps.class,
1078 deviceVtepKey).build();
1080 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
1081 InstanceIdentifier<DeviceVteps> path2 =
1082 InstanceIdentifier.builder(TransportZones.class)
1083 .child(TransportZone.class, new TransportZoneKey(transportZone))
1084 .child(DeviceVteps.class,
1085 deviceVtepKey2).build();
1090 future.addCallback(new FutureCallback<Object>() {
1093 public void onSuccess(Object voidInstance) {
1094 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>success().build());
1098 public void onFailure(Throwable error) {
1099 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
1100 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
1101 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed()
1102 .withError(RpcError.ErrorType.APPLICATION, msg, error)
1105 }, MoreExecutors.directExecutor());
1108 } catch (Exception e) {
1109 RpcResultBuilder<DeleteL2GwMlagDeviceOutput> resultBuilder =
1110 RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed().withError(RpcError.ErrorType.APPLICATION,
1111 "Deleting l2 Gateway to DS Failed", e);
1112 return Futures.immediateFuture(resultBuilder.build());
1117 public ListenableFuture<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
1118 IsTunnelInternalOrExternalInput input) {
1119 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
1120 String tunIfName = input.getTunnelInterfaceName();
1122 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder()
1123 .setTunnelType(tunVal);
1125 if (ItmUtils.ITM_CACHE.getInternalTunnel(tunIfName) != null) {
1127 } else if (ItmUtils.ITM_CACHE.getExternalTunnel(tunIfName) != null) {
1130 output.setTunnelType(tunVal);
1131 resultBld = RpcResultBuilder.success();
1132 resultBld.withResult(output.build());
1133 return Futures.immediateFuture(resultBld.build());
1137 public ListenableFuture<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
1138 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
1140 Map<DcGatewayIpKey, DcGatewayIp> dcGatewayIpList = new HashMap<>();
1141 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
1142 tx -> dcGatewayIpList.putAll(getDcGatewayIpList(tx))).isDone();
1143 String dcgwIpStr = input.getDcgwIp();
1144 IpAddress dcgwIpAddr = IpAddressBuilder.getDefaultInstance(dcgwIpStr);
1147 if (!dcGatewayIpList.isEmpty()
1148 && dcGatewayIpList.values().stream().anyMatch(gwIp -> Objects.equal(gwIp.getIpAddress(), dcgwIpAddr))) {
1151 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
1152 resultBld.withResult(output.build());
1156 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
1157 resultBld.withResult(output.build());
1159 return Futures.immediateFuture(resultBld.build());
1163 public ListenableFuture<RpcResult<GetDpnEndpointIpsOutput>> getDpnEndpointIps(GetDpnEndpointIpsInput input) {
1164 Uint64 srcDpn = input.getSourceDpid();
1165 RpcResultBuilder<GetDpnEndpointIpsOutput> resultBld = failed();
1166 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
1167 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
1168 new DPNTEPsInfoKey(srcDpn)).build();
1169 Optional<DPNTEPsInfo> tunnelInfo = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tunnelInfoId, dataBroker);
1170 if (!tunnelInfo.isPresent()) {
1171 LOG.error("tunnelInfo is not present");
1172 return Futures.immediateFuture(resultBld.build());
1175 List<TunnelEndPoints> tunnelEndPointList = tunnelInfo.get().getTunnelEndPoints();
1176 if (tunnelEndPointList == null || tunnelEndPointList.isEmpty()) {
1177 LOG.error("tunnelEndPointList is null or empty");
1178 return Futures.immediateFuture(resultBld.build());
1181 List<IpAddress> nexthopIpList = new ArrayList<>();
1182 tunnelEndPointList.forEach(tunnelEndPoint -> nexthopIpList.add(tunnelEndPoint.getIpAddress()));
1184 GetDpnEndpointIpsOutputBuilder output = new GetDpnEndpointIpsOutputBuilder().setNexthopipList(nexthopIpList);
1185 resultBld = RpcResultBuilder.success();
1186 resultBld.withResult(output.build()) ;
1187 return Futures.immediateFuture(resultBld.build());
1191 public ListenableFuture<RpcResult<GetDpnInfoOutput>> getDpnInfo(GetDpnInfoInput input) {
1192 return FutureRpcResults.fromListenableFuture(LOG, "getDpnInfo", input,
1193 () -> Futures.immediateFuture(getDpnInfoInternal(input))).build();
1196 private GetDpnInfoOutput getDpnInfoInternal(GetDpnInfoInput input) throws ReadFailedException {
1197 Map<String, Uint64> computeNamesVsDpnIds
1198 = getDpnIdByComputeNodeNameFromOpInventoryNodes(input.getComputeNames());
1199 Map<Uint64, ComputesBuilder> dpnIdVsVtepsComputes
1200 = getTunnelEndPointByDpnIdFromTranPortZone(computeNamesVsDpnIds.values());
1201 List<Computes> computes = computeNamesVsDpnIds.entrySet().stream()
1202 .map(entry -> dpnIdVsVtepsComputes.get(entry.getValue()).setComputeName(entry.getKey()).build())
1203 .collect(Collectors.toList());
1204 return new GetDpnInfoOutputBuilder().setComputes(computes).build();
1207 private Map<Uint64, ComputesBuilder> getTunnelEndPointByDpnIdFromTranPortZone(Collection<Uint64> dpnIds)
1208 throws ReadFailedException {
1209 TransportZones transportZones = singleTransactionDataBroker.syncRead(
1210 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(TransportZones.class).build());
1211 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
1212 throw new IllegalStateException("Failed to find transport zones in config datastore");
1214 Map<Uint64, ComputesBuilder> result = new HashMap<>();
1215 for (TransportZone transportZone : transportZones.getTransportZone()) {
1216 for (Vteps vtep : transportZone.getVteps().values()) {
1217 if (dpnIds.contains(vtep.getDpnId())) {
1218 result.putIfAbsent(vtep.getDpnId(),
1219 new ComputesBuilder()
1220 .setZoneName(transportZone.getZoneName())
1221 .setDpnId(vtep.getDpnId())
1222 .setNodeId(getNodeId(vtep.getDpnId()))
1223 .setTepIp(Collections.singletonList(vtep.getIpAddress())));
1227 for (Uint64 dpnId : dpnIds) {
1228 if (!result.containsKey(dpnId)) {
1229 throw new IllegalStateException("Failed to find dpn id " + dpnId + " in transport zone");
1235 private Map<String, Uint64> getDpnIdByComputeNodeNameFromOpInventoryNodes(List<String> nodeNames)
1236 throws ReadFailedException {
1237 Nodes operInventoryNodes = singleTransactionDataBroker.syncRead(
1238 LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(Nodes.class).build());
1239 if (operInventoryNodes.getNode() == null || operInventoryNodes.getNode().isEmpty()) {
1240 throw new IllegalStateException("Failed to find operational inventory nodes datastore");
1242 Map<String, Uint64> result = new HashMap<>();
1243 for (Node node : operInventoryNodes.getNode().values()) {
1244 String name = node.augmentation(FlowCapableNode.class).getDescription();
1245 if (nodeNames.contains(name)) {
1246 String[] nodeId = node.getId().getValue().split(":");
1247 result.put(name, Uint64.valueOf(nodeId[1]));
1250 for (String nodeName : nodeNames) {
1251 if (!result.containsKey(nodeName)) {
1252 throw new IllegalStateException("Failed to find dpn id of compute node name from oper inventory "
1259 private String getNodeId(Uint64 dpnId) throws ReadFailedException {
1260 InstanceIdentifier<BridgeRefEntry> path = InstanceIdentifier
1261 .builder(BridgeRefInfo.class)
1262 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId)).build();
1263 BridgeRefEntry bridgeRefEntry =
1264 singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, path);
1265 return bridgeRefEntry.getBridgeReference().getValue()
1266 .firstKeyOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
1267 .network.topology.topology.Node.class).getNodeId().getValue();
1270 private ListenableFuture<GetEgressActionsForTunnelOutput>
1271 getEgressActionsForInternalTunnels(String interfaceName, Long tunnelKey, Integer actionKey)
1272 throws ExecutionException, InterruptedException, OperationFailedException {
1274 if (interfaceName.startsWith("of")) {
1275 Optional<OfTep> oftep = ofTepStateCache.get(interfaceName);
1276 if (!oftep.isPresent()) {
1277 throw new IllegalStateException("Interface information not present in oper DS for" + interfaceName);
1279 List<ActionInfo> actions = getEgressActionInfosForOpenFlowTunnel(oftep.get().getIfIndex(),
1280 oftep.get().getTepIp(), tunnelKey, actionKey);
1281 return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
1282 .setAction(actions.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
1284 DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
1285 if (interfaceInfo == null) {
1286 throw new IllegalStateException("Interface information not present in config DS for" + interfaceName);
1289 String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType());
1290 if (!tunnelType.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_VXLAN)) {
1291 throw new IllegalArgumentException(tunnelType + " tunnel not handled by ITM");
1294 Optional<DPNTEPsInfo> dpntePsInfoOptional = dpnTEPsInfoCache.get(InstanceIdentifier
1295 .builder(DpnEndpoints.class)
1296 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(
1297 // FIXME: the cache should be caching this value, not just as a String
1298 Uint64.valueOf(dpnTepStateCache.getTunnelEndPointInfoFromCache(
1299 interfaceInfo.getTunnelName()).getDstEndPointInfo())))
1302 if (dpntePsInfoOptional.isPresent()) {
1303 dstId = dpntePsInfoOptional.get().getDstId();
1305 dstId = directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME,
1306 interfaceInfo.getRemoteDPN().toString());
1309 List<ActionInfo> result = new ArrayList<>();
1310 long regValue = MetaDataUtil.getRemoteDpnMetadatForEgressTunnelTable(dstId);
1311 int actionKeyStart = actionKey == null ? 0 : actionKey;
1312 result.add(new ActionSetFieldTunnelId(actionKeyStart++,
1313 Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L)));
1314 result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, MetaDataUtil.REG6_START_INDEX,
1315 MetaDataUtil.REG6_END_INDEX, regValue));
1316 result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_TUNNEL_TABLE));
1318 return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
1319 .setAction(result.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
1323 private static List<ActionInfo> getEgressActionInfosForOpenFlowTunnel(Uint16 ifIndex, IpAddress ipAddress,
1324 Long tunnelKey, Integer actionKey) {
1325 List<ActionInfo> result = new ArrayList<>();
1326 int actionKeyStart = actionKey == null ? 0 : actionKey;
1327 result.add(new ActionSetFieldTunnelId(actionKeyStart++,
1328 Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L)));
1329 long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex.intValue() ,
1330 NwConstants.DEFAULT_SERVICE_INDEX);
1331 result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, ITMConstants.REG6_START_INDEX,
1332 ITMConstants.REG6_END_INDEX, regValue));
1333 result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE));
1338 public static Map<DcGatewayIpKey, DcGatewayIp>
1339 getDcGatewayIpList(TypedReadWriteTransaction<Datastore.Configuration> tx)
1340 throws ExecutionException, InterruptedException {
1341 Map<DcGatewayIpKey, DcGatewayIp> dcGatewayIpMap = new HashMap<>();
1342 FluentFuture<Optional<DcGatewayIpList>> future =
1343 tx.read(InstanceIdentifier.builder(DcGatewayIpList.class).build());
1344 future.addCallback(new FutureCallback<Optional<DcGatewayIpList>>() {
1346 public void onSuccess(Optional<DcGatewayIpList> optional) {
1348 // FIXME: why not just use the provided optional?
1349 Optional<DcGatewayIpList> opt = future.get();
1350 if (opt.isPresent()) {
1351 DcGatewayIpList list = opt.get();
1353 dcGatewayIpMap.putAll(list.getDcGatewayIp());
1356 } catch (ExecutionException | InterruptedException e) {
1357 LOG.error("DcGateway IpList read failed", e);
1362 public void onFailure(Throwable error) {
1363 LOG.error("DcGateway IpList read failed", error);
1365 }, MoreExecutors.directExecutor());
1366 return dcGatewayIpMap;