2 * Copyright (c) 2018 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.itmdirecttunnels.workers;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14 import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
15 import org.opendaylight.genius.itm.globals.ITMConstants;
16 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
17 import org.opendaylight.genius.itm.impl.ItmUtils;
18 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
19 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
20 import org.opendaylight.genius.itm.utils.TunnelStateInfo;
21 import org.opendaylight.mdsal.binding.util.Datastore;
22 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.IfIndexesTunnelMap;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnel;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210._if.indexes.tunnel.map.IfIndexTunnelKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelListKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.DstInfoBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.state.tunnel.list.SrcInfoBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.OperationFailedException;
42 import org.opendaylight.yangtools.yang.common.Uint64;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public final class TunnelStateAddWorker {
48 private static final Logger LOG = LoggerFactory.getLogger(TunnelStateAddWorker.class);
49 private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
51 private final DirectTunnelUtils directTunnelUtils;
52 private final ManagedNewTransactionRunner txRunner;
54 public TunnelStateAddWorker(final DirectTunnelUtils directTunnelUtils, final ManagedNewTransactionRunner txRunner) {
55 this.directTunnelUtils = directTunnelUtils;
56 this.txRunner = txRunner;
59 public List<? extends ListenableFuture<?>> addState(TunnelStateInfo tunnelStateInfo)
60 throws ExecutionException, InterruptedException, OperationFailedException {
62 // When this method is invoked, all parameters necessary should be available
63 // Retrieve Port No from nodeConnectorId
64 NodeConnectorId nodeConnectorId = InstanceIdentifier.keyOf(tunnelStateInfo.getNodeConnectorInfo()
65 .getNodeConnectorId().firstIdentifierOf(NodeConnector.class)).getId();
66 String tunnelName = tunnelStateInfo.getNodeConnectorInfo().getNodeConnector().getName();
67 if (tunnelName != null && tunnelName.startsWith("of")) {
68 tunnelName = tunnelStateInfo.getDpnTepInterfaceInfo().getTunnelName();
71 String interfaceName = tunnelName;
73 long portNo = DirectTunnelUtils.getPortNumberFromNodeConnectorId(nodeConnectorId);
74 EVENT_LOGGER.debug("ITM-TunnelState, ADD to oper DS {}", interfaceName);
75 if (portNo == ITMConstants.INVALID_PORT_NO) {
76 LOG.error("Cannot derive port number, not proceeding with Interface State addition for interface: {}",
78 EVENT_LOGGER.debug("ITM-TunnelState,ADD Table 0 flow for {} completed", interfaceName);
79 return Collections.emptyList();
82 LOG.info("adding interface state to Oper DS for interface: {}", interfaceName);
84 // Fetch the interface/Tunnel from config DS if exists
85 // If it doesnt exists then "park" the processing and comeback to it when the data is available and
86 // this will be triggered by the corres. listener. Caching and de-caching has to be synchronized.
87 StateTunnelList stateTnl = addStateEntry(interfaceName, portNo, tunnelStateInfo);
89 // This will be only tunnel If so not required
90 // If this interface is a tunnel interface, create the tunnel ingress flow,
91 // Egress flow for table 95 is installed based on dstId of the remote dpn,
92 // and start tunnel monitoring
93 if (stateTnl != null) {
94 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(Datastore.CONFIGURATION,
96 Uint64 dpId = DirectTunnelUtils.getDpnFromNodeConnectorId(nodeConnectorId);
97 directTunnelUtils.addTunnelIngressFlow(tx, dpId, portNo, interfaceName,
98 stateTnl.getIfIndex().toJava(),
99 tunnelStateInfo.getDstDpnTepsInfo().getTunnelEndPoints().get(0).getIpAddress()
101 directTunnelUtils.addTunnelEgressFlow(tx, dpId, String.valueOf(portNo),
102 tunnelStateInfo.getDstDpnTepsInfo().getDstId(), interfaceName,
103 tunnelStateInfo.getDstDpnTepsInfo().getTunnelEndPoints().get(0).getIpAddress());
106 return Collections.emptyList();
109 private StateTunnelList addStateEntry(String interfaceName, long portNo, TunnelStateInfo tunnelStateInfo)
110 throws ExecutionException, InterruptedException, OperationFailedException {
111 LOG.debug("Start addStateEntry adding interface state for {}", interfaceName);
112 final StateTunnelListBuilder stlBuilder = new StateTunnelListBuilder();
113 Class<? extends TunnelTypeBase> tunnelType;
114 DPNTEPsInfo srcDpnTepsInfo = tunnelStateInfo.getSrcDpnTepsInfo();
116 DpnTepInterfaceInfo dpnTepInfo = tunnelStateInfo.getDpnTepInterfaceInfo();
117 LOG.debug("Source Dpn TEP Interface Info {}", dpnTepInfo);
118 tunnelType = dpnTepInfo.getTunnelType();
120 final SrcInfoBuilder srcInfoBuilder =
121 new SrcInfoBuilder().setTepDeviceId(tunnelStateInfo.getTunnelEndPointInfo().getSrcEndPointInfo());
122 final DstInfoBuilder dstInfoBuilder =
123 new DstInfoBuilder().setTepDeviceId(tunnelStateInfo.getTunnelEndPointInfo().getDstEndPointInfo());
124 LOG.trace("Source Dpn TEP Info {}",srcDpnTepsInfo);
125 TunnelEndPoints srcEndPtInfo = srcDpnTepsInfo.getTunnelEndPoints().get(0);
126 srcInfoBuilder.setTepIp(srcEndPtInfo.getIpAddress());
127 // As ITM Direct Tunnels deals with only Internal Tunnels.
128 // Relook at this when it deals with external as well
129 srcInfoBuilder.setTepDeviceType(TepTypeInternal.class);
131 DPNTEPsInfo dstDpnTePsInfo = tunnelStateInfo.getDstDpnTepsInfo();
132 LOG.trace("Dest Dpn TEP Info {}", dstDpnTePsInfo);
133 TunnelEndPoints dstEndPtInfo = dstDpnTePsInfo.getTunnelEndPoints().get(0);
134 dstInfoBuilder.setTepIp(dstEndPtInfo.getIpAddress());
135 // As ITM Direct Tunnels deals with only Internal Tunnels.
136 // Relook at this when it deals with external as well
137 dstInfoBuilder.setTepDeviceType(TepTypeInternal.class);
139 Interface.OperStatus operStatus = Interface.OperStatus.Up;
141 // ITM Direct Tunnels NOT SETTING THE TEP TYPe coz its not available. CHECK IF REQUIRED
142 TunnelOperStatus tunnelOperStatus = DirectTunnelUtils.convertInterfaceToTunnelOperState(operStatus);
143 boolean tunnelState = operStatus.equals(Interface.OperStatus.Up);
145 StateTunnelListKey tlKey = new StateTunnelListKey(interfaceName);
146 stlBuilder.withKey(tlKey).setOperState(tunnelOperStatus).setTunnelState(tunnelState)
147 .setDstInfo(dstInfoBuilder.build()).setSrcInfo(srcInfoBuilder.build()).setTransportType(tunnelType)
148 .setPortNumber(String.valueOf(portNo));
149 int ifIndex = directTunnelUtils.allocateId(IfmConstants.IFM_IDPOOL_NAME, interfaceName);
150 createLportTagInterfaceMap(interfaceName, ifIndex);
151 stlBuilder.setIfIndex(ifIndex);
152 InstanceIdentifier<StateTunnelList> stListId = ItmUtils.buildStateTunnelListId(tlKey);
153 LOG.info("Batching the Creation of tunnel_state: {} for Id: {}", stlBuilder.build(), stListId);
154 ITMBatchingUtils.write(stListId, stlBuilder.build(), ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);
155 return stlBuilder.build();
158 private void createLportTagInterfaceMap(String infName, Integer ifIndex) {
159 LOG.debug("creating lport tag to interface map for {}", infName);
160 InstanceIdentifier<IfIndexTunnel> id = InstanceIdentifier.builder(IfIndexesTunnelMap.class)
161 .child(IfIndexTunnel.class, new IfIndexTunnelKey(ifIndex)).build();
162 IfIndexTunnel ifIndexInterface = new IfIndexTunnelBuilder().setIfIndex(ifIndex)
163 .withKey(new IfIndexTunnelKey(ifIndex)).setInterfaceName(infName).build();
164 ITMBatchingUtils.write(id, ifIndexInterface, ITMBatchingUtils.EntityType.DEFAULT_OPERATIONAL);