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.netvirt.natservice.internal;
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
11 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
13 import java.util.concurrent.locks.ReentrantLock;
14 import javax.annotation.PreDestroy;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
18 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
19 import org.opendaylight.genius.mdsalutil.MDSALUtil;
20 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
21 import org.opendaylight.infrautils.utils.concurrent.Executors;
22 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
25 import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.opendaylight.yangtools.yang.common.Uint64;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 public class NatRouterInterfaceListener extends AbstractAsyncDataTreeChangeListener<Interfaces> {
42 private static final Logger LOG = LoggerFactory.getLogger(NatRouterInterfaceListener.class);
43 private final DataBroker dataBroker;
44 private final ManagedNewTransactionRunner txRunner;
45 private final OdlInterfaceRpcService interfaceManager;
46 private final IMdsalApiManager mdsalManager;
47 private final NaptManager naptManager;
48 private final NeutronvpnService neutronVpnService;
51 public NatRouterInterfaceListener(final DataBroker dataBroker, final OdlInterfaceRpcService interfaceManager,
52 final IMdsalApiManager mdsalManager,final NaptManager naptManager,
53 final NeutronvpnService neutronvpnService) {
54 super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(RouterInterfacesMap.class)
55 .child(RouterInterfaces.class).child(Interfaces.class),
56 Executors.newListeningSingleThreadExecutor("NatRouterInterfaceListener", LOG));
57 this.dataBroker = dataBroker;
58 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
59 this.interfaceManager = interfaceManager;
60 this.mdsalManager = mdsalManager;
61 this.naptManager = naptManager;
62 this.neutronVpnService = neutronvpnService;
66 LOG.info("{} init", getClass().getSimpleName());
73 Executors.shutdownAndAwaitTermination(getExecutorService());
77 // TODO Clean up the exception handling
78 @SuppressWarnings("checkstyle:IllegalCatch")
79 public void add(InstanceIdentifier<Interfaces> identifier, Interfaces interfaceInfo) {
80 LOG.trace("add : Add event - key: {}, value: {}", interfaceInfo.key(), interfaceInfo);
81 final String routerId = identifier.firstKeyOf(RouterInterfaces.class).getRouterId().getValue();
82 final String interfaceName = interfaceInfo.getInterfaceId();
83 if (NatUtil.isRouterInterfacePort(dataBroker, interfaceName)) {
84 LOG.info("ADD: Ignoring Router Interface Port {} for processing of router {}", interfaceName, routerId);
88 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
89 NatUtil.getRouterInterfaceId(interfaceName), getRouterInterface(interfaceName, routerId));
90 } catch (Exception e) {
91 LOG.error("add: Unable to write data in RouterInterface model", e);
94 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
95 .state.Interface interfaceState = NatUtil.getInterfaceStateFromOperDS(dataBroker, interfaceName);
96 if (interfaceState != null) {
97 Uint64 dpId = NatUtil.getDpIdFromInterface(interfaceState);
98 if (dpId.equals(Uint64.ZERO)) {
99 LOG.warn("ADD : Could not retrieve dp id for interface {} to handle router {} association model",
100 interfaceName, routerId);
103 final ReentrantLock lock = NatUtil.lockForNat(dpId);
106 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL,
108 NatUtil.addToNeutronRouterDpnsMap(routerId, interfaceName, dpId, operTx);
109 NatUtil.addToDpnRoutersMap(routerId, interfaceName, dpId, operTx);
110 }), LOG, "Error processing NAT router interface addition");
114 LOG.info("ADD: Added neutron-router-dpns mapping for interface {} of router {}", interfaceName, routerId);
116 LOG.info("add : Interface {} not yet operational to handle router interface add event in router {}",
117 interfaceName, routerId);
122 public void remove(InstanceIdentifier<Interfaces> identifier, Interfaces interfaceInfo) {
123 LOG.trace("remove : Remove event - key: {}, value: {}", interfaceInfo.key(), interfaceInfo);
124 final String routerId = identifier.firstKeyOf(RouterInterfaces.class).getRouterId().getValue();
125 final String interfaceName = interfaceInfo.getInterfaceId();
126 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
127 interfaceState = NatUtil.getInterfaceStateFromOperDS(dataBroker, interfaceName);
128 if (interfaceState != null) {
129 Uint64 dpId = NatUtil.getDpIdFromInterface(interfaceState);
130 if (dpId.equals(Uint64.ZERO)) {
132 "REMOVE : Could not retrieve DPN ID for interface {} to handle router {} dissociation model",
133 interfaceName, routerId);
137 final ReentrantLock lock = NatUtil.lockForNat(dpId);
140 if (NatUtil.isSnatEnabledForRouterId(dataBroker, routerId)) {
141 NatUtil.removeSnatEntriesForPort(dataBroker, naptManager, mdsalManager, neutronVpnService,
142 interfaceName, routerId);
144 ListenableFutures.addErrorLogging(
145 txRunner.callWithNewReadWriteTransactionAndSubmit(OPERATIONAL, operTx -> {
146 //Delete the NeutronRouterDpnMap from the ODL:L3VPN operational model
148 .removeFromNeutronRouterDpnsMap(routerId, interfaceName, dpId, operTx);
149 //Delete the DpnRouterMap from the ODL:L3VPN operational model
150 NatUtil.removeFromDpnRoutersMap(dataBroker, routerId, interfaceName, dpId,
151 interfaceManager, operTx);
152 }), LOG, "Error handling NAT router interface removal");
153 //Delete the RouterInterfaces maintained in the ODL:L3VPN configuration model
155 .addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
156 confTx -> confTx.delete(NatUtil.getRouterInterfaceId(interfaceName))), LOG,
157 "Error handling NAT router interface removal");
165 public void update(InstanceIdentifier<Interfaces> identifier, Interfaces original, Interfaces update) {
166 LOG.trace("update key: {}, original: {}, update: {}", update.key(), original, update);
169 static RouterInterface getRouterInterface(String interfaceName, String routerName) {
170 return new RouterInterfaceBuilder().withKey(new RouterInterfaceKey(interfaceName))
171 .setInterfaceName(interfaceName).setRouterName(routerName).build();