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.vpnmanager;
10 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
17 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
18 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
19 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.Tunnel;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import java.math.BigInteger;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.concurrent.Callable;
33 public class InterfaceStateChangeListener extends AsyncDataTreeChangeListenerBase<Interface,
34 InterfaceStateChangeListener> implements AutoCloseable {
35 private static final Logger LOG = LoggerFactory.getLogger(InterfaceStateChangeListener.class);
36 private final DataBroker dataBroker;
37 private final VpnInterfaceManager vpnInterfaceManager;
39 public InterfaceStateChangeListener(final DataBroker dataBroker, VpnInterfaceManager vpnInterfaceManager) {
40 super(Interface.class, InterfaceStateChangeListener.class);
41 this.dataBroker = dataBroker;
42 this.vpnInterfaceManager = vpnInterfaceManager;
46 LOG.info("{} start", getClass().getSimpleName());
47 registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
52 protected InstanceIdentifier<Interface> getWildCardPath() {
53 return InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
57 protected InterfaceStateChangeListener getDataTreeChangeListener() {
58 return InterfaceStateChangeListener.this;
63 protected void add(InstanceIdentifier<Interface> identifier, Interface intrf) {
64 LOG.trace("Received interface {} add event", intrf);
65 LOG.info("Received interface {} add event", intrf.getName());
67 final String interfaceName = intrf.getName();
68 LOG.info("Received interface add event for interface {} ", interfaceName);
69 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface
70 configInterface = InterfaceUtils.getInterface(dataBroker, interfaceName);
71 if (configInterface != null) {
72 if (!configInterface.getType().equals(Tunnel.class)) {
73 // We service only VM interfaces and Router interfaces here.
74 // We donot service Tunnel Interfaces here.
75 // Tunnel events are directly serviced
76 // by TunnelInterfacesStateListener present as part of VpnInterfaceManager
77 LOG.debug("Config Interface Name {}", configInterface.getName());
78 final VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
79 if (vpnInterface != null) {
80 LOG.debug("VPN Interface Name {}", vpnInterface);
81 BigInteger intfDpnId = BigInteger.ZERO;
83 intfDpnId = InterfaceUtils.getDpIdFromInterface(intrf);
84 } catch (Exception e){
85 LOG.error("Unable to retrieve dpnId for interface {}. Process vpn interface add fail with exception {}.",
89 final BigInteger dpnId = intfDpnId;
90 final int ifIndex = intrf.getIfIndex();
91 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
92 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + intrf.getName(),
93 new Callable<List<ListenableFuture<Void>>>() {
95 public List<ListenableFuture<Void>> call() throws Exception {
96 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
97 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
98 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
99 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnInterface, ifIndex, false,
100 writeConfigTxn, writeOperTxn, writeInvTxn);
101 String routerName = VpnUtil.getNeutronRouterFromInterface(dataBroker, interfaceName);
102 if (routerName != null) {
103 LOG.debug("Router Name {} ", routerName);
104 handleRouterInterfacesUpEvent(routerName, interfaceName, writeOperTxn);
106 LOG.info("Unable to process add for interface {} for NAT service", interfaceName);
108 List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
109 futures.add(writeOperTxn.submit());
110 futures.add(writeConfigTxn.submit());
111 futures.add(writeInvTxn.submit());
118 LOG.error("Unable to process add for interface {} ," +
119 "since Interface ConfigDS entry absent for the same", interfaceName);
121 } catch (Exception e) {
122 LOG.error("Exception caught in Interface Operational State Up event", e);
127 protected void remove(InstanceIdentifier<Interface> identifier, Interface intrf) {
128 LOG.trace("Received interface {} down event", intrf);
129 LOG.info("Received interface {} remove event", intrf.getName());
131 final String interfaceName = intrf.getName();
132 LOG.info("Received port DOWN event for interface {} ", interfaceName);
133 if (intrf != null && intrf.getType() != null && !intrf.getType().equals(Tunnel.class)) {
134 BigInteger dpId = BigInteger.ZERO;
135 InstanceIdentifier<VpnInterface> id = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
136 Optional<VpnInterface> optVpnInterface = VpnUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
137 if (!optVpnInterface.isPresent()) {
138 LOG.debug("Interface {} is not a vpninterface, ignoring.", intrf.getName());
141 final VpnInterface vpnInterface = optVpnInterface.get();
143 dpId = InterfaceUtils.getDpIdFromInterface(intrf);
144 } catch (Exception e){
145 LOG.error("Unable to retrieve dpnId from interface operational data store for interface {}.Fetching from vpn interface op data store. ", intrf.getName(), e);
146 dpId = vpnInterface.getDpnId();
148 final BigInteger dpnId = dpId;
149 final int ifIndex = intrf.getIfIndex();
150 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
151 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + intrf.getName(),
152 new Callable<List<ListenableFuture<Void>>>() {
154 public List<ListenableFuture<Void>> call() throws Exception {
155 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
156 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
157 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
158 vpnInterfaceManager.processVpnInterfaceDown(dpnId, interfaceName, ifIndex, false, false,
159 writeConfigTxn, writeOperTxn, writeInvTxn);
160 RouterInterface routerInterface = VpnUtil.getConfiguredRouterInterface(dataBroker, interfaceName);
161 if (routerInterface != null) {
162 handleRouterInterfacesDownEvent(routerInterface.getRouterName(), interfaceName, dpnId, writeOperTxn);
164 List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
165 futures.add(writeOperTxn.submit());
166 futures.add(writeConfigTxn.submit());
167 futures.add(writeInvTxn.submit());
172 } catch (Exception e) {
173 LOG.error("Exception observed in handling deletion of VPN Interface {}. ", intrf.getName(), e);
178 protected void update(InstanceIdentifier<Interface> identifier,
179 Interface original, Interface update) {
180 LOG.trace("Operation Interface update event - Old: {}, New: {}", original, update);
181 final String interfaceName = update.getName();
182 if (original.getOperStatus().equals(Interface.OperStatus.Unknown) ||
183 update.getOperStatus().equals(Interface.OperStatus.Unknown)){
184 LOG.debug("Interface {} state change is from/to UNKNOWN. Ignoring the update event.", interfaceName);
187 final BigInteger dpnId = InterfaceUtils.getDpIdFromInterface(update);
189 if (update.getIfIndex() == null) {
192 if (update != null && (update.getType() != null)) {
193 if (!update.getType().equals(Tunnel.class)) {
194 final VpnInterface vpnInterface = VpnUtil.getConfiguredVpnInterface(dataBroker, interfaceName);
195 if (vpnInterface != null) {
196 final int ifIndex = update.getIfIndex();
197 if (update.getOperStatus().equals(Interface.OperStatus.Up)) {
198 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
199 dataStoreCoordinator.enqueueJob("VPNINTERFACE-" + interfaceName,
200 new Callable<List<ListenableFuture<Void>>>() {
202 public List<ListenableFuture<Void>> call() throws Exception {
203 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
204 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
205 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
206 vpnInterfaceManager.processVpnInterfaceUp(dpnId, vpnInterface, ifIndex,
207 true, writeConfigTxn, writeOperTxn, writeInvTxn);
208 List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
209 futures.add(writeOperTxn.submit());
210 futures.add(writeConfigTxn.submit());
211 futures.add(writeInvTxn.submit());
215 } else if (update.getOperStatus().equals(Interface.OperStatus.Down)) {
216 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
217 dataStoreCoordinator.enqueueJob(interfaceName,
218 new Callable<List<ListenableFuture<Void>>>() {
220 public List<ListenableFuture<Void>> call() throws Exception {
221 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
222 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
223 WriteTransaction writeInvTxn = dataBroker.newWriteOnlyTransaction();
224 vpnInterfaceManager.processVpnInterfaceDown(dpnId, interfaceName, ifIndex, true, false,
225 writeConfigTxn, writeOperTxn, writeInvTxn);
226 List<ListenableFuture<Void>> futures = new ArrayList<ListenableFuture<Void>>();
227 futures.add(writeOperTxn.submit());
228 futures.add(writeConfigTxn.submit());
229 futures.add(writeInvTxn.submit());
239 void handleRouterInterfacesUpEvent(String routerName, String interfaceName, WriteTransaction writeOperTxn) {
240 LOG.debug("Handling UP event for router interface {} in Router {}", interfaceName, routerName);
241 vpnInterfaceManager.addToNeutronRouterDpnsMap(routerName, interfaceName, writeOperTxn);
244 void handleRouterInterfacesDownEvent(String routerName, String interfaceName, BigInteger dpnId,
245 WriteTransaction writeOperTxn) {
246 LOG.debug("Handling DOWN event for router interface {} in Router {}", interfaceName, routerName);
247 vpnInterfaceManager.removeFromNeutronRouterDpnsMap(routerName, interfaceName, dpnId, writeOperTxn);