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 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
455 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
456 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
460 future.addCallback(new FutureCallback<Object>() {
461 @Override public void onSuccess(Object voidInstance) {
462 result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>success().build());
465 @Override public void onFailure(Throwable error) {
466 String msg = "Unable to delete DcGatewayIp " + input.getDestinationIp()
467 + " in datastore and tunnel type " + input.getTunnelType();
468 LOG.error("Unable to delete DcGatewayIp {} in datastore and tunnel type {}", input.getDestinationIp(),
469 input.getTunnelType());
470 result.set(RpcResultBuilder.<RemoveExternalTunnelEndpointOutput>failed()
471 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
473 }, MoreExecutors.directExecutor());
478 public ListenableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> removeExternalTunnelFromDpns(
479 RemoveExternalTunnelFromDpnsInput input) {
480 //Ignore the Futures for now
481 final SettableFuture<RpcResult<RemoveExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
482 List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dpnTEPsInfoCache, input.getDpnId());
483 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
484 tx -> ItmExternalTunnelDeleteWorker.deleteTunnels(cfgDpnList, input.getDestinationIp(),
485 input.getTunnelType(), tx));
487 future.addCallback(new FutureCallback<Object>() {
489 public void onSuccess(Object voidInstance) {
490 result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>success().build());
494 public void onFailure(Throwable error) {
495 String msg = "Unable to remove external tunnel from DPN";
496 LOG.error("remove ext tunnel failed. {}.", msg, error);
497 result.set(RpcResultBuilder.<RemoveExternalTunnelFromDpnsOutput>failed()
498 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
500 }, MoreExecutors.directExecutor());
505 public ListenableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> buildExternalTunnelFromDpns(
506 BuildExternalTunnelFromDpnsInput input) {
507 //Ignore the Futures for now
508 final SettableFuture<RpcResult<BuildExternalTunnelFromDpnsOutput>> result = SettableFuture.create();
509 FluentFuture<?> extTunnelResultList =
510 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
511 tx -> externalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(input.getDpnId(),
512 input.getDestinationIp(),input.getTunnelType(), tx));
514 extTunnelResultList.addCallback(new FutureCallback<Object>() {
516 public void onSuccess(Object voidInstance) {
517 result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>success().build());
521 public void onFailure(Throwable error) {
522 String msg = "Unable to create ext tunnel";
523 LOG.error("create ext tunnel failed. {}.", msg, error);
524 result.set(RpcResultBuilder.<BuildExternalTunnelFromDpnsOutput>failed()
525 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
527 }, MoreExecutors.directExecutor());
532 public ListenableFuture<RpcResult<AddExternalTunnelEndpointOutput>> addExternalTunnelEndpoint(
533 AddExternalTunnelEndpointInput input) {
534 // TODO Auto-generated method stub
536 //Ignore the Futures for now
537 final SettableFuture<RpcResult<AddExternalTunnelEndpointOutput>> result = SettableFuture.create();
538 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
539 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
540 DcGatewayIp dcGatewayIp =
541 new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp())
542 .setTunnnelType(input.getTunnelType()).build();
544 FluentFuture<?> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
546 tx.mergeParentStructurePut(extPath, dcGatewayIp);
549 future.addCallback(new FutureCallback<Object>() {
550 @Override public void onSuccess(Object voidInstance) {
551 result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>success().build());
554 @Override public void onFailure(Throwable error) {
556 "Unable to create DcGatewayIp {} in datastore for ip " + input.getDestinationIp() + "and "
557 + "tunnel type " + input.getTunnelType();
559 LOG.error("Unable to create DcGatewayIp in datastore for ip {} and tunnel type {}",
560 input.getDestinationIp() , input.getTunnelType());
561 result.set(RpcResultBuilder.<AddExternalTunnelEndpointOutput>failed()
562 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
564 }, MoreExecutors.directExecutor());
569 public ListenableFuture<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
570 GetExternalTunnelInterfaceNameInput input) {
571 SettableFuture.create();
572 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
573 String sourceNode = input.getSourceNode();
574 String dstNode = input.getDestinationNode();
575 if (interfaceManager.isItmOfTunnelsEnabled()) {
576 Optional<OfDpnTep> tepDetail;
578 tepDetail = ofDpnTepConfigCache.get(new BigInteger(sourceNode));
579 } catch (ReadFailedException e) {
580 LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for "
581 + "source dpn {} reason: {}", sourceNode, e.getMessage());
582 resultBld = failed();
583 return Futures.immediateFuture(resultBld.build());
585 if (tepDetail.isPresent()) {
586 GetExternalTunnelInterfaceNameOutputBuilder output =
587 new GetExternalTunnelInterfaceNameOutputBuilder()
588 .setInterfaceName(tepDetail.get().getOfPortName());
589 resultBld = RpcResultBuilder.success();
590 resultBld.withResult(output.build());
591 return Futures.immediateFuture(resultBld.build());
593 LOG.error("OF tunnel interface is not available in config DS for source dpn {}", sourceNode);
594 resultBld = failed();
595 return Futures.immediateFuture(resultBld.build());
598 ExternalTunnelKey externalTunnelKey = new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType());
599 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
600 ExternalTunnelList.class)
601 .child(ExternalTunnel.class, externalTunnelKey);
602 ExternalTunnel exTunnel =
603 ItmUtils.getExternalTunnelbyExternalTunnelKey(externalTunnelKey, path, this.dataBroker);
604 if (exTunnel != null) {
605 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder();
606 output.setInterfaceName(exTunnel.getTunnelInterfaceName());
607 resultBld = RpcResultBuilder.success();
608 resultBld.withResult(output.build());
610 resultBld = failed();
613 return Futures.immediateFuture(resultBld.build());
617 public ListenableFuture<RpcResult<CreateTerminatingServiceActionsOutput>>
618 createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
619 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}",
620 input.getDpnId() , input.getServiceId(), input.getInstruction());
621 final SettableFuture<RpcResult<CreateTerminatingServiceActionsOutput>> result = SettableFuture.create();
622 Uint16 serviceId = input.getServiceId();
623 final List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
625 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
626 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, serviceId), 5,
627 "ITM Flow Entry :" + serviceId, 0, 0,
628 Uint64.fromLongBits(ITMConstants.COOKIE_ITM.longValue() + serviceId.toJava()), mkMatches,
629 input.getInstruction());
631 ListenableFuture<?> installFlowResult = txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
632 tx -> mdsalManager.addFlow(tx, input.getDpnId(), terminatingServiceTableFlow));
633 Futures.addCallback(installFlowResult, new FutureCallback<Object>() {
636 public void onSuccess(Object voidInstance) {
637 result.set(RpcResultBuilder.<CreateTerminatingServiceActionsOutput>success().build());
641 public void onFailure(Throwable error) {
642 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
643 LOG.error("create terminating service actions failed. {}", msg, error);
644 result.set(RpcResultBuilder.<CreateTerminatingServiceActionsOutput>failed()
645 .withError(RpcError.ErrorType.APPLICATION, msg, error)
648 }, MoreExecutors.directExecutor());
649 // result.set(RpcResultBuilder.<Void>success().build());
654 public ListenableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>>
655 removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
656 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}",
657 input.getDpnId(), input.getServiceId());
658 final SettableFuture<RpcResult<RemoveTerminatingServiceActionsOutput>> result = SettableFuture.create();
660 ListenableFuture<?> removeFlowResult = txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
661 tx -> mdsalManager.removeFlow(tx, input.getDpnId(),
662 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, input.getServiceId()),
663 NwConstants.INTERNAL_TUNNEL_TABLE));
664 Futures.addCallback(removeFlowResult, new FutureCallback<Object>() {
667 public void onSuccess(Object voidInstance) {
668 result.set(RpcResultBuilder.<RemoveTerminatingServiceActionsOutput>success().build());
672 public void onFailure(Throwable error) {
673 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
674 LOG.error("remove terminating service actions failed. {}", msg, error);
675 result.set(RpcResultBuilder.<RemoveTerminatingServiceActionsOutput>failed()
676 .withError(RpcError.ErrorType.APPLICATION, msg, error)
679 }, MoreExecutors.directExecutor());
680 //result.set(RpcResultBuilder.<Void>success().build());
685 public List<MatchInfo> getTunnelMatchesForServiceId(Uint16 serviceId) {
686 final List<MatchInfo> mkMatches = new ArrayList<>();
689 mkMatches.add(new MatchTunnelId(Uint64.valueOf(serviceId)));
694 private String getFlowRef(long termSvcTable, Uint16 svcId) {
695 return String.valueOf(termSvcTable) + svcId;
699 public ListenableFuture<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
700 GetInternalOrExternalInterfaceNameInput input) {
701 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = failed();
702 Uint64 srcDpn = input.getSourceDpid();
703 IpAddress dstIp = input.getDestinationIp();
704 if (interfaceManager.isItmOfTunnelsEnabled()) {
705 Optional<OfDpnTep> tepDetail;
707 tepDetail = ofDpnTepConfigCache.get(srcDpn.toJava());
708 } catch (ReadFailedException e) {
709 LOG.error("ReadFailedException: OF tunnel interface is not available in config DS for "
710 + "source dpn {} reason: {}", srcDpn, e.getMessage());
711 return Futures.immediateFuture(resultBld.build());
713 if (tepDetail.isPresent()) {
714 GetInternalOrExternalInterfaceNameOutputBuilder output =
715 new GetInternalOrExternalInterfaceNameOutputBuilder()
716 .setInterfaceName(tepDetail.get().getOfPortName());
717 resultBld = RpcResultBuilder.success();
718 resultBld.withResult(output.build());
719 return Futures.immediateFuture(resultBld.build());
721 LOG.error("OF tunnel interface is not available in config DS for source dpn {}", srcDpn);
722 return Futures.immediateFuture(resultBld.build());
725 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
726 .child(ExternalTunnel.class,
727 new ExternalTunnelKey(dstIp.stringValue(), srcDpn.toString(), input.getTunnelType()));
729 Optional<ExternalTunnel> optExtTunnel = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
731 if (optExtTunnel != null && optExtTunnel.isPresent()) {
732 ExternalTunnel extTunnel = optExtTunnel.get();
733 GetInternalOrExternalInterfaceNameOutputBuilder output =
734 new GetInternalOrExternalInterfaceNameOutputBuilder()
735 .setInterfaceName(extTunnel.getTunnelInterfaceName());
736 resultBld = RpcResultBuilder.success();
737 resultBld.withResult(output.build()) ;
739 Collection<DPNTEPsInfo> meshedDpnList = dpnTEPsInfoCache.getAllPresent();
741 // Look for external tunnels if not look for internal tunnel
742 for (DPNTEPsInfo teps : meshedDpnList) {
743 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
744 if (dstIp.equals(firstEndPt.getIpAddress())) {
745 Optional<InternalTunnel> optTunnel = Optional.empty();
746 if (interfaceManager.isItmDirectTunnelsEnabled()) {
747 DpnTepInterfaceInfo interfaceInfo =
748 dpnTepStateCache.getDpnTepInterface(srcDpn, teps.getDPNID());
749 if (interfaceInfo != null) {
750 resultBld = RpcResultBuilder.success();
751 resultBld.withResult(new GetInternalOrExternalInterfaceNameOutputBuilder()
752 .setInterfaceName(interfaceInfo.getTunnelName())).build();
753 return Futures.immediateFuture(resultBld.build());
757 if (ItmUtils.isTunnelAggregationUsed(input.getTunnelType())) {
758 optTunnel = ItmUtils.getInternalTunnelFromDS(srcDpn, teps.getDPNID(),
759 TunnelTypeLogicalGroup.class, dataBroker);
760 LOG.debug("MULTIPLE_VxLAN_TUNNELS: getInternalOrExternalInterfaceName {}", optTunnel);
762 if (!optTunnel.isPresent()) {
763 optTunnel = ItmUtils.getInternalTunnelFromDS(srcDpn, teps.getDPNID(),
764 input.getTunnelType(), dataBroker);
766 if (optTunnel.isPresent()) {
767 InternalTunnel tunnel = optTunnel.get();
768 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
769 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
770 GetInternalOrExternalInterfaceNameOutputBuilder
772 new GetInternalOrExternalInterfaceNameOutputBuilder()
773 .setInterfaceName(tunnelInterfaces.get(0));
774 resultBld = RpcResultBuilder.success();
775 resultBld.withResult(output.build());
777 LOG.error("No tunnel interface found between source DPN {} ans destination IP {}", srcDpn,
782 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
787 return Futures.immediateFuture(resultBld.build());
790 @SuppressWarnings("checkstyle:IllegalCatch")
792 public ListenableFuture<RpcResult<DeleteL2GwDeviceOutput>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
793 final SettableFuture<RpcResult<DeleteL2GwDeviceOutput>> result = SettableFuture.create();
794 boolean foundVxlanTzone = false;
796 final IpAddress hwIp = input.getIpAddress();
797 final String nodeId = input.getNodeId();
798 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
799 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
800 containerPath, dataBroker);
801 if (transportZonesOptional.isPresent()) {
802 TransportZones transportZones = transportZonesOptional.get();
803 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
804 LOG.error("No teps configured");
805 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
806 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
809 for (TransportZone tzone : transportZones.getTransportZone()) {
810 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
813 foundVxlanTzone = true;
814 String transportZone = tzone.getZoneName();
815 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
816 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier
817 .builder(TransportZones.class)
818 .child(TransportZone.class,
819 new TransportZoneKey(transportZone))
820 .child(DeviceVteps.class, deviceVtepKey)
822 FluentFuture<?> future =
823 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(path));
824 future.addCallback(new FutureCallback<Object>() {
825 @Override public void onSuccess(Object voidInstance) {
826 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>success().build());
829 @Override public void onFailure(Throwable error) {
830 String msg = String.format("Unable to delete HwVtep %s from datastore", nodeId);
831 LOG.error("Unable to delete HwVtep {}, {} from datastore", nodeId, hwIp);
832 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
833 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
835 }, MoreExecutors.directExecutor());
838 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
839 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
843 if (!foundVxlanTzone) {
844 result.set(RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
845 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
850 } catch (Exception e) {
851 RpcResultBuilder<DeleteL2GwDeviceOutput> resultBuilder = RpcResultBuilder.<DeleteL2GwDeviceOutput>failed()
852 .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
853 return Futures.immediateFuture(resultBuilder.build());
857 @SuppressWarnings("checkstyle:IllegalCatch")
859 public ListenableFuture<RpcResult<AddL2GwDeviceOutput>> addL2GwDevice(AddL2GwDeviceInput input) {
861 final SettableFuture<RpcResult<AddL2GwDeviceOutput>> result = SettableFuture.create();
862 boolean foundVxlanTzone = false;
864 final IpAddress hwIp = input.getIpAddress();
865 final String nodeId = input.getNodeId();
866 //iterate through all transport zones and put TORs under vxlan
867 //if no vxlan tzone is cnfigured, return an error.
868 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
869 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
870 containerPath, dataBroker);
871 if (transportZonesOptional.isPresent()) {
872 TransportZones transportZones = transportZonesOptional.get();
873 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
874 LOG.error("No transportZone configured");
875 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
876 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
879 for (TransportZone tzone : transportZones.getTransportZone()) {
880 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
883 String transportZone = tzone.getZoneName();
884 foundVxlanTzone = true;
885 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
886 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier
887 .builder(TransportZones.class)
888 .child(TransportZone.class,
889 new TransportZoneKey(transportZone))
890 .child(DeviceVteps.class, deviceVtepKey)
892 DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey).setIpAddress(hwIp)
893 .setNodeId(nodeId).setTopologyId(input.getTopologyId()).build();
894 //TO DO: add retry if it fails
895 FluentFuture<?> future = retryingTxRunner
896 .callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
897 tx -> tx.mergeParentStructurePut(path, deviceVtep));
899 future.addCallback(new FutureCallback<Object>() {
901 @Override public void onSuccess(Object voidInstance) {
902 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>success().build());
905 @Override public void onFailure(Throwable error) {
906 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
907 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
908 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
909 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
911 }, MoreExecutors.directExecutor());
915 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
916 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
920 if (!foundVxlanTzone) {
921 result.set(RpcResultBuilder.<AddL2GwDeviceOutput>failed()
922 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
927 } catch (Exception e) {
928 RpcResultBuilder<AddL2GwDeviceOutput> resultBuilder = RpcResultBuilder.<AddL2GwDeviceOutput>failed()
929 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
930 return Futures.immediateFuture(resultBuilder.build());
935 public ListenableFuture<RpcResult<GetWatchPortForTunnelOutput>> getWatchPortForTunnel(
936 GetWatchPortForTunnelInput input) {
937 throw new UnsupportedOperationException("TODO");
940 public ListenableFuture<RpcResult<GetTepIpOutput>> getTepIp(GetTepIpInput input) {
941 RpcResultBuilder<GetTepIpOutput> resultBld;
942 Uint64 sourceDpn = input.getDpnId();
943 Optional<OfDpnTep> dpnstep;
945 dpnstep = ofDpnTepConfigCache.get(sourceDpn.toJava());
946 } catch (ReadFailedException e) {
947 LOG.error("ReadFailedException: OF tunnel is not available in ITM for source dpn {} reason: {}",sourceDpn,
949 resultBld = RpcResultBuilder.failed();
950 return Futures.immediateFuture(resultBld.build());
952 if (dpnstep.isPresent()) {
953 resultBld = RpcResultBuilder.success();
954 resultBld.withResult(new GetTepIpOutputBuilder()
955 .setTepIp(dpnstep.get().getTepIp())).build();
956 return Futures.immediateFuture(resultBld.build());
958 LOG.error("OF tunnel is not available in ITM for source dpn {}",sourceDpn);
959 resultBld = RpcResultBuilder.failed();
960 return Futures.immediateFuture(resultBld.build());
964 @SuppressWarnings("checkstyle:IllegalCatch")
966 public ListenableFuture<RpcResult<AddL2GwMlagDeviceOutput>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input) {
968 final SettableFuture<RpcResult<AddL2GwMlagDeviceOutput>> result = SettableFuture.create();
970 final IpAddress hwIp = input.getIpAddress();
971 final List<String> nodeId = input.getNodeId();
972 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
973 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
974 containerPath, dataBroker);
975 if (transportZonesOptional.isPresent()) {
976 TransportZones transportZones = transportZonesOptional.get();
977 if (transportZones.getTransportZone() == null || transportZones.getTransportZone()
979 LOG.error("No teps configured");
980 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
981 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
984 for (TransportZone tzone : transportZones.getTransportZone()) {
985 if (!TunnelTypeVxlan.class.equals(tzone.getTunnelType())) {
988 String transportZone = tzone.getZoneName();
989 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
990 InstanceIdentifier<DeviceVteps> path =
991 InstanceIdentifier.builder(TransportZones.class)
992 .child(TransportZone.class, new TransportZoneKey(transportZone))
993 .child(DeviceVteps.class, deviceVtepKey).build();
994 DeviceVteps deviceVtep = new DeviceVtepsBuilder().withKey(deviceVtepKey)
996 .setNodeId(nodeId.get(0)).setTopologyId(input.getTopologyId()).build();
997 LOG.trace("writing hWvtep{}", deviceVtep);
998 FluentFuture<?> future =
999 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
1001 tx.mergeParentStructurePut(path, deviceVtep);
1002 if (nodeId.size() == 2) {
1003 LOG.trace("second node-id {}", nodeId.get(1));
1004 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp,
1006 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier
1007 .builder(TransportZones.class)
1008 .child(TransportZone.class, new TransportZoneKey(transportZone))
1009 .child(DeviceVteps.class, deviceVtepKey2).build();
1010 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder()
1011 .withKey(deviceVtepKey2)
1012 .setIpAddress(hwIp).setNodeId(nodeId.get(1))
1013 .setTopologyId(input.getTopologyId()).build();
1014 LOG.trace("writing {}", deviceVtep2);
1015 tx.mergeParentStructurePut(path2, deviceVtep2);
1018 future.addCallback(new FutureCallback<Object>() {
1020 public void onSuccess(Object voidInstance) {
1021 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>success().build());
1025 public void onFailure(Throwable error) {
1027 .format("Unable to write HwVtep %s to datastore", nodeId);
1028 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
1029 result.set(RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
1030 .withError(RpcError.ErrorType.APPLICATION, msg, error)
1033 }, MoreExecutors.directExecutor());
1037 } catch (RuntimeException e) {
1038 RpcResultBuilder<AddL2GwMlagDeviceOutput> resultBuilder = RpcResultBuilder.<AddL2GwMlagDeviceOutput>failed()
1039 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
1040 return Futures.immediateFuture(resultBuilder.build());
1044 @SuppressWarnings("checkstyle:IllegalCatch")
1046 public ListenableFuture<RpcResult<DeleteL2GwMlagDeviceOutput>> deleteL2GwMlagDevice(
1047 DeleteL2GwMlagDeviceInput input) {
1048 final SettableFuture<RpcResult<DeleteL2GwMlagDeviceOutput>> result = SettableFuture.create();
1050 final IpAddress hwIp = input.getIpAddress();
1051 final List<String> nodeId = input.getNodeId();
1052 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
1053 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
1054 containerPath, dataBroker);
1055 if (transportZonesOptional.isPresent()) {
1056 TransportZones tzones = transportZonesOptional.get();
1057 if (tzones.getTransportZone() == null || tzones.getTransportZone().isEmpty()) {
1058 LOG.error("No teps configured");
1059 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed()
1060 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
1063 String transportZone = tzones.getTransportZone().get(0).getZoneName();
1064 FluentFuture<?> future =
1065 retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
1067 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
1068 InstanceIdentifier<DeviceVteps> path =
1069 InstanceIdentifier.builder(TransportZones.class)
1070 .child(TransportZone.class, new TransportZoneKey(transportZone))
1071 .child(DeviceVteps.class,
1072 deviceVtepKey).build();
1074 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
1075 InstanceIdentifier<DeviceVteps> path2 =
1076 InstanceIdentifier.builder(TransportZones.class)
1077 .child(TransportZone.class, new TransportZoneKey(transportZone))
1078 .child(DeviceVteps.class,
1079 deviceVtepKey2).build();
1084 future.addCallback(new FutureCallback<Object>() {
1087 public void onSuccess(Object voidInstance) {
1088 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>success().build());
1092 public void onFailure(Throwable error) {
1093 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
1094 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
1095 result.set(RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed()
1096 .withError(RpcError.ErrorType.APPLICATION, msg, error)
1099 }, MoreExecutors.directExecutor());
1102 } catch (Exception e) {
1103 RpcResultBuilder<DeleteL2GwMlagDeviceOutput> resultBuilder =
1104 RpcResultBuilder.<DeleteL2GwMlagDeviceOutput>failed().withError(RpcError.ErrorType.APPLICATION,
1105 "Deleting l2 Gateway to DS Failed", e);
1106 return Futures.immediateFuture(resultBuilder.build());
1111 public ListenableFuture<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
1112 IsTunnelInternalOrExternalInput input) {
1113 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
1114 String tunIfName = input.getTunnelInterfaceName();
1116 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder()
1117 .setTunnelType(tunVal);
1119 if (ItmUtils.ITM_CACHE.getInternalTunnel(tunIfName) != null) {
1121 } else if (ItmUtils.ITM_CACHE.getExternalTunnel(tunIfName) != null) {
1124 output.setTunnelType(tunVal);
1125 resultBld = RpcResultBuilder.success();
1126 resultBld.withResult(output.build());
1127 return Futures.immediateFuture(resultBld.build());
1131 public ListenableFuture<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
1132 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
1134 Map<DcGatewayIpKey, DcGatewayIp> dcGatewayIpList = new HashMap<>();
1135 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
1136 tx -> dcGatewayIpList.putAll(getDcGatewayIpList(tx))).isDone();
1137 String dcgwIpStr = input.getDcgwIp();
1138 IpAddress dcgwIpAddr = IpAddressBuilder.getDefaultInstance(dcgwIpStr);
1141 if (!dcGatewayIpList.isEmpty()
1142 && dcGatewayIpList.values().stream().anyMatch(gwIp -> Objects.equal(gwIp.getIpAddress(), dcgwIpAddr))) {
1145 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
1146 resultBld.withResult(output.build());
1150 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
1151 resultBld.withResult(output.build());
1153 return Futures.immediateFuture(resultBld.build());
1157 public ListenableFuture<RpcResult<GetDpnEndpointIpsOutput>> getDpnEndpointIps(GetDpnEndpointIpsInput input) {
1158 Uint64 srcDpn = input.getSourceDpid();
1159 RpcResultBuilder<GetDpnEndpointIpsOutput> resultBld = failed();
1160 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
1161 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class,
1162 new DPNTEPsInfoKey(srcDpn)).build();
1163 Optional<DPNTEPsInfo> tunnelInfo = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, tunnelInfoId, dataBroker);
1164 if (!tunnelInfo.isPresent()) {
1165 LOG.error("tunnelInfo is not present");
1166 return Futures.immediateFuture(resultBld.build());
1169 List<TunnelEndPoints> tunnelEndPointList = tunnelInfo.get().getTunnelEndPoints();
1170 if (tunnelEndPointList == null || tunnelEndPointList.isEmpty()) {
1171 LOG.error("tunnelEndPointList is null or empty");
1172 return Futures.immediateFuture(resultBld.build());
1175 List<IpAddress> nexthopIpList = new ArrayList<>();
1176 tunnelEndPointList.forEach(tunnelEndPoint -> nexthopIpList.add(tunnelEndPoint.getIpAddress()));
1178 GetDpnEndpointIpsOutputBuilder output = new GetDpnEndpointIpsOutputBuilder().setNexthopipList(nexthopIpList);
1179 resultBld = RpcResultBuilder.success();
1180 resultBld.withResult(output.build()) ;
1181 return Futures.immediateFuture(resultBld.build());
1185 public ListenableFuture<RpcResult<GetDpnInfoOutput>> getDpnInfo(GetDpnInfoInput input) {
1186 return FutureRpcResults.fromListenableFuture(LOG, "getDpnInfo", input,
1187 () -> Futures.immediateFuture(getDpnInfoInternal(input))).build();
1190 private GetDpnInfoOutput getDpnInfoInternal(GetDpnInfoInput input) throws ReadFailedException {
1191 Map<String, Uint64> computeNamesVsDpnIds
1192 = getDpnIdByComputeNodeNameFromOpInventoryNodes(input.getComputeNames());
1193 Map<Uint64, ComputesBuilder> dpnIdVsVtepsComputes
1194 = getTunnelEndPointByDpnIdFromTranPortZone(computeNamesVsDpnIds.values());
1195 List<Computes> computes = computeNamesVsDpnIds.entrySet().stream()
1196 .map(entry -> dpnIdVsVtepsComputes.get(entry.getValue()).setComputeName(entry.getKey()).build())
1197 .collect(Collectors.toList());
1198 return new GetDpnInfoOutputBuilder().setComputes(computes).build();
1201 private Map<Uint64, ComputesBuilder> getTunnelEndPointByDpnIdFromTranPortZone(Collection<Uint64> dpnIds)
1202 throws ReadFailedException {
1203 TransportZones transportZones = singleTransactionDataBroker.syncRead(
1204 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(TransportZones.class).build());
1205 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
1206 throw new IllegalStateException("Failed to find transport zones in config datastore");
1208 Map<Uint64, ComputesBuilder> result = new HashMap<>();
1209 for (TransportZone transportZone : transportZones.getTransportZone()) {
1210 for (Vteps vtep : transportZone.getVteps().values()) {
1211 if (dpnIds.contains(vtep.getDpnId())) {
1212 result.putIfAbsent(vtep.getDpnId(),
1213 new ComputesBuilder()
1214 .setZoneName(transportZone.getZoneName())
1215 .setDpnId(vtep.getDpnId())
1216 .setNodeId(getNodeId(vtep.getDpnId()))
1217 .setTepIp(Collections.singletonList(vtep.getIpAddress())));
1221 for (Uint64 dpnId : dpnIds) {
1222 if (!result.containsKey(dpnId)) {
1223 throw new IllegalStateException("Failed to find dpn id " + dpnId + " in transport zone");
1229 private Map<String, Uint64> getDpnIdByComputeNodeNameFromOpInventoryNodes(List<String> nodeNames)
1230 throws ReadFailedException {
1231 Nodes operInventoryNodes = singleTransactionDataBroker.syncRead(
1232 LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(Nodes.class).build());
1233 if (operInventoryNodes.getNode() == null || operInventoryNodes.getNode().isEmpty()) {
1234 throw new IllegalStateException("Failed to find operational inventory nodes datastore");
1236 Map<String, Uint64> result = new HashMap<>();
1237 for (Node node : operInventoryNodes.getNode().values()) {
1238 String name = node.augmentation(FlowCapableNode.class).getDescription();
1239 if (nodeNames.contains(name)) {
1240 String[] nodeId = node.getId().getValue().split(":");
1241 result.put(name, Uint64.valueOf(nodeId[1]));
1244 for (String nodeName : nodeNames) {
1245 if (!result.containsKey(nodeName)) {
1246 throw new IllegalStateException("Failed to find dpn id of compute node name from oper inventory "
1253 private String getNodeId(Uint64 dpnId) throws ReadFailedException {
1254 InstanceIdentifier<BridgeRefEntry> path = InstanceIdentifier
1255 .builder(BridgeRefInfo.class)
1256 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId)).build();
1257 BridgeRefEntry bridgeRefEntry =
1258 singleTransactionDataBroker.syncRead(LogicalDatastoreType.OPERATIONAL, path);
1259 return bridgeRefEntry.getBridgeReference().getValue()
1260 .firstKeyOf(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
1261 .network.topology.topology.Node.class).getNodeId().getValue();
1264 private ListenableFuture<GetEgressActionsForTunnelOutput>
1265 getEgressActionsForInternalTunnels(String interfaceName, Long tunnelKey, Integer actionKey)
1266 throws ExecutionException, InterruptedException, OperationFailedException {
1268 if (interfaceName.startsWith("of")) {
1269 Optional<OfTep> oftep = ofTepStateCache.get(interfaceName);
1270 if (!oftep.isPresent()) {
1271 throw new IllegalStateException("Interface information not present in oper DS for" + interfaceName);
1273 List<ActionInfo> actions = getEgressActionInfosForOpenFlowTunnel(oftep.get().getIfIndex(),
1274 oftep.get().getTepIp(), tunnelKey, actionKey);
1275 return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
1276 .setAction(actions.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
1278 DpnTepInterfaceInfo interfaceInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
1279 if (interfaceInfo == null) {
1280 throw new IllegalStateException("Interface information not present in config DS for" + interfaceName);
1283 String tunnelType = ItmUtils.convertTunnelTypetoString(interfaceInfo.getTunnelType());
1284 if (!tunnelType.equalsIgnoreCase(ITMConstants.TUNNEL_TYPE_VXLAN)) {
1285 throw new IllegalArgumentException(tunnelType + " tunnel not handled by ITM");
1288 Optional<DPNTEPsInfo> dpntePsInfoOptional = dpnTEPsInfoCache.get(InstanceIdentifier
1289 .builder(DpnEndpoints.class)
1290 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(
1291 // FIXME: the cache should be caching this value, not just as a String
1292 Uint64.valueOf(dpnTepStateCache.getTunnelEndPointInfoFromCache(
1293 interfaceInfo.getTunnelName()).getDstEndPointInfo())))
1296 if (dpntePsInfoOptional.isPresent()) {
1297 dstId = dpntePsInfoOptional.get().getDstId();
1299 dstId = directTunnelUtils.allocateId(ITMConstants.ITM_IDPOOL_NAME,
1300 interfaceInfo.getRemoteDPN().toString());
1303 List<ActionInfo> result = new ArrayList<>();
1304 long regValue = MetaDataUtil.getRemoteDpnMetadatForEgressTunnelTable(dstId);
1305 int actionKeyStart = actionKey == null ? 0 : actionKey;
1306 result.add(new ActionSetFieldTunnelId(actionKeyStart++,
1307 Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L)));
1308 result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, MetaDataUtil.REG6_START_INDEX,
1309 MetaDataUtil.REG6_END_INDEX, regValue));
1310 result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_TUNNEL_TABLE));
1312 return Futures.immediateFuture(new GetEgressActionsForTunnelOutputBuilder()
1313 .setAction(result.stream().map(ActionInfo::buildAction).collect(Collectors.toList())).build());
1317 private static List<ActionInfo> getEgressActionInfosForOpenFlowTunnel(Uint16 ifIndex, IpAddress ipAddress,
1318 Long tunnelKey, Integer actionKey) {
1319 List<ActionInfo> result = new ArrayList<>();
1320 int actionKeyStart = actionKey == null ? 0 : actionKey;
1321 result.add(new ActionSetFieldTunnelId(actionKeyStart++,
1322 Uint64.valueOf(tunnelKey != null ? tunnelKey : 0L)));
1323 long regValue = MetaDataUtil.getReg6ValueForLPortDispatcher(ifIndex.intValue() ,
1324 NwConstants.DEFAULT_SERVICE_INDEX);
1325 result.add(new ActionRegLoad(actionKeyStart++, NxmNxReg6.class, ITMConstants.REG6_START_INDEX,
1326 ITMConstants.REG6_END_INDEX, regValue));
1327 result.add(new ActionNxResubmit(actionKeyStart, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE));
1332 public static Map<DcGatewayIpKey, DcGatewayIp>
1333 getDcGatewayIpList(TypedReadWriteTransaction<Datastore.Configuration> tx)
1334 throws ExecutionException, InterruptedException {
1335 Map<DcGatewayIpKey, DcGatewayIp> dcGatewayIpMap = new HashMap<>();
1336 FluentFuture<Optional<DcGatewayIpList>> future =
1337 tx.read(InstanceIdentifier.builder(DcGatewayIpList.class).build());
1338 future.addCallback(new FutureCallback<Optional<DcGatewayIpList>>() {
1340 public void onSuccess(Optional<DcGatewayIpList> optional) {
1342 // FIXME: why not just use the provided optional?
1343 Optional<DcGatewayIpList> opt = future.get();
1344 if (opt.isPresent()) {
1345 DcGatewayIpList list = opt.get();
1347 dcGatewayIpMap.putAll(list.getDcGatewayIp());
1350 } catch (ExecutionException | InterruptedException e) {
1351 LOG.error("DcGateway IpList read failed", e);
1356 public void onFailure(Throwable error) {
1357 LOG.error("DcGateway IpList read failed", error);
1359 }, MoreExecutors.directExecutor());
1360 return dcGatewayIpMap;