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.util.concurrent.FluentFuture;
15 import com.google.common.util.concurrent.FutureCallback;
16 import com.google.common.util.concurrent.Futures;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import com.google.common.util.concurrent.MoreExecutors;
19 import com.google.common.util.concurrent.SettableFuture;
20 import java.math.BigInteger;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.List;
27 import java.util.Optional;
28 import java.util.concurrent.ExecutionException;
29 import java.util.stream.Collectors;
30 import javax.annotation.PostConstruct;
31 import javax.annotation.PreDestroy;
32 import javax.inject.Inject;
33 import javax.inject.Singleton;
34 import org.eclipse.jdt.annotation.NonNull;
35 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
36 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
37 import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
38 import org.opendaylight.genius.itm.cache.DPNTEPsInfoCache;
39 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
40 import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
41 import org.opendaylight.genius.itm.cache.OfTepStateCache;
42 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
43 import org.opendaylight.genius.itm.cache.TunnelStateCache;
44 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
45 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelDeleteWorker;
46 import org.opendaylight.genius.itm.globals.ITMConstants;
47 import org.opendaylight.genius.itm.impl.ItmUtils;
48 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
49 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
50 import org.opendaylight.genius.mdsalutil.ActionInfo;
51 import org.opendaylight.genius.mdsalutil.MDSALUtil;
52 import org.opendaylight.genius.mdsalutil.MatchInfo;
53 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
54 import org.opendaylight.genius.mdsalutil.NwConstants;
55 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
56 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
57 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldTunnelId;
58 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
59 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
60 import org.opendaylight.mdsal.binding.api.DataBroker;
61 import org.opendaylight.mdsal.binding.util.Datastore;
62 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
63 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
64 import org.opendaylight.mdsal.binding.util.RetryingManagedNewTransactionRunner;
65 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
66 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
67 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
68 import org.opendaylight.mdsal.common.api.ReadFailedException;
69 import org.opendaylight.serviceutils.tools.rpc.FutureRpcResults;
70 import org.opendaylight.serviceutils.tools.rpc.FutureRpcResults.LogLevel;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnTepsState;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTeps;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.DpnsTepsKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpns;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.teps.state.dpns.teps.RemoteDpnsKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpKey;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVteps;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVtepsBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVtepsKey;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointOutput;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceInput;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceOutput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceInput;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceOutput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsInput;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsOutput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsInput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsOutput;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceInput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceOutput;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceInput;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceOutput;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnEndpointIpsInput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnEndpointIpsOutput;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnEndpointIpsOutputBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoInput;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoOutput;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetDpnInfoOutputBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInput;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutputBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutputBuilder;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInput;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutput;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutputBuilder;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpInput;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpOutput;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTepIpOutputBuilder;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInput;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeInput;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutput;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelTypeOutputBuilder;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetWatchPortForTunnelInput;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetWatchPortForTunnelOutput;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInput;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutputBuilder;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalInput;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutput;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutputBuilder;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointOutput;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsInput;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsOutput;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInput;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsOutput;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.SetBfdParamOnTunnelInput;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.SetBfdParamOnTunnelOutput;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.get.dpn.info.output.Computes;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.get.dpn.info.output.ComputesBuilder;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
169 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
170 import org.opendaylight.yangtools.yang.common.OperationFailedException;
171 import org.opendaylight.yangtools.yang.common.RpcError;
172 import org.opendaylight.yangtools.yang.common.RpcResult;
173 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
174 import org.opendaylight.yangtools.yang.common.Uint16;
175 import org.opendaylight.yangtools.yang.common.Uint64;
176 import org.slf4j.Logger;
177 import org.slf4j.LoggerFactory;
180 public class ItmManagerRpcService implements ItmRpcService {
182 private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
184 private final DataBroker dataBroker;
185 private final IMdsalApiManager mdsalManager;
186 private final DPNTEPsInfoCache dpnTEPsInfoCache;
187 private final ItmExternalTunnelAddWorker externalTunnelAddWorker;
188 private final SingleTransactionDataBroker singleTransactionDataBroker;
189 private final IInterfaceManager interfaceManager;
190 private final InterfaceManagerService interfaceManagerService;
191 private final DpnTepStateCache dpnTepStateCache;
192 private final TunnelStateCache tunnelStateCache;
193 private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
194 private final DirectTunnelUtils directTunnelUtils;
195 private final ManagedNewTransactionRunner txRunner;
196 private final RetryingManagedNewTransactionRunner retryingTxRunner;
197 private final ItmConfig itmConfig;
198 private final OfDpnTepConfigCache ofDpnTepConfigCache;
199 private final OfTepStateCache ofTepStateCache;
202 public ItmManagerRpcService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
203 final ItmConfig itmConfig, final DPNTEPsInfoCache dpnTEPsInfoCache,
204 final IInterfaceManager interfaceManager, final DpnTepStateCache dpnTepStateCache,
205 final TunnelStateCache tunnelStateCache,
206 final InterfaceManagerService interfaceManagerService,
207 final OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
208 final DirectTunnelUtils directTunnelUtils, OfDpnTepConfigCache ofDpnTepConfigCache,
209 OfTepStateCache ofTepStateCache) {
210 this.dataBroker = dataBroker;
211 this.mdsalManager = mdsalManager;
212 this.dpnTEPsInfoCache = dpnTEPsInfoCache;
213 this.externalTunnelAddWorker = new ItmExternalTunnelAddWorker(itmConfig, dpnTEPsInfoCache);
214 this.singleTransactionDataBroker = new SingleTransactionDataBroker(dataBroker);
215 this.interfaceManager = interfaceManager;
216 this.interfaceManagerService = interfaceManagerService;
217 this.dpnTepStateCache = dpnTepStateCache;
218 this.tunnelStateCache = tunnelStateCache;
219 this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
220 this.directTunnelUtils = directTunnelUtils;
221 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
222 this.retryingTxRunner = new RetryingManagedNewTransactionRunner(dataBroker);
223 this.itmConfig = itmConfig;
224 this.ofDpnTepConfigCache = ofDpnTepConfigCache;
225 this.ofTepStateCache = ofTepStateCache;
229 public void start() {
230 LOG.info("ItmManagerRpcService Started");
234 public void close() {
235 LOG.info("ItmManagerRpcService Closed");
239 public ListenableFuture<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(
240 GetTunnelInterfaceNameInput input) {
241 RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
242 Uint64 sourceDpn = input.getSourceDpid();
243 Uint64 destinationDpn = input.getDestinationDpid();
244 Optional<InternalTunnel> optTunnel = Optional.empty();
246 if (interfaceManager.isItmOfTunnelsEnabled()) {
247 //Destination DPN Id is not relevant in OF Tunnel scenario and so is ignored
249 Optional<OfDpnTep> dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava());
250 if (dpnstep.isPresent()) {
251 resultBld = RpcResultBuilder.success();
252 resultBld.withResult(new GetTunnelInterfaceNameOutputBuilder()
253 .setInterfaceName(dpnstep.get().getOfPortName())).build();
254 return Futures.immediateFuture(resultBld.build());
256 LOG.error("OF tunnel is not available in ITM for source dpn {}", sourceDpn);
257 resultBld = RpcResultBuilder.failed();
258 return Futures.immediateFuture(resultBld.build());
260 } catch (ReadFailedException e) {
261 LOG.error("ReadFailedException: cache read failed for source dpn {} reason: {}", sourceDpn,
263 resultBld = RpcResultBuilder.failed();
264 return Futures.immediateFuture(resultBld.build());
267 if (interfaceManager.isItmDirectTunnelsEnabled()) {
268 DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getDpnTepInterface(sourceDpn, destinationDpn);
269 if (interfaceInfo != null) {
270 resultBld = RpcResultBuilder.success();
271 resultBld.withResult(new GetTunnelInterfaceNameOutputBuilder()
272 .setInterfaceName(interfaceInfo.getTunnelName())).build();
273 return Futures.immediateFuture(resultBld.build());
276 if (ItmUtils.isTunnelAggregationUsed(input.getTunnelType())) {
277 optTunnel = ItmUtils.getInternalTunnelFromDS(sourceDpn, destinationDpn,
278 TunnelTypeLogicalGroup.class, dataBroker);
279 LOG.debug("MULTIPLE_VxLAN_TUNNELS: getTunnelInterfaceName {}", optTunnel);
281 if (!optTunnel.isPresent()) {
282 optTunnel = ItmUtils.getInternalTunnelFromDS(sourceDpn, destinationDpn, input.getTunnelType(), dataBroker);
284 if (optTunnel.isPresent()) {
285 InternalTunnel tunnel = optTunnel.get();
286 GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
287 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
288 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
289 output.setInterfaceName(tunnelInterfaces.get(0));
290 resultBld = RpcResultBuilder.success();
291 resultBld.withResult(output.build());
293 resultBld = failed();
297 resultBld = failed();
299 return Futures.immediateFuture(resultBld.build());
303 public ListenableFuture<RpcResult<GetEgressActionsForTunnelOutput>>
304 getEgressActionsForTunnel(GetEgressActionsForTunnelInput input) {
305 String tunnelName = input.getIntfName();
306 if (tunnelName == null) {
307 return Futures.immediateFuture(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
308 .withError(RpcError.ErrorType.APPLICATION,
309 "tunnel name not set for GetEgressActionsForTunnel call").build());
311 if (tunnelName.startsWith("of")
312 || (interfaceManager.isItmDirectTunnelsEnabled() && dpnTepStateCache.isInternal(tunnelName))) {
313 return fromListenableFuture(LOG, input, () -> getEgressActionsForInternalTunnels(input.getIntfName(),
314 input.getTunnelKey() != null ? input.getTunnelKey().toJava() : null,
315 input.getActionKey())).onFailureLogLevel(LogLevel.ERROR).build();
317 // Re-direct the RPC to Interface Manager
318 // From the rpc input and get the output and copy to output
319 org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
320 .GetEgressActionsForInterfaceInputBuilder inputIfmBuilder =
321 new org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
322 .GetEgressActionsForInterfaceInputBuilder().setIntfName(input.getIntfName())
323 .setTunnelKey(input.getTunnelKey()).setActionKey(input.getActionKey());
324 SettableFuture<RpcResult<GetEgressActionsForTunnelOutput>> settableFuture = SettableFuture.create();
325 Futures.addCallback(interfaceManagerService.getEgressActionsForInterface(inputIfmBuilder.build()),
326 new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
327 .interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput>() {
329 public void onSuccess(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs
330 .rev160406.@NonNull GetEgressActionsForInterfaceOutput result) {
331 GetEgressActionsForTunnelOutputBuilder output =
332 new GetEgressActionsForTunnelOutputBuilder().setAction(result.getAction());
333 settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>success()
334 .withResult(output.build()).build());
338 public void onFailure(Throwable throwable) {
339 LOG.debug("RPC Call to Get egress actions failed for interface {}", tunnelName);
340 String errMsg = String.format("RPC call to get egress actions failed for interface %s",
342 settableFuture.set(RpcResultBuilder.<GetEgressActionsForTunnelOutput>failed()
343 .withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
345 } ,MoreExecutors.directExecutor());
346 return settableFuture;
351 public ListenableFuture<RpcResult<GetTunnelTypeOutput>> getTunnelType(GetTunnelTypeInput input) {
352 String tunnelName = input.getIntfName();
353 if (tunnelName == null) {
354 return Futures.immediateFuture(RpcResultBuilder.<GetTunnelTypeOutput>failed()
355 .withError(RpcError.ErrorType.APPLICATION,
356 "tunnel name not set for getTunnelType call").build());
359 if (!dpnTepStateCache.isInternal(tunnelName) || !interfaceManager.isItmDirectTunnelsEnabled()) {
360 org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406
361 .GetTunnelTypeInputBuilder inputBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight
362 .genius.interfacemanager.rpcs.rev160406.GetTunnelTypeInputBuilder()
363 .setIntfName(input.getIntfName());
364 SettableFuture<RpcResult<GetTunnelTypeOutput>> settableFuture = SettableFuture.create();
365 Futures.addCallback(interfaceManagerService.getTunnelType(inputBuilder.build()),
366 new FutureCallback<org.opendaylight.yang.gen.v1.urn.opendaylight.genius
367 .interfacemanager.rpcs.rev160406.GetTunnelTypeOutput>() {
369 public void onSuccess(org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs
370 .rev160406.@NonNull GetTunnelTypeOutput result) {
371 GetTunnelTypeOutputBuilder output = new GetTunnelTypeOutputBuilder()
372 .setTunnelType(result.getTunnelType());
373 settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>success()
374 .withResult(output.build()).build());
378 public void onFailure(Throwable throwable) {
379 LOG.debug("RPC Call to Get tunnel type failed for interface {}", tunnelName);
380 String errMsg = String.format("RPC to Get tunnel type failed for interface %s",
382 settableFuture.set(RpcResultBuilder.<GetTunnelTypeOutput>failed()
383 .withError(RpcError.ErrorType.APPLICATION, errMsg, throwable).build());
385 },MoreExecutors.directExecutor());
386 return settableFuture;
388 LOG.debug("get tunnel type from ITM for interface name {}", input.getIntfName());
389 return FutureRpcResults.fromBuilder(LOG, input, () -> {
390 DpnTepInterfaceInfo ifInfo = dpnTepStateCache.getTunnelFromCache(input.getIntfName());
391 return new GetTunnelTypeOutputBuilder().setTunnelType(ifInfo.getTunnelType());
397 public ListenableFuture<RpcResult<SetBfdParamOnTunnelOutput>> setBfdParamOnTunnel(
398 SetBfdParamOnTunnelInput input) {
399 final Uint64 srcDpnId = Uint64.valueOf(input.getSourceNode());
400 final Uint64 destDpnId = Uint64.valueOf(input.getDestinationNode());
401 LOG.debug("setBfdParamOnTunnel srcDpnId: {}, destDpnId: {}", srcDpnId, destDpnId);
402 final SettableFuture<RpcResult<SetBfdParamOnTunnelOutput>> result = SettableFuture.create();
403 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
404 enableBFD(tx, srcDpnId, destDpnId, input.isMonitoringEnabled(), input.getMonitoringInterval().toJava());
405 enableBFD(tx, destDpnId, srcDpnId, input.isMonitoringEnabled(), input.getMonitoringInterval().toJava());
408 future.addCallback(new FutureCallback<Object>() {
410 public void onSuccess(Object voidInstance) {
411 result.set(RpcResultBuilder.<SetBfdParamOnTunnelOutput>success().build());
415 public void onFailure(Throwable error) {
416 String msg = "Unable to remove external tunnel from DPN";
417 LOG.error("remove ext tunnel failed. {}.", msg, error);
418 result.set(RpcResultBuilder.<SetBfdParamOnTunnelOutput>failed()
419 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
421 }, MoreExecutors.directExecutor());
425 private void enableBFD(TypedWriteTransaction<Datastore.Configuration> tx, Uint64 srcDpnId, Uint64 destDpnId,
426 final Boolean enabled, final Integer interval) throws ReadFailedException {
427 DpnTepInterfaceInfo dpnTepInterfaceInfo = dpnTepStateCache.getDpnTepInterface(srcDpnId, destDpnId);
428 RemoteDpnsBuilder remoteDpnsBuilder = new RemoteDpnsBuilder();
429 remoteDpnsBuilder.withKey(new RemoteDpnsKey(destDpnId)).setDestinationDpnId(destDpnId)
430 .setTunnelName(dpnTepInterfaceInfo.getTunnelName()).setInternal(dpnTepInterfaceInfo.isInternal())
431 .setMonitoringEnabled(enabled);
432 if (enabled && interval != null) {
433 remoteDpnsBuilder.setMonitoringInterval(interval);
435 RemoteDpns remoteDpn = remoteDpnsBuilder.build();
436 Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(srcDpnId);
437 LOG.debug("setBfdParamOnTunnel TunnelName: {}, ovsBridgeRefEntry: {}", dpnTepInterfaceInfo.getTunnelName(),
439 directTunnelUtils.updateBfdConfiguration(srcDpnId, remoteDpn, ovsBridgeRefEntry);
440 InstanceIdentifier<RemoteDpns> iid = InstanceIdentifier.builder(DpnTepsState.class)
441 .child(DpnsTeps.class, new DpnsTepsKey(srcDpnId))
442 .child(RemoteDpns.class,
443 new RemoteDpnsKey(destDpnId)).build();
444 tx.mergeParentStructureMerge(iid, remoteDpn);
448 public ListenableFuture<RpcResult<RemoveExternalTunnelEndpointOutput>> removeExternalTunnelEndpoint(
449 RemoveExternalTunnelEndpointInput input) {
450 //Ignore the Futures for now
451 final SettableFuture<RpcResult<RemoveExternalTunnelEndpointOutput>> result = SettableFuture.create();
452 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
454 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
455 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
459 future.addCallback(new FutureCallback<Object>() {
460 @Override public void onSuccess(Object voidInstance) {
461 result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>success().build());
464 @Override public void onFailure(Throwable error) {
465 String msg = "Unable to delete DcGatewayIp " + input.getDestinationIp()
466 + " in datastore and tunnel type " + input.getTunnelType();
467 LOG.error("Unable to delete DcGatewayIp {} in datastore and tunnel type {}", input.getDestinationIp(),
468 input.getTunnelType());
469 result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>failed()
470 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
472 }, MoreExecutors.directExecutor());
477 public ListenableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> removeExternalTunnelFromDpns(
478 RemoveExternalTunnelFromDpnsInput input) {
479 //Ignore the Futures for now
480 final SettableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
481 List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dpnTEPsInfoCache, input.getDpnId());
482 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
483 tx -> ItmExternalTunnelDeleteWorker.deleteTunnels(cfgDpnList, input.getDestinationIp(),
484 input.getTunnelType(), tx));
486 future.addCallback(new FutureCallback<Object>() {
488 public void onSuccess(Object voidInstance) {
489 result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>success().build());
493 public void onFailure(Throwable error) {
494 String msg = "Unable to remove external tunnel from DPN";
495 LOG.error("remove ext tunnel failed. {}.", msg, error);
496 result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>failed()
497 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
499 }, MoreExecutors.directExecutor());
504 public ListenableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> buildExternalTunnelFromDpns(
505 BuildExternalTunnelFromDpnsInput input) {
506 //Ignore the Futures for now
507 final SettableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
508 FluentFuture<?> extTunnelResultList =
509 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
510 tx -> externalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(input.getDpnId(),
511 input.getDestinationIp(),input.getTunnelType(), tx));
513 extTunnelResultList.addCallback(new FutureCallback<Object>() {
515 public void onSuccess(Object voidInstance) {
516 result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>success().build());
520 public void onFailure(Throwable error) {
521 String msg = "Unable to create ext tunnel";
522 LOG.error("create ext tunnel failed. {}.", msg, error);
523 result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>failed()
524 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
526 }, MoreExecutors.directExecutor());
531 public ListenableFuture<RpcResult<AddExternalTunnelEndpointOutput>> addExternalTunnelEndpoint(
532 AddExternalTunnelEndpointInput input) {
533 // TODO Auto-generated method stub
535 //Ignore the Futures for now
536 final SettableFuture<RpcResult<AddExternalTunnelEndpointOutput>> result = SettableFuture.create();
537 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
538 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
539 DcGatewayIp dcGatewayIp =
540 new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp())
541 .setTunnnelType(input.getTunnelType()).build();
543 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
545 tx.mergeParentStructurePut(extPath, dcGatewayIp);
548 future.addCallback(new FutureCallback<Object>() {
549 @Override public void onSuccess(Object voidInstance) {
550 result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>success().build());
553 @Override public void onFailure(Throwable error) {
555 "Unable to create DcGatewayIp {} in datastore for ip " + input.getDestinationIp() + "and "
556 + "tunnel type " + input.getTunnelType();
558 LOG.error("Unable to create DcGatewayIp in datastore for ip {} and tunnel type {}",
559 input.getDestinationIp() , input.getTunnelType());
560 result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>failed()
561 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
563 }, MoreExecutors.directExecutor());
568 public ListenableFuture<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
569 GetExternalTunnelInterfaceNameInput input) {
570 SettableFuture.create();
571 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
572 String sourceNode = input.getSourceNode();
573 String dstNode = input.getDestinationNode();
574 if (interfaceManager.isItmOfTunnelsEnabled()) {
575 Optional<OfDpnTep> tepDetail;
577 tepDetail = ofDpnTepConfigCache.get(new BigInteger(sourceNode));
578 } catch (ReadFailedException e) {
579 LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for "
580 + "source dpn {} reason: {}", sourceNode, e.getMessage());
581 resultBld = failed();
582 return Futures.immediateFuture(resultBld.build());
584 if (tepDetail.isPresent()) {
585 GetExternalTunnelInterfaceNameOutputBuilder output =
586 new GetExternalTunnelInterfaceNameOutputBuilder()
587 .setInterfaceName(tepDetail.get().getOfPortName());
588 resultBld = RpcResultBuilder.success();
589 resultBld.withResult(output.build());
590 return Futures.immediateFuture(resultBld.build());
592 LOG.error("OF tunnel interface is not available in config DS for source dpn {}", sourceNode);
593 resultBld = failed();
594 return Futures.immediateFuture(resultBld.build());
597 ExternalTunnelKey externalTunnelKey = new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType());
598 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
599 ExternalTunnelList.class)
600 .child(ExternalTunnel.class, externalTunnelKey);
601 ExternalTunnel exTunnel =
602 ItmUtils.getExternalTunnelbyExternalTunnelKey(externalTunnelKey, path, this.dataBroker);
603 if (exTunnel != null) {
604 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder();
605 output.setInterfaceName(exTunnel.getTunnelInterfaceName());
606 resultBld = RpcResultBuilder.success();
607 resultBld.withResult(output.build());
609 resultBld = failed();
612 return Futures.immediateFuture(resultBld.build());
616 public ListenableFuture<RpcResult<CreateTerminatingServiceActionsOutput>>
617 createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
618 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}",
619 input.getDpnId() , input.getServiceId(), input.getInstruction());
620 final SettableFuture<RpcResult<CreateTerminatingServiceActionsOutput>> result = SettableFuture.create();
621 Uint16 serviceId = input.getServiceId();
622 final List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
624 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
625 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, serviceId), 5,
626 "ITM Flow Entry :" + serviceId, 0, 0,
627 Uint64.fromLongBits(ITMConstants.COOKIE_ITM.longValue() + serviceId.toJava()), mkMatches,
628 input.getInstruction());
630 ListenableFuture<?> installFlowResult = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
631 tx -> mdsalManager.addFlow(tx, input.getDpnId(), terminatingServiceTableFlow));
632 Futures.addCallback(installFlowResult, new FutureCallback<Object>() {
635 public void onSuccess(Object voidInstance) {
636 result.set(RpcResultBuilder.<CreateTerminatingServiceActionsOutput>success().build());
640 public void onFailure(Throwable error) {
641 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
642 LOG.error("create terminating service actions failed. {}", msg, error);
643 result.set(RpcResultBuilder.<CreateTerminatingServiceActionsOutput>failed()
644 .withError(RpcError.ErrorType.APPLICATION, msg, error)
647 }, MoreExecutors.directExecutor());
648 // result.set(RpcResultBuilder.<Void>success().build());
653 public ListenableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>>
654 removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
655 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}",
656 input.getDpnId(), input.getServiceId());
657 final SettableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>> result = SettableFuture.create();
659 ListenableFuture<?> removeFlowResult = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
660 tx -> mdsalManager.removeFlow(tx, input.getDpnId(),
661 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, input.getServiceId()),
662 NwConstants.INTERNAL_TUNNEL_TABLE));
663 Futures.addCallback(removeFlowResult, new FutureCallback<Object>() {
666 public void onSuccess(Object voidInstance) {
667 result.set(RpcResultBuilder.<RemoveTerminatingServiceActionsOutput>success().build());
671 public void onFailure(Throwable error) {
672 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
673 LOG.error("remove terminating service actions failed. {}", msg, error);
674 result.set(RpcResultBuilder.<RemoveTerminatingServiceActionsOutput>failed()
675 .withError(RpcError.ErrorType.APPLICATION, msg, error)
678 }, MoreExecutors.directExecutor());
679 //result.set(RpcResultBuilder.<Void>success().build());
684 public List<MatchInfo> getTunnelMatchesForServiceId(Uint16 serviceId) {
685 final List<MatchInfo> mkMatches = new ArrayList<>();
688 mkMatches.add(new MatchTunnelId(Uint64.valueOf(serviceId)));
693 private String getFlowRef(long termSvcTable, Uint16 svcId) {
694 return String.valueOf(termSvcTable) + svcId;
698 public ListenableFuture<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
699 GetInternalOrExternalInterfaceNameInput input) {
700 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = failed();
701 Uint64 srcDpn = input.getSourceDpid();
702 IpAddress dstIp = input.getDestinationIp();
703 if (interfaceManager.isItmOfTunnelsEnabled()) {
704 Optional<OfDpnTep> tepDetail;
706 tepDetail = ofDpnTepConfigCache.get(srcDpn.toJava());
707 } catch (ReadFailedException e) {
708 LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for "
709 + "source dpn {} reason: {}", srcDpn, e.getMessage());
710 return Futures.immediateFuture(resultBld.build());
712 if (tepDetail.isPresent()) {
713 GetInternalOrExternalInterfaceNameOutputBuilder output =
714 new GetInternalOrExternalInterfaceNameOutputBuilder()
715 .setInterfaceName(tepDetail.get().getOfPortName());
716 resultBld = RpcResultBuilder.success();
717 resultBld.withResult(output.build());
718 return Futures.immediateFuture(resultBld.build());
720 LOG.error("OF tunnel interface is not available in config DS for source dpn {}", srcDpn);
721 return Futures.immediateFuture(resultBld.build());
724 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
725 .child(ExternalTunnel.class,
726 new ExternalTunnelKey(dstIp.stringValue(), srcDpn.toString(), input.getTunnelType()));
728 Optional<ExternalTunnel> optExtTunnel = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
730 if (optExtTunnel != null && optExtTunnel.isPresent()) {
731 ExternalTunnel extTunnel = optExtTunnel.get();
732 GetInternalOrExternalInterfaceNameOutputBuilder output =
733 new GetInternalOrExternalInterfaceNameOutputBuilder()
734 .setInterfaceName(extTunnel.getTunnelInterfaceName());
735 resultBld = RpcResultBuilder.success();
736 resultBld.withResult(output.build()) ;
738 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
740 // Look for external tunnels if not look for internal tunnel
741 for (DPNTEPsInfo teps : meshedDpnList) {
742 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
743 if (dstIp.equals(firstEndPt.getIpAddress())) {
744 Optional<InternalTunnel> optTunnel = Optional.empty();
745 if (interfaceManager.isItmDirectTunnelsEnabled()) {
746 DpnTepInterfaceInfo interfaceInfo =
747 dpnTepStateCache.getDpnTepInterface(srcDpn, teps.getDPNID());
748 if (interfaceInfo != null) {
749 resultBld = RpcResultBuilder.success();
750 resultBld.withResult(new GetInternalOrExternalInterfaceNameOutputBuilder()
751 .setInterfaceName(interfaceInfo.getTunnelName())).build();
752 return Futures.immediateFuture(resultBld.build());
756 if (ItmUtils.isTunnelAggregationUsed(input.getTunnelType())) {
757 optTunnel = ItmUtils.getInternalTunnelFromDS(srcDpn, teps.getDPNID(),
758 TunnelTypeLogicalGroup.class, dataBroker);
759 LOG.debug("MULTIPLE_VxLAN_TUNNELS: getInternalOrExternalInterfaceName {}", optTunnel);
761 if (!optTunnel.isPresent()) {
762 optTunnel = ItmUtils.getInternalTunnelFromDS(srcDpn, teps.getDPNID(),
763 input.getTunnelType(), dataBroker);
765 if (optTunnel.isPresent()) {
766 InternalTunnel tunnel = optTunnel.get();
767 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
768 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
769 GetInternalOrExternalInterfaceNameOutputBuilder
771 new GetInternalOrExternalInterfaceNameOutputBuilder()
772 .setInterfaceName(tunnelInterfaces.get(0));
773 resultBld = RpcResultBuilder.success();
774 resultBld.withResult(output.build());
776 LOG.error("No tunnel interface found between source DPN {} ans destination IP {}", srcDpn,
781 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
786 return Futures.immediateFuture(resultBld.build());
789 @SuppressWarnings("checkstyle:IllegalCatch")
791 public ListenableFuture<RpcResult<DeleteL2GwDeviceOutput>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
792 final SettableFuture<RpcResult<DeleteL2GwDeviceOutput>> result = SettableFuture.create();
793 boolean foundVxlanTzone = false;
795 final IpAddress hwIp = input.getIpAddress();
796 final String nodeId = input.getNodeId();
797 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
798 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
799 containerPath, dataBroker);
800 if (transportZonesOptional.isPresent()) {
801 TransportZones transportZones = transportZonesOptional.get();
802 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
803 LOG.error("No teps configured");
804 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
805 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
808 for (TransportZone tzone : transportZones.getTransportZone()) {
809 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
812 foundVxlanTzone = true;
813 String transportZone = tzone.getZoneName();
814 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
815 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier
816 .builder(TransportZones.class)
817 .child(TransportZone.class,
818 new TransportZoneKey(transportZone))
819 .child(DeviceVteps.class, deviceVtepKey)
821 FluentFuture<?> future =
822 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(path));
823 future.addCallback(new FutureCallback<Object>() {
824 @Override public void onSuccess(Object voidInstance) {
825 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>success().build());
828 @Override public void onFailure(Throwable error) {
829 String msg = String.format("Unable to delete HwVtep %s from datastore", nodeId);
830 LOG.error("Unable to delete HwVtep {}, {} from datastore", nodeId, hwIp);
831 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
832 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
834 }, MoreExecutors.directExecutor());
837 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
838 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
842 if (!foundVxlanTzone) {
843 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
844 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
849 } catch (Exception e) {
850 RpcResultBuilder<DeleteL2GwDeviceOutput> resultBuilder = RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
851 .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
852 return Futures.immediateFuture(resultBuilder.build());
856 @SuppressWarnings("checkstyle:IllegalCatch")
858 public ListenableFuture<RpcResult<AddL2GwDeviceOutput>> addL2GwDevice(AddL2GwDeviceInput input) {
860 final SettableFuture<RpcResult<AddL2GwDeviceOutput>> result = SettableFuture.create();
861 boolean foundVxlanTzone = false;
863 final IpAddress hwIp = input.getIpAddress();
864 final String nodeId = input.getNodeId();
865 //iterate through all transport zones and put TORs under vxlan
866 //if no vxlan tzone is cnfigured, return an error.
867 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
868 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
869 containerPath, dataBroker);
870 if (transportZonesOptional.isPresent()) {
871 TransportZones transportZones = transportZonesOptional.get();
872 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
873 LOG.error("No transportZone configured");
874 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
875 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
878 for (TransportZone tzone : transportZones.getTransportZone()) {
879 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
882 String transportZone = tzone.getZoneName();
883 foundVxlanTzone = true;
884 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
885 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier
886 .builder(TransportZones.class)
887 .child(TransportZone.class,
888 new TransportZoneKey(transportZone))
889 .child(DeviceVteps.class, deviceVtepKey)
891 DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey).setIpAddress(hwIp)
892 .setNodeId(nodeId).setTopologyId(input.getTopologyId()).build();
893 //TO DO: add retry if it fails
894 FluentFuture<?> future = retryingTxRunner
895 .callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
896 tx -> tx.mergeParentStructurePut(path, deviceVtep));
898 future.addCallback(new FutureCallback<Object>() {
900 @Override public void onSuccess(Object voidInstance) {
901 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>success().build());
904 @Override public void onFailure(Throwable error) {
905 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
906 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
907 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
908 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
910 }, MoreExecutors.directExecutor());
914 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
915 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
919 if (!foundVxlanTzone) {
920 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
921 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
926 } catch (Exception e) {
927 RpcResultBuilder<AddL2GwDeviceOutput> resultBuilder = RpcResultBuilder.<AddL2GwDeviceOutput>failed()
928 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
929 return Futures.immediateFuture(resultBuilder.build());
934 public ListenableFuture<RpcResult<GetWatchPortForTunnelOutput>> getWatchPortForTunnel(
935 GetWatchPortForTunnelInput input) {
936 throw new UnsupportedOperationException("TODO");
939 public ListenableFuture<RpcResult<GetTepIpOutput>> getTepIp(GetTepIpInput input) {
940 RpcResultBuilder<GetTepIpOutput> resultBld;
941 Uint64 sourceDpn = input.getDpnId();
942 Optional<OfDpnTep> dpnstep;
944 dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava());
945 } catch (ReadFailedException e) {
946 LOG.error("ReadFailedException: OF tunnel is not available in ITM for source dpn {} reason: {}",sourceDpn,
948 resultBld = RpcResultBuilder.failed();
949 return Futures.immediateFuture(resultBld.build());
951 if (dpnstep.isPresent()) {
952 resultBld = RpcResultBuilder.success();
953 resultBld.withResult(new GetTepIpOutputBuilder()
954 .setTepIp(dpnstep.get().getTepIp())).build();
955 return Futures.immediateFuture(resultBld.build());
957 LOG.error("OF tunnel is not available in ITM for source dpn {}",sourceDpn);
958 resultBld = RpcResultBuilder.failed();
959 return Futures.immediateFuture(resultBld.build());
963 @SuppressWarnings("checkstyle:IllegalCatch")
965 public ListenableFuture<RpcResult<AddL2GwMlagDeviceOutput>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input) {
967 final SettableFuture<RpcResult<AddL2GwMlagDeviceOutput>> result = SettableFuture.create();
969 final IpAddress hwIp = input.getIpAddress();
970 final List<String> nodeId = input.getNodeId();
971 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
972 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
973 containerPath, dataBroker);
974 if (transportZonesOptional.isPresent()) {
975 TransportZones transportZones = transportZonesOptional.get();
976 if (transportZones.getTransportZone() == null || transportZones.getTransportZone()
978 LOG.error("No teps configured");
979 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
980 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
983 for (TransportZone tzone : transportZones.getTransportZone()) {
984 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
987 String transportZone = tzone.getZoneName();
988 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
989 InstanceIdentifier<DeviceVteps> path =
990 InstanceIdentifier.builder(TransportZones.class)
991 .child(TransportZone.class, new TransportZoneKey(transportZone))
992 .child(DeviceVteps.class, deviceVtepKey).build();
993 DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey)
995 .setNodeId(nodeId.get(0)).setTopologyId(input.getTopologyId()).build();
996 LOG.trace("writing hWvtep{}", deviceVtep);
997 FluentFuture<?> future =
998 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
1000 tx.mergeParentStructurePut(path, deviceVtep);
1001 if (nodeId.size() == 2) {
1002 LOG.trace("second node-id {}", nodeId.get(1));
1003 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp,
1005 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier
1006 .builder(TransportZones.class)
1007 .child(TransportZone.class, new TransportZoneKey(transportZone))
1008 .child(DeviceVteps.class, deviceVtepKey2).build();
1009 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder()
1010 .withKey(deviceVtepKey2)
1011 .setIpAddress(hwIp).setNodeId(nodeId.get(1))
1012 .setTopologyId(input.getTopologyId()).build();
1013 LOG.trace("writing {}", deviceVtep2);
1014 tx.mergeParentStructurePut(path2, deviceVtep2);
1017 future.addCallback(new FutureCallback<Object>() {
1019 public void onSuccess(Object voidInstance) {
1020 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>success().build());
1024 public void onFailure(Throwable error) {
1026 .format("Unable to write HwVtep %s to datastore", nodeId);
1027 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
1028 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
1029 .withError(RpcError.ErrorType.APPLICATION, msg, error)
1032 }, MoreExecutors.directExecutor());
1036 } catch (RuntimeException e) {
1037 RpcResultBuilder<AddL2GwMlagDeviceOutput> resultBuilder = RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
1038 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
1039 return Futures.immediateFuture(resultBuilder.build());
1043 @SuppressWarnings("checkstyle:IllegalCatch")
1045 public ListenableFuture<RpcResult<DeleteL2GwMlagDeviceOutput>> deleteL2GwMlagDevice(
1046 DeleteL2GwMlagDeviceInput input) {
1047 final SettableFuture<RpcResult<DeleteL2GwMlagDeviceOutput>> result = SettableFuture.create();
1049 final IpAddress hwIp = input.getIpAddress();
1050 final List<String> nodeId = input.getNodeId();
1051 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
1052 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1053 containerPath, dataBroker);
1054 if (transportZonesOptional.isPresent()) {
1055 TransportZones tzones = transportZonesOptional.get();
1056 if (tzones.getTransportZone() == null || tzones.getTransportZone().isEmpty()) {
1057 LOG.error("No teps configured");
1058 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed()
1059 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
1062 String transportZone = tzones.getTransportZone().get(0).getZoneName();
1063 FluentFuture<?> future =
1064 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
1066 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
1067 InstanceIdentifier<DeviceVteps> path =
1068 InstanceIdentifier.builder(TransportZones.class)
1069 .child(TransportZone.class, new TransportZoneKey(transportZone))
1070 .child(DeviceVteps.class,
1071 deviceVtepKey).build();
1073 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
1074 InstanceIdentifier<DeviceVteps> path2 =
1075 InstanceIdentifier.builder(TransportZones.class)
1076 .child(TransportZone.class, new TransportZoneKey(transportZone))
1077 .child(DeviceVteps.class,
1078 deviceVtepKey2).build();
1083 future.addCallback(new FutureCallback<Object>() {
1086 public void onSuccess(Object voidInstance) {
1087 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>success().build());
1091 public void onFailure(Throwable error) {
1092 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
1093 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
1094 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed()
1095 .withError(RpcError.ErrorType.APPLICATION, msg, error)
1098 }, MoreExecutors.directExecutor());
1101 } catch (Exception e) {
1102 RpcResultBuilder<DeleteL2GwMlagDeviceOutput> resultBuilder =
1103 RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed().withError(RpcError.ErrorType.APPLICATION,
1104 "Deleting l2 Gateway to DS Failed", e);
1105 return Futures.immediateFuture(resultBuilder.build());
1110 public ListenableFuture<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
1111 IsTunnelInternalOrExternalInput input) {
1112 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
1113 String tunIfName = input.getTunnelInterfaceName();
1115 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder()
1116 .setTunnelType(tunVal);
1118 if (ItmUtils.ITM_CACHE.getInternalTunnel(tunIfName) != null) {
1120 } else if (ItmUtils.ITM_CACHE.getExternalTunnel(tunIfName) != null) {
1123 output.setTunnelType(tunVal);
1124 resultBld = RpcResultBuilder.success();
1125 resultBld.withResult(output.build());
1126 return Futures.immediateFuture(resultBld.build());
1130 public ListenableFuture<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
1131 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
1133 Map<DcGatewayIpKey, DcGatewayIp> dcGatewayIpList = new HashMap<>();
1134 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
1135 tx -> dcGatewayIpList.putAll(getDcGatewayIpList(tx))).isDone();
1136 String dcgwIpStr = input.getDcgwIp();
1137 IpAddress dcgwIpAddr = IpAddressBuilder.getDefaultInstance(dcgwIpStr);
1140 if (!dcGatewayIpList.isEmpty()
1141 && dcGatewayIpList.values().stream().anyMatch(gwIp -> dcgwIpAddr.equals(gwIp.getIpAddress()))) {
1144 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
1145 resultBld.withResult(output.build());
1149 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
1150 resultBld.withResult(output.build());
1152 return Futures.immediateFuture(resultBld.build());
1156 public ListenableFuture<RpcResult<GetDpnEndpointIpsOutput>> getDpnEndpointIps(GetDpnEndpointIpsInput input) {
1157 Uint64 srcDpn = input.getSourceDpid();
1158 RpcResultBuilder<GetDpnEndpointIpsOutput> resultBld = failed();
1159 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
1160 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
1161 new DPNTEPsInfoKey(srcDpn)).build();
1162 Optional<DPNTEPsInfo> tunnelInfo = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tunnelInfoId, dataBroker);
1163 if (!tunnelInfo.isPresent()) {
1164 LOG.error("tunnelInfo is not present");
1165 return Futures.immediateFuture(resultBld.build());
1168 List<TunnelEndPoints> tunnelEndPointList = tunnelInfo.get().getTunnelEndPoints();
1169 if (tunnelEndPointList == null || tunnelEndPointList.isEmpty()) {
1170 LOG.error("tunnelEndPointList is null or empty");
1171 return Futures.immediateFuture(resultBld.build());
1174 List<IpAddress> nexthopIpList = new ArrayList<>();
1175 tunnelEndPointList.forEach(tunnelEndPoint -> nexthopIpList.add(tunnelEndPoint.getIpAddress()));
1177 GetDpnEndpointIpsOutputBuilder output = new GetDpnEndpointIpsOutputBuilder().setNexthopipList(nexthopIpList);
1178 resultBld = RpcResultBuilder.success();
1179 resultBld.withResult(output.build()) ;
1180 return Futures.immediateFuture(resultBld.build());
1184 public ListenableFuture<RpcResult<GetDpnInfoOutput>> getDpnInfo(GetDpnInfoInput input) {
1185 return FutureRpcResults.fromListenableFuture(LOG, "getDpnInfo", input,
1186 () -> Futures.immediateFuture(getDpnInfoInternal(input))).build();
1189 private GetDpnInfoOutput getDpnInfoInternal(GetDpnInfoInput input) throws ReadFailedException {
1190 Map<String, Uint64> computeNamesVsDpnIds
1191 = getDpnIdByComputeNodeNameFromOpInventoryNodes(input.getComputeNames());
1192 Map<Uint64, ComputesBuilder> dpnIdVsVtepsComputes
1193 = getTunnelEndPointByDpnIdFromTranPortZone(computeNamesVsDpnIds.values());
1194 List<Computes> computes = computeNamesVsDpnIds.entrySet().stream()
1195 .map(entry -> dpnIdVsVtepsComputes.get(entry.getValue()).setComputeName(entry.getKey()).build())
1196 .collect(Collectors.toList());
1197 return new GetDpnInfoOutputBuilder().setComputes(computes).build();
1200 private Map<Uint64, ComputesBuilder> getTunnelEndPointByDpnIdFromTranPortZone(Collection<Uint64> dpnIds)
1201 throws ReadFailedException {
1202 TransportZones transportZones = singleTransactionDataBroker.syncRead(
1203 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(TransportZones.class).build());
1204 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
1205 throw new IllegalStateException("Failed to find transport zones in config datastore");
1207 Map<Uint64, ComputesBuilder> result = new HashMap<>();
1208 for (TransportZone transportZone : transportZones.getTransportZone()) {
1209 for (Vteps vtep : transportZone.getVteps().values()) {
1210 if (dpnIds.contains(vtep.getDpnId())) {
1211 result.putIfAbsent(vtep.getDpnId(),
1212 new ComputesBuilder()
1213 .setZoneName(transportZone.getZoneName())
1214 .setDpnId(vtep.getDpnId())
1215 .setNodeId(getNodeId(vtep.getDpnId()))
1216 .setTepIp(Collections.singletonList(vtep.getIpAddress())));
1220 for (Uint64 dpnId : dpnIds) {
1221 if (!result.containsKey(dpnId)) {
1222 throw new IllegalStateException("Failed to find dpn id " + dpnId + " in transport zone");
1228 private Map<String, Uint64> getDpnIdByComputeNodeNameFromOpInventoryNodes(List<String> nodeNames)
1229 throws ReadFailedException {
1230 Nodes operInventoryNodes = singleTransactionDataBroker.syncRead(
1231 LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(Nodes.class).build());
1232 if (operInventoryNodes.getNode() == null || operInventoryNodes.getNode().isEmpty()) {
1233 throw new IllegalStateException("Failed to find operational inventory nodes datastore");
1235 Map<String, Uint64> result = new HashMap<>();
1236 for (Node node : operInventoryNodes.getNode().values()) {
1237 String name = node.augmentation(FlowCapableNode.class).getDescription();
1238 if (nodeNames.contains(name)) {
1239 String[] nodeId = node.getId().getValue().split(":");
1240 result.put(name, Uint64.valueOf(nodeId[1]));
1243 for (String nodeName : nodeNames) {
1244 if (!result.containsKey(nodeName)) {
1245 throw new IllegalStateException("Failed to find dpn id of compute node name from oper inventory "
1252 private String getNodeId(Uint64 dpnId) throws ReadFailedException {
1253 InstanceIdentifier<BridgeRefEntry> path = InstanceIdentifier
1254 .builder(BridgeRefInfo.class)
1255 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId)).build();
1256 BridgeRefEntry bridgeRefEntry =
1257 singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, path);
1258 return bridgeRefEntry.getBridgeReference().getValue()
1259 .firstKeyOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
1260 .network.topology.topology.Node.class).getNodeId().getValue();
1263 private ListenableFuture<GetEgressActionsForTunnelOutput>
1264 getEgressActionsForInternalTunnels(String interfaceName, Long tunnelKey, Integer actionKey)
1265 throws ExecutionException, InterruptedException, OperationFailedException {
1267 if (interfaceName.startsWith("of")) {
1268 Optional<OfTep> oftep = ofTepStateCache.get(interfaceName);
1269 if (!oftep.isPresent()) {
1270 throw new IllegalStateException("Interface information not present in oper DS for" + interfaceName);
1272 List<ActionInfo> actions = getEgressActionInfosForOpenFlowTunnel(oftep.get().getIfIndex(),
1273 oftep.get().getTepIp(), tunnelKey, actionKey);
1274 return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
1275 .setAction(actions.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
1277 DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
1278 if (interfaceInfo == null) {
1279 throw new IllegalStateException("Interface information not present in config DS for" + interfaceName);
1282 String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType());
1283 if (!tunnelType.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_VXLAN)) {
1284 throw new IllegalArgumentException(tunnelType + " tunnel not handled by ITM");
1287 Optional<DPNTEPsInfo> dpntePsInfoOptional = dpnTEPsInfoCache.get(InstanceIdentifier
1288 .builder(DpnEndpoints.class)
1289 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(
1290 // FIXME: the cache should be caching this value, not just as a String
1291 dpnTepStateCache.getTunnelEndPointInfoFromCache(
1292 interfaceInfo.getTunnelName()).getDstEndPointInfo())).build());
1294 if (dpntePsInfoOptional.isPresent()) {
1295 dstId = dpntePsInfoOptional.get().getDstId();
1297 dstId = directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME,
1298 interfaceInfo.getRemoteDPN().toString());
1301 List<ActionInfo> result = new ArrayList<>();
1302 long regValue = MetaDataUtil.getRemoteDpnMetadatForEgressTunnelTable(dstId);
1303 int actionKeyStart = actionKey == null ? 0 : actionKey;
1304 result.add(new ActionSetFieldTunnelId(actionKeyStart++,
1305 Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L)));
1306 result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, MetaDataUtil.REG6_START_INDEX,
1307 MetaDataUtil.REG6_END_INDEX, regValue));
1308 result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_TUNNEL_TABLE));
1310 return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
1311 .setAction(result.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
1316 private static List<ActionInfo> getEgressActionInfosForOpenFlowTunnel(Uint16 ifIndex, IpAddress ipAddress,
1317 Long tunnelKey, Integer actionKey) {
1318 List<ActionInfo> result = new ArrayList<>();
1319 int actionKeyStart = actionKey == null ? 0 : actionKey;
1320 result.add(new ActionSetFieldTunnelId(actionKeyStart++,
1321 Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L)));
1322 long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex.intValue() ,
1323 NwConstants.DEFAULT_SERVICE_INDEX);
1324 result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, ITMConstants.REG6_START_INDEX,
1325 ITMConstants.REG6_END_INDEX, regValue));
1326 result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE));
1331 public static Map<DcGatewayIpKey, DcGatewayIp>
1332 getDcGatewayIpList(TypedReadWriteTransaction<Datastore.Configuration> tx)
1333 throws ExecutionException, InterruptedException {
1334 Map<DcGatewayIpKey, DcGatewayIp> dcGatewayIpMap = new HashMap<>();
1335 FluentFuture<Optional<DcGatewayIpList>> future =
1336 tx.read(InstanceIdentifier.builder(DcGatewayIpList.class).build());
1337 future.addCallback(new FutureCallback<Optional<DcGatewayIpList>>() {
1339 public void onSuccess(Optional<DcGatewayIpList> optional) {
1341 // FIXME: why not just use the provided optional?
1342 Optional<DcGatewayIpList> opt = future.get();
1343 if (opt.isPresent()) {
1344 DcGatewayIpList list = opt.get();
1346 dcGatewayIpMap.putAll(list.getDcGatewayIp());
1349 } catch (ExecutionException | InterruptedException e) {
1350 LOG.error("DcGateway IpList read failed", e);
1355 public void onFailure(Throwable error) {
1356 LOG.error("DcGateway IpList read failed", error);
1358 }, MoreExecutors.directExecutor());
1359 return dcGatewayIpMap;