2 * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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
9 package org.opendaylight.netvirt.vpnmanager;
11 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
12 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
14 import com.google.common.util.concurrent.FutureCallback;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.MoreExecutors;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashSet;
21 import java.util.List;
23 import javax.annotation.PostConstruct;
24 import javax.inject.Inject;
25 import javax.inject.Singleton;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
29 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
30 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
31 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
32 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
33 import org.opendaylight.netvirt.vpnmanager.api.InterfaceUtils;
34 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.Uint32;
42 import org.opendaylight.yangtools.yang.common.Uint64;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 public class TunnelEndPointChangeListener
48 extends AsyncDataTreeChangeListenerBase<TunnelEndPoints, TunnelEndPointChangeListener> {
49 private static final Logger LOG = LoggerFactory.getLogger(TunnelEndPointChangeListener.class);
51 private final DataBroker broker;
52 private final ManagedNewTransactionRunner txRunner;
53 private final VpnInterfaceManager vpnInterfaceManager;
54 private final JobCoordinator jobCoordinator;
55 private final VpnUtil vpnUtil;
56 private final IFibManager fibManager;
59 public TunnelEndPointChangeListener(final DataBroker broker, final VpnInterfaceManager vpnInterfaceManager,
60 final JobCoordinator jobCoordinator, VpnUtil vpnUtil, final IFibManager fibManager) {
61 super(TunnelEndPoints.class, TunnelEndPointChangeListener.class);
63 this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
64 this.vpnInterfaceManager = vpnInterfaceManager;
65 this.jobCoordinator = jobCoordinator;
66 this.vpnUtil = vpnUtil;
67 this.fibManager = fibManager;
72 LOG.info("{} start", getClass().getSimpleName());
73 registerListener(LogicalDatastoreType.CONFIGURATION, broker);
77 protected InstanceIdentifier<TunnelEndPoints> getWildCardPath() {
78 return InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class).child(TunnelEndPoints.class)
83 protected void remove(InstanceIdentifier<TunnelEndPoints> key, TunnelEndPoints tep) {
87 protected void update(InstanceIdentifier<TunnelEndPoints> key, TunnelEndPoints origTep,
88 TunnelEndPoints updatedTep) {
92 protected void add(InstanceIdentifier<TunnelEndPoints> key, TunnelEndPoints tep) {
93 Uint64 dpnId = key.firstIdentifierOf(DPNTEPsInfo.class).firstKeyOf(DPNTEPsInfo.class).getDPNID();
94 if (Uint64.ZERO.equals(dpnId)) {
95 LOG.warn("add: Invalid DPN id for TEP {}", tep.getInterfaceName());
99 List<VpnInstance> vpnInstances = VpnHelper.getAllVpnInstances(broker);
100 if (vpnInstances == null || vpnInstances.isEmpty()) {
101 LOG.warn("add: dpnId: {}: tep: {}: No VPN instances defined", dpnId, tep.getInterfaceName());
105 for (VpnInstance vpnInstance : vpnInstances) {
106 final String vpnName = vpnInstance.getVpnInstanceName();
107 final Uint32 vpnId = vpnUtil.getVpnId(vpnName);
108 LOG.info("add: Handling TEP {} add for VPN instance {}", tep.getInterfaceName(), vpnName);
109 final String primaryRd = vpnUtil.getPrimaryRd(vpnName);
110 if (!vpnUtil.isVpnPendingDelete(primaryRd)) {
111 List<VpnInterfaces> vpnInterfaces = vpnUtil.getDpnVpnInterfaces(vpnInstance, dpnId);
112 if (vpnInterfaces != null) {
113 for (VpnInterfaces vpnInterface : vpnInterfaces) {
114 String vpnInterfaceName = vpnInterface.getInterfaceName();
115 jobCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterfaceName,
117 final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces
118 .rev140508.interfaces.state.Interface
120 InterfaceUtils.getInterfaceStateFromOperDS(broker, vpnInterfaceName);
121 if (interfaceState == null) {
122 LOG.debug("add: Cannot retrieve interfaceState for vpnInterfaceName {}, "
123 + "cannot generate lPortTag and process adjacencies", vpnInterfaceName);
124 return Collections.emptyList();
126 final int lPortTag = interfaceState.getIfIndex();
127 List<ListenableFuture<Void>> futures = new ArrayList<>();
128 Set<String> prefixesForRefreshFib = new HashSet<>();
129 ListenableFuture<Void> writeConfigFuture =
130 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
131 writeConfigTxn -> futures.add(
132 txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL,
133 writeOperTxn -> futures.add(
134 txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
136 vpnInterfaceManager.processVpnInterfaceAdjacencies(dpnId,
137 lPortTag, vpnName, primaryRd, vpnInterfaceName, vpnId,
138 writeConfigTxn, writeOperTxn, writeInvTxn,
139 interfaceState, prefixesForRefreshFib)
141 Futures.addCallback(writeConfigFuture, new FutureCallback<Void>() {
143 public void onSuccess(Void voidObj) {
144 prefixesForRefreshFib.forEach(prefix -> {
145 fibManager.refreshVrfEntry(primaryRd, prefix);
150 public void onFailure(Throwable throwable) {
151 LOG.debug("addVpnInterface: write Tx config execution failed", throwable);
153 }, MoreExecutors.directExecutor());
154 futures.add(writeConfigFuture);
155 LOG.trace("add: Handled TEP {} add for VPN instance {} VPN interface {}",
156 tep.getInterfaceName(), vpnName, vpnInterfaceName);
162 LOG.error("add: Ignoring addition of tunnel interface {} dpn {} for vpnInstance {} with primaryRd {},"
163 + " as the VPN is already marked for deletion", tep.getInterfaceName(), dpnId,
170 protected TunnelEndPointChangeListener getDataTreeChangeListener() {