2 * Copyright (c) 2015 - 2016 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.netvirt.fibmanager;
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.genius.mdsalutil.ActionInfo;
19 import org.opendaylight.genius.mdsalutil.ActionType;
20 import org.opendaylight.genius.mdsalutil.BucketInfo;
21 import org.opendaylight.genius.mdsalutil.GroupEntity;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
24 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
25 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddressBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthop;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.vpnnexthops.VpnNexthopKey;
61 import org.opendaylight.yangtools.yang.binding.DataObject;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
64 import org.opendaylight.yangtools.yang.common.RpcResult;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67 import org.opendaylight.genius.itm.globals.ITMConstants;
68 import org.opendaylight.genius.mdsalutil.*;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.ConfTransportTypeL3vpn;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.ConfTransportTypeL3vpnBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.*;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
77 import java.math.BigInteger;
78 import java.util.ArrayList;
79 import java.util.List;
80 import java.util.concurrent.ExecutionException;
81 import java.util.concurrent.Future;
83 public class NexthopManager implements AutoCloseable {
84 private static final Logger LOG = LoggerFactory.getLogger(NexthopManager.class);
85 private final DataBroker broker;
86 private IMdsalApiManager mdsalManager;
87 private OdlInterfaceRpcService interfaceManager;
88 private ItmRpcService itmManager;
89 private IdManagerService idManager;
90 private static final short LPORT_INGRESS_TABLE = 0;
91 private static final short LFIB_TABLE = 20;
92 private static final short FIB_TABLE = 21;
93 private static final short DEFAULT_FLOW_PRIORITY = 10;
94 private static final String NEXTHOP_ID_POOL_NAME = "nextHopPointerPool";
95 private static final long FIXED_DELAY_IN_MILLISECONDS = 4000;
96 private L3VPNTransportTypes configuredTransportTypeL3VPN = L3VPNTransportTypes.Invalid;
98 private static final FutureCallback<Void> DEFAULT_CALLBACK =
99 new FutureCallback<Void>() {
100 public void onSuccess(Void result) {
101 LOG.debug("Success in Datastore write operation");
103 public void onFailure(Throwable error) {
104 LOG.error("Error in Datastore write operation", error);
109 * Provides nexthop functions
110 * Creates group ID pool
112 * @param db - dataBroker reference
114 public NexthopManager(final DataBroker db) {
119 public void close() throws Exception {
120 LOG.info("NextHop Manager Closed");
123 public void setInterfaceManager(OdlInterfaceRpcService ifManager) {
124 this.interfaceManager = ifManager;
127 public void setMdsalManager(IMdsalApiManager mdsalManager) {
128 this.mdsalManager = mdsalManager;
131 public void setIdManager(IdManagerService idManager) {
132 this.idManager = idManager;
133 createNexthopPointerPool();
136 public void setITMRpcService(ItmRpcService itmManager) {
137 this.itmManager = itmManager;
140 protected void createNexthopPointerPool() {
141 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
142 .setPoolName(NEXTHOP_ID_POOL_NAME)
146 //TODO: Error handling
147 Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
148 LOG.trace("NextHopPointerPool result : {}", result);
151 private BigInteger getDpnId(String ofPortId) {
152 String[] fields = ofPortId.split(":");
153 BigInteger dpn = new BigInteger(fields[1]);
154 LOG.debug("DpnId: {}", dpn);
158 private String getNextHopKey(long vpnId, String ipAddress){
159 String nhKey = new String("nexthop." + vpnId + ipAddress);
163 private String getNextHopKey(String ifName, String ipAddress){
164 String nhKey = new String("nexthop." + ifName + ipAddress);
168 protected long createNextHopPointer(String nexthopKey) {
169 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
170 .setPoolName(NEXTHOP_ID_POOL_NAME).setIdKey(nexthopKey)
172 //TODO: Proper error handling once IdManager code is complete
174 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
175 RpcResult<AllocateIdOutput> rpcResult = result.get();
176 return rpcResult.getResult().getIdValue();
177 } catch (NullPointerException | InterruptedException | ExecutionException e) {
183 protected void removeNextHopPointer(String nexthopKey) {
184 ReleaseIdInput idInput = new ReleaseIdInputBuilder().
185 setPoolName(NEXTHOP_ID_POOL_NAME)
186 .setIdKey(nexthopKey).build();
188 Future<RpcResult<Void>> result = idManager.releaseId(idInput);
189 RpcResult<Void> rpcResult = result.get();
190 if(!rpcResult.isSuccessful()) {
191 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
193 } catch (InterruptedException | ExecutionException e) {
194 LOG.warn("Exception when getting Unique Id for key {}", nexthopKey, e);
198 protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
199 List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
201 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
202 interfaceManager.getEgressActionsForInterface(
203 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
204 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
205 if(!rpcResult.isSuccessful()) {
206 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName, rpcResult.getErrors());
208 List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions =
209 rpcResult.getResult().getAction();
210 for (Action action : actions) {
211 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
212 if (actionClass instanceof OutputActionCase) {
213 listActionInfo.add(new ActionInfo(ActionType.output,
214 new String[] {((OutputActionCase)actionClass).getOutputAction()
215 .getOutputNodeConnector().getValue()}));
216 } else if (actionClass instanceof PushVlanActionCase) {
217 listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
218 } else if (actionClass instanceof SetFieldCase) {
219 if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
220 int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
221 listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
222 new String[] { Long.toString(vlanVid) }));
227 } catch (InterruptedException | ExecutionException e) {
228 LOG.warn("Exception when egress actions for interface {}", ifName, e);
230 return listActionInfo;
233 protected String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId) {
234 Class<? extends TunnelTypeBase> tunType = getReqTunType(getReqTransType().toUpperCase());
236 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
237 .setSourceDpid(srcDpId)
238 .setDestinationDpid(dstDpId)
239 .setTunnelType(tunType).build());
240 RpcResult<GetTunnelInterfaceNameOutput> rpcResult = result.get();
241 if(!rpcResult.isSuccessful()) {
242 LOG.warn("RPC Call to getTunnelInterfaceId returned with Errors {}", rpcResult.getErrors());
244 return rpcResult.getResult().getInterfaceName();
246 } catch (InterruptedException | ExecutionException e) {
247 LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and {}", srcDpId, dstDpId, e);
253 protected String getTunnelInterfaceName(BigInteger srcDpId, IpAddress dstIp) {
254 Class<? extends TunnelTypeBase> tunType = getReqTunType(getReqTransType().toUpperCase());
256 Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> result = itmManager.getInternalOrExternalInterfaceName(new GetInternalOrExternalInterfaceNameInputBuilder()
257 .setSourceDpid(srcDpId)
258 .setDestinationIp(dstIp)
259 .setTunnelType(tunType).build());
260 RpcResult<GetInternalOrExternalInterfaceNameOutput> rpcResult = result.get();
261 if(!rpcResult.isSuccessful()) {
262 LOG.warn("RPC Call to getTunnelInterfaceName returned with Errors {}", rpcResult.getErrors());
264 return rpcResult.getResult().getInterfaceName();
266 } catch (InterruptedException | ExecutionException e) {
267 LOG.warn("Exception when getting tunnel interface Id for tunnel between {} and {}", srcDpId, dstIp, e);
273 public long createLocalNextHop(long vpnId, BigInteger dpnId,
274 String ifName, String ipAddress) {
275 long groupId = createNextHopPointer(getNextHopKey(vpnId, ipAddress));
276 String nextHopLockStr = new String(vpnId + ipAddress);
277 synchronized (nextHopLockStr.intern()) {
278 VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
279 LOG.trace("nexthop: {}", nexthop);
280 if (nexthop == null) {
281 Optional<Adjacency> adjacencyData =
282 read(LogicalDatastoreType.OPERATIONAL, getAdjacencyIdentifier(ifName, ipAddress));
283 String macAddress = adjacencyData.isPresent() ? adjacencyData.get().getMacAddress() : null;
284 List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
285 List<ActionInfo> listActionInfo = getEgressActionsForInterface(ifName);
286 BucketInfo bucket = new BucketInfo(listActionInfo);
288 if (macAddress != null) {
289 listActionInfo.add(0, new ActionInfo(ActionType.set_field_eth_dest, new String[]{macAddress}));
290 //listActionInfo.add(0, new ActionInfo(ActionType.pop_mpls, new String[]{}));
292 //FIXME: Log message here.
293 LOG.debug("mac address for new local nexthop is null");
295 listBucketInfo.add(bucket);
296 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
297 dpnId, groupId, ipAddress, GroupTypes.GroupIndirect, listBucketInfo);
300 addVpnNexthopToDS(dpnId, vpnId, ipAddress, groupId);
303 mdsalManager.syncInstallGroup(groupEntity, FIXED_DELAY_IN_MILLISECONDS);
306 //nexthop exists already; a new flow is going to point to it, increment the flowrefCount by 1
307 int flowrefCnt = nexthop.getFlowrefCount() + 1;
308 VpnNexthop nh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(flowrefCnt).build();
309 LOG.trace("Updating vpnnextHop {} for refCount {} to Operational DS", nh, flowrefCnt);
310 syncWrite(LogicalDatastoreType.OPERATIONAL, getVpnNextHopIdentifier(vpnId, ipAddress), nh, DEFAULT_CALLBACK);
318 protected void addVpnNexthopToDS(BigInteger dpnId, long vpnId, String ipPrefix, long egressPointer) {
320 InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(
322 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
324 // Add nexthop to vpn node
325 VpnNexthop nh = new VpnNexthopBuilder().
326 setKey(new VpnNexthopKey(ipPrefix)).
328 setIpAddress(ipPrefix).
330 setEgressPointer(egressPointer).build();
332 InstanceIdentifier<VpnNexthop> id1 = idBuilder
333 .child(VpnNexthop.class, new VpnNexthopKey(ipPrefix)).build();
334 LOG.trace("Adding vpnnextHop {} to Operational DS", nh);
335 syncWrite(LogicalDatastoreType.OPERATIONAL, id1, nh, DEFAULT_CALLBACK);
341 protected InstanceIdentifier<VpnNexthop> getVpnNextHopIdentifier(long vpnId, String ipAddress) {
342 InstanceIdentifier<VpnNexthop> id = InstanceIdentifier.builder(
344 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId)).child(VpnNexthop.class, new VpnNexthopKey(ipAddress)).build();
348 protected VpnNexthop getVpnNexthop(long vpnId, String ipAddress) {
350 // check if vpn node is there
351 InstanceIdentifierBuilder<VpnNexthops> idBuilder =
352 InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class,
353 new VpnNexthopsKey(vpnId));
354 InstanceIdentifier<VpnNexthops> id = idBuilder.build();
355 Optional<VpnNexthops> vpnNexthops = read(LogicalDatastoreType.OPERATIONAL, id);
356 if (vpnNexthops.isPresent()) {
357 // get nexthops list for vpn
358 List<VpnNexthop> nexthops = vpnNexthops.get().getVpnNexthop();
359 for (VpnNexthop nexthop : nexthops) {
360 if (nexthop.getIpAddress().equals(ipAddress)) {
362 LOG.trace("VpnNextHop : {}", nexthop);
366 // return null if not found
372 public String getRemoteNextHopPointer(BigInteger localDpnId, BigInteger remoteDpnId,
373 long vpnId, String prefixIp, String nextHopIp) {
374 String tunnelIfName = null;
375 LOG.trace("getRemoteNextHopPointer: input [localDpnId {} remoteDpnId {}, vpnId {}, prefixIp {}, nextHopIp {} ]",
376 localDpnId, remoteDpnId, vpnId, prefixIp, nextHopIp);
378 LOG.trace("getRemoteNextHopPointer: Calling ITM with localDpnId {} ", localDpnId);
379 if (nextHopIp != null && !nextHopIp.isEmpty()) {
381 // here use the config for tunnel type param
382 tunnelIfName = getTunnelInterfaceName(remoteDpnId, IpAddressBuilder.getDefaultInstance(nextHopIp));
383 }catch(Exception ex){
384 LOG.error("Error while retrieving nexthop pointer for nexthop {} : ", nextHopIp, ex.getMessage());
390 public BigInteger getDpnForPrefix(long vpnId, String prefixIp) {
391 VpnNexthop vpnNexthop = getVpnNexthop(vpnId, prefixIp);
392 BigInteger localDpnId = (vpnNexthop == null) ? null : vpnNexthop.getDpnId();
397 private void removeVpnNexthopFromDS(long vpnId, String ipPrefix) {
399 InstanceIdentifierBuilder<VpnNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
400 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId))
401 .child(VpnNexthop.class, new VpnNexthopKey(ipPrefix));
402 InstanceIdentifier<VpnNexthop> id = idBuilder.build();
404 LOG.trace("Removing vpn next hop from datastore : {}", id);
405 delete(LogicalDatastoreType.OPERATIONAL, id);
409 public void removeLocalNextHop(BigInteger dpnId, Long vpnId, String ipAddress) {
411 String nextHopLockStr = new String(vpnId + ipAddress);
412 synchronized (nextHopLockStr.intern()) {
413 VpnNexthop nh = getVpnNexthop(vpnId, ipAddress);
415 int newFlowrefCnt = nh.getFlowrefCount() - 1;
416 if (newFlowrefCnt == 0) { //remove the group only if there are no more flows using this group
417 GroupEntity groupEntity = MDSALUtil.buildGroupEntity(
418 dpnId, nh.getEgressPointer(), ipAddress, GroupTypes.GroupIndirect, null);
420 mdsalManager.removeGroup(groupEntity);
422 removeVpnNexthopFromDS(vpnId, ipAddress);
424 removeNextHopPointer(getNextHopKey(vpnId, ipAddress));
425 LOG.debug("Local Next hop for {} on dpn {} successfully deleted", ipAddress, dpnId);
427 //just update the flowrefCount of the vpnNexthop
428 VpnNexthop currNh = new VpnNexthopBuilder().setKey(new VpnNexthopKey(ipAddress)).setFlowrefCount(newFlowrefCnt).build();
429 LOG.trace("Updating vpnnextHop {} for refCount {} to Operational DS", currNh, newFlowrefCnt);
430 syncWrite(LogicalDatastoreType.OPERATIONAL, getVpnNextHopIdentifier(vpnId, ipAddress), currNh, DEFAULT_CALLBACK);
434 LOG.error("Local Next hop for {} on dpn {} not deleted", ipAddress, dpnId);
441 private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
442 InstanceIdentifier<T> path) {
444 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
446 Optional<T> result = Optional.absent();
448 result = tx.read(datastoreType, path).get();
449 } catch (Exception e) {
450 throw new RuntimeException(e);
456 private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
457 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
458 WriteTransaction tx = broker.newWriteOnlyTransaction();
459 tx.merge(datastoreType, path, data, true);
460 Futures.addCallback(tx.submit(), callback);
463 private <T extends DataObject> void syncWrite(LogicalDatastoreType datastoreType,
464 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
465 WriteTransaction tx = broker.newWriteOnlyTransaction();
466 tx.merge(datastoreType, path, data, true);
470 private <T extends DataObject> void delete(LogicalDatastoreType datastoreType, InstanceIdentifier<T> path) {
471 WriteTransaction tx = broker.newWriteOnlyTransaction();
472 tx.delete(datastoreType, path);
473 Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
476 private InstanceIdentifier<Adjacency> getAdjacencyIdentifier(String vpnInterfaceName, String ipAddress) {
477 return InstanceIdentifier.builder(VpnInterfaces.class)
478 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
479 Adjacencies.class).child(Adjacency.class, new AdjacencyKey(ipAddress)).build();
482 InstanceIdentifier<Adjacencies> getAdjListPath(String vpnInterfaceName) {
483 return InstanceIdentifier.builder(VpnInterfaces.class)
484 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).augmentation(
485 Adjacencies.class).build();
489 public void setConfTransType(String service,String transportType) {
491 if (!service.toUpperCase().equals("L3VPN")) {
492 System.out.println("Please provide a valid service name. Available value(s): L3VPN");
493 LOG.error("Incorrect service {} provided for setting the transport type.", service);
497 L3VPNTransportTypes transType = L3VPNTransportTypes.validateTransportType(transportType.toUpperCase());
499 if (transType != L3VPNTransportTypes.Invalid) {
500 configuredTransportTypeL3VPN = transType;
504 public void writeConfTransTypeConfigDS() {
505 FibUtil.syncWrite( broker, LogicalDatastoreType.CONFIGURATION, getConfTransportTypeIdentifier(),
506 createConfTransportType(configuredTransportTypeL3VPN.getTransportType()),
507 FibUtil.DEFAULT_CALLBACK);
510 public L3VPNTransportTypes getConfiguredTransportTypeL3VPN() {
511 return this.configuredTransportTypeL3VPN;
515 public String getReqTransType() {
516 if (configuredTransportTypeL3VPN == L3VPNTransportTypes.Invalid) {
518 * Restart scenario, Read from the ConfigDS.
519 * if the value is Unset, cache value as VxLAN.
521 LOG.trace("configureTransportType is not yet set.");
522 Optional<ConfTransportTypeL3vpn> configuredTransTypeFromConfig =
523 FibUtil.read(broker, LogicalDatastoreType.CONFIGURATION, getConfTransportTypeIdentifier());
525 if (configuredTransTypeFromConfig.isPresent()) {
526 if (configuredTransTypeFromConfig.get().getTransportType().equals(TunnelTypeGre.class)) {
527 configuredTransportTypeL3VPN.setL3VPNTransportTypes(ITMConstants.TUNNEL_TYPE_GRE);
529 configuredTransportTypeL3VPN.setL3VPNTransportTypes(ITMConstants.TUNNEL_TYPE_VXLAN);
531 LOG.trace("configuredTransportType set from config DS to " + getConfiguredTransportTypeL3VPN().getTransportType());
533 setConfTransType("L3VPN", L3VPNTransportTypes.VxLAN.getTransportType());
534 LOG.trace("configuredTransportType is not set in the Config DS. VxLAN as default will be used.");
537 LOG.trace("configuredTransportType is set as {}", getConfiguredTransportTypeL3VPN().getTransportType());
539 return getConfiguredTransportTypeL3VPN().getTransportType();
541 public InstanceIdentifier<ConfTransportTypeL3vpn> getConfTransportTypeIdentifier() {
542 return InstanceIdentifier.builder(ConfTransportTypeL3vpn.class).build();
545 private ConfTransportTypeL3vpn createConfTransportType (String type) {
546 ConfTransportTypeL3vpn confTransType;
547 if (type.equals(ITMConstants.TUNNEL_TYPE_GRE)) {
548 confTransType = new ConfTransportTypeL3vpnBuilder().setTransportType(TunnelTypeGre.class).build();
549 LOG.trace("Setting the confTransportType to GRE.");
550 } else if (type.equals(ITMConstants.TUNNEL_TYPE_VXLAN)) {
551 confTransType = new ConfTransportTypeL3vpnBuilder().setTransportType(TunnelTypeVxlan.class).build();
552 LOG.trace("Setting the confTransportType to VxLAN.");
554 LOG.trace("Invalid transport type {} passed to Config DS ", type);
555 confTransType = null;
557 return confTransType;
560 Class<? extends TunnelTypeBase> getReqTunType(String transportType) {
561 if (transportType.equals("VXLAN")) {
562 return TunnelTypeVxlan.class;
563 } else if (transportType.equals("GRE")) {
564 return TunnelTypeGre.class;
566 return TunnelTypeMplsOverGre.class;