2 * Copyright (c) 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.genius.itm.confighelpers;
10 import com.google.common.util.concurrent.FutureCallback;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.genius.itm.globals.ITMConstants;
16 import org.opendaylight.genius.itm.impl.ItmUtils;
17 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpointsBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 import java.math.BigInteger;
35 import java.util.ArrayList;
36 import java.util.List;
38 public class ItmInternalTunnelAddWorker {
39 private static final Logger logger = LoggerFactory.getLogger(ItmInternalTunnelAddWorker.class) ;
40 private static final FutureCallback<Void> DEFAULT_CALLBACK =
41 new FutureCallback<Void>() {
42 public void onSuccess(Void result) {
43 logger.debug("Success in Datastore operation");
46 public void onFailure(Throwable error) {
47 logger.error("Error in Datastore operation", error);
52 public static List<ListenableFuture<Void>> build_all_tunnels(DataBroker dataBroker, IdManagerService idManagerService,IMdsalApiManager mdsalManager,
53 List<DPNTEPsInfo> cfgdDpnList, List<DPNTEPsInfo> meshedDpnList) {
54 logger.trace( "Building tunnels with DPN List {} " , cfgdDpnList );
55 List<ListenableFuture<Void>> futures = new ArrayList<>();
56 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
57 if( null == cfgdDpnList || cfgdDpnList.isEmpty()) {
58 logger.error(" Build Tunnels was invoked with empty list");
62 for( DPNTEPsInfo dpn : cfgdDpnList) {
63 //#####if dpn is not in meshedDpnList
64 build_tunnel_from(dpn, meshedDpnList, dataBroker, idManagerService, mdsalManager, t, futures);
65 if(null == meshedDpnList) {
66 meshedDpnList = new ArrayList<DPNTEPsInfo>() ;
68 meshedDpnList.add(dpn) ;
69 // Update the operational datastore -- FIXME -- Error Handling
70 updateOperationalDatastore(dataBroker, dpn, t, futures) ;
72 futures.add( t.submit()) ;
76 private static void updateOperationalDatastore(DataBroker dataBroker, DPNTEPsInfo dpn, WriteTransaction t, List<ListenableFuture<Void>> futures) {
77 logger.debug("Updating CONFIGURATION datastore with DPN {} ", dpn);
78 InstanceIdentifier<DpnEndpoints> dep = InstanceIdentifier.builder( DpnEndpoints.class).build() ;
79 List<DPNTEPsInfo> dpnList = new ArrayList<DPNTEPsInfo>() ;
81 DpnEndpoints tnlBuilder = new DpnEndpointsBuilder().setDPNTEPsInfo(dpnList).build() ;
82 t.merge(LogicalDatastoreType.CONFIGURATION, dep, tnlBuilder, true);
85 private static void build_tunnel_from( DPNTEPsInfo srcDpn,List<DPNTEPsInfo> meshedDpnList, DataBroker dataBroker, IdManagerService idManagerService, IMdsalApiManager mdsalManager, WriteTransaction t, List<ListenableFuture<Void>> futures) {
86 logger.trace( "Building tunnels from DPN {} " , srcDpn );
88 if( null == meshedDpnList || 0 == meshedDpnList.size()) {
89 logger.debug( "No DPN in the mesh ");
92 for( DPNTEPsInfo dstDpn: meshedDpnList) {
93 if ( ! srcDpn.equals(dstDpn) )
94 wireUpWithinTransportZone(srcDpn, dstDpn, dataBroker, idManagerService, mdsalManager, t, futures) ;
99 private static void wireUpWithinTransportZone( DPNTEPsInfo srcDpn, DPNTEPsInfo dstDpn, DataBroker dataBroker,
100 IdManagerService idManagerService, IMdsalApiManager mdsalManager,WriteTransaction t, List<ListenableFuture<Void>> futures) {
101 logger.trace( "Wiring up within Transport Zone for Dpns {}, {} " , srcDpn, dstDpn );
102 List<TunnelEndPoints> srcEndPts = srcDpn.getTunnelEndPoints();
103 List<TunnelEndPoints> dstEndPts = dstDpn.getTunnelEndPoints();
105 for( TunnelEndPoints srcte : srcEndPts) {
106 for( TunnelEndPoints dstte : dstEndPts ) {
107 // Compare the Transport zones
108 if (!srcDpn.getDPNID().equals(dstDpn.getDPNID())) {
109 if( (srcte.getTransportZone().equals(dstte.getTransportZone()))) {
111 wireUpBidirectionalTunnel( srcte, dstte, srcDpn.getDPNID(), dstDpn.getDPNID(), dataBroker, idManagerService, mdsalManager, t, futures );
112 // CHECK THIS -- Assumption -- One end point per Dpn per transport zone
120 private static void wireUpBidirectionalTunnel( TunnelEndPoints srcte, TunnelEndPoints dstte, BigInteger srcDpnId, BigInteger dstDpnId,
121 DataBroker dataBroker, IdManagerService idManagerService, IMdsalApiManager mdsalManager, WriteTransaction t, List<ListenableFuture<Void>> futures) {
122 // Setup the flow for LLDP monitoring -- PUNT TO CONTROLLER
123 ItmUtils.setUpOrRemoveTerminatingServiceTable(srcDpnId, mdsalManager, true);
124 ItmUtils.setUpOrRemoveTerminatingServiceTable(dstDpnId, mdsalManager, true);
126 // Create the forward direction tunnel
127 if(!wireUp( srcte, dstte, srcDpnId, dstDpnId, dataBroker, idManagerService, t, futures ))
128 logger.error("Could not build tunnel between end points {}, {} " , srcte, dstte );
130 // CHECK IF FORWARD IS NOT BUILT , REVERSE CAN BE BUILT
131 // Create the tunnel for the reverse direction
132 if(! wireUp( dstte, srcte, dstDpnId, srcDpnId, dataBroker, idManagerService, t, futures ))
133 logger.error("Could not build tunnel between end points {}, {} " , dstte, srcte);
136 private static boolean wireUp(TunnelEndPoints srcte, TunnelEndPoints dstte, BigInteger srcDpnId, BigInteger dstDpnId ,
137 DataBroker dataBroker, IdManagerService idManagerService, WriteTransaction t, List<ListenableFuture<Void>> futures) {
139 logger.trace( "Wiring between source tunnel end points {}, destination tunnel end points {} " , srcte, dstte );
140 String interfaceName = srcte.getInterfaceName() ;
141 Class<? extends TunnelTypeBase> tunType = srcte.getTunnelType();
142 String tunTypeStr = srcte.getTunnelType().getName();
143 // Form the trunk Interface Name
144 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName( idManagerService, interfaceName,
145 srcte.getIpAddress().getIpv4Address().getValue(),
146 dstte.getIpAddress().getIpv4Address().getValue(),
148 IpAddress gatewayIpObj = new IpAddress("0.0.0.0".toCharArray());
149 IpAddress gwyIpAddress = ( srcte.getSubnetMask().equals(dstte.getSubnetMask()) ) ? gatewayIpObj : srcte.getGwIpAddress() ;
150 logger.debug( " Creating Trunk Interface with parameters trunk I/f Name - {}, parent I/f name - {}, source IP - {}, destination IP - {} gateway IP - {}",trunkInterfaceName, interfaceName, srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress ) ;
151 Boolean monitorEnabled = ItmUtils.readMonitoringStateFromDS(dataBroker);
152 Integer monitorInterval = ItmUtils.determineMonitorInterval(dataBroker);
153 Class<? extends TunnelMonitoringTypeBase> monitorProtocol = ItmUtils.determineMonitorProtocol(dataBroker);
154 Interface iface = ItmUtils.buildTunnelInterface(srcDpnId, trunkInterfaceName, String.format( "%s %s",ItmUtils.convertTunnelTypetoString(srcte.getTunnelType()), "Trunk Interface"), true, tunType, srcte.getIpAddress(), dstte.getIpAddress(), gwyIpAddress, srcte.getVLANID(), true, monitorEnabled, monitorProtocol, monitorInterval);
155 logger.debug( " Trunk Interface builder - {} ", iface ) ;
156 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
157 logger.debug( " Trunk Interface Identifier - {} ", trunkIdentifier ) ;
158 logger.trace( " Writing Trunk Interface to Config DS {}, {} ", trunkIdentifier, iface ) ;
159 t.merge(LogicalDatastoreType.CONFIGURATION, trunkIdentifier, iface, true);
160 ItmUtils.itmCache.addInterface(iface);
161 // also update itm-state ds?
162 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
164 .child(InternalTunnel.class, new InternalTunnelKey( dstDpnId, srcDpnId, tunType));
165 InternalTunnel tnl = ItmUtils.buildInternalTunnel(srcDpnId, dstDpnId, tunType, trunkInterfaceName);
166 //ItmUtils.asyncUpdate(LogicalDatastoreType.CONFIGURATION, path, tnl, dataBroker, DEFAULT_CALLBACK);
167 t.merge(LogicalDatastoreType.CONFIGURATION,path, tnl, true) ;
168 ItmUtils.itmCache.addInternalTunnel(tnl);