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;
12 import com.google.common.base.Optional;
13 import java.util.Objects;
14 import java.util.concurrent.ExecutionException;
15 import javax.inject.Inject;
16 import javax.inject.Singleton;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
20 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
21 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
22 import org.opendaylight.genius.mdsalutil.MDSALUtil;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32 import org.opendaylight.yangtools.yang.common.Uint32;
33 import org.opendaylight.yangtools.yang.common.Uint64;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<VpnMap, NatVpnMapsChangeListener> {
39 private static final Logger LOG = LoggerFactory.getLogger(NatVpnMapsChangeListener.class);
40 private final DataBroker dataBroker;
41 private final ManagedNewTransactionRunner txRunner;
42 private final FloatingIPListener floatingIpListener;
43 private final OdlInterfaceRpcService interfaceManager;
44 private final ExternalRoutersListener externalRoutersListener;
47 public NatVpnMapsChangeListener(final DataBroker dataBroker,
48 final FloatingIPListener floatingIpListener,
49 final OdlInterfaceRpcService interfaceManager,
50 final ExternalRoutersListener externalRoutersListener) {
51 super(VpnMap.class, NatVpnMapsChangeListener.class);
52 this.dataBroker = dataBroker;
53 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
54 this.floatingIpListener = floatingIpListener;
55 this.interfaceManager = interfaceManager;
56 this.externalRoutersListener = externalRoutersListener;
60 LOG.info("{} init", getClass().getSimpleName());
61 registerListener(dataBroker);
65 protected InstanceIdentifier<VpnMap> getWildCardPath() {
66 return InstanceIdentifier.create(VpnMaps.class).child(VpnMap.class);
69 private void registerListener(final DataBroker db) {
70 registerListener(LogicalDatastoreType.CONFIGURATION, db);
74 protected void add(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
75 Uuid vpnUuid = vpnMap.getVpnId();
76 String vpnName = vpnUuid.getValue();
77 vpnMap.getRouterIds().stream()
78 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
80 String routerName = router.getRouterId().getValue();
81 LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
82 onRouterAssociatedToVpn(vpnName, routerName);
87 protected void remove(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
88 Uuid vpnUuid = vpnMap.getVpnId();
89 String vpnName = vpnUuid.getValue();
90 vpnMap.getRouterIds().stream()
91 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
93 String routerName = router.getRouterId().getValue();
94 LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
95 onRouterDisassociatedFromVpn(vpnName, routerName);
100 protected void update(InstanceIdentifier<VpnMap> identifier, VpnMap original, VpnMap updated) {
101 Uuid vpnUuid = updated.getVpnId();
102 String vpnName = vpnUuid.getValue();
104 updated.getRouterIds().stream()
105 .filter(router -> ! original.getRouterIds().contains(router))
106 .filter(router -> !(Objects.equals(router.getRouterId(), updated.getVpnId())))
108 String routerName = router.getRouterId().getValue();
109 onRouterAssociatedToVpn(vpnName, routerName);
112 original.getRouterIds().stream()
113 .filter(router -> ! updated.getRouterIds().contains(router))
114 .filter(router -> !(Objects.equals(router.getRouterId(), original.getVpnId())))
116 String routerName = router.getRouterId().getValue();
117 onRouterDisassociatedFromVpn(vpnName, routerName);
122 protected NatVpnMapsChangeListener getDataTreeChangeListener() {
126 public void onRouterAssociatedToVpn(String vpnName, String routerName) {
128 //check router is associated to external network
129 String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
130 if (extNetwork != null) {
132 LOG.debug("onRouterAssociatedToVpn : Router {} is associated with ext nw {}", routerName, extNetwork);
133 handleDNATConfigurationForRouterAssociation(routerName, vpnName, extNetwork);
134 Uuid extNetworkUuid = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
135 if (extNetworkUuid == null) {
136 LOG.error("onRouterAssociatedToVpn : Unable to retrieve external network Uuid for router {}",
140 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName,
142 if (extNwProvType == null) {
143 LOG.error("onRouterAssociatedToVpn : External Network Provider Type missing");
146 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
147 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
148 tx -> externalRoutersListener.changeLocalVpnIdToBgpVpnId(routerName, routerId, vpnName, tx,
149 extNwProvType)).get();
150 } catch (InterruptedException | ExecutionException e) {
151 LOG.error("Error changling local VPN identifier to BGP VPN identifier", e);
154 LOG.debug("onRouterAssociatedToVpn : Ignoring the Router {} association with VPN {} "
155 + "since it is not external router", routerName, vpnName);
160 * router disassociation from vpn.
163 public void onRouterDisassociatedFromVpn(String vpnName, String routerName) {
165 //check router is associated to external network
166 String extNetwork = NatUtil.getAssociatedExternalNetwork(dataBroker, routerName);
167 if (extNetwork != null) {
169 LOG.debug("onRouterDisassociatedFromVpn : Router {} is associated with ext nw {}", routerName,
171 handleDNATConfigurationForRouterDisassociation(routerName, vpnName, extNetwork);
172 Uuid extNetworkUuid = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
173 if (extNetworkUuid == null) {
174 LOG.error("onRouterDisassociatedFromVpn : Unable to retrieve external network Uuid for router {}",
178 ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker, routerName,
180 if (extNwProvType == null) {
181 LOG.error("onRouterDisassociatedFromVpn : External Network Provider Type missing");
184 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
185 txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION,
186 tx -> externalRoutersListener.changeBgpVpnIdToLocalVpnId(routerName, routerId, vpnName, tx,
187 extNwProvType)).get();
188 } catch (InterruptedException | ExecutionException e) {
189 LOG.error("Error changing BGP VPN identifier to local VPN identifier", e);
192 LOG.debug("onRouterDisassociatedFromVpn : Ignoring the Router {} association with VPN {} "
193 + "since it is not external router", routerName, vpnName);
197 void handleDNATConfigurationForRouterAssociation(String routerName, String vpnName, String externalNetwork)
198 throws ExecutionException, InterruptedException {
199 InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerName);
200 Optional<RouterPorts> optRouterPorts =
201 MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);
202 if (!optRouterPorts.isPresent()) {
203 LOG.debug("handleDNATConfigurationForRouterAssociation : Could not read Router Ports data "
204 + "object with id: {} to handle associate vpn {}", routerName, vpnName);
207 Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
208 for (Ports port : optRouterPorts.get().nonnullPorts()) {
209 String portName = port.getPortName();
210 Uint64 dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
211 if (dpnId.equals(Uint64.ZERO)) {
212 LOG.warn("handleDNATConfigurationForRouterAssociation : DPN not found for {}, "
213 + "skip handling of router {} association with vpn {}", portName, routerName, vpnName);
217 for (InternalToExternalPortMap intExtPortMap : port.nonnullInternalToExternalPortMap()) {
218 //remove all NAT related entries with routerName
219 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, null,
220 // intExtPortMap.getInternalIp(), externalIp);
221 //Create NAT entries with VPN Id
222 LOG.debug("handleDNATConfigurationForRouterAssociation : Updating DNAT flows with VPN metadata {} ",
224 floatingIpListener.createNATOnlyFlowEntries(dpnId, routerName, vpnName, networkId, intExtPortMap);
229 void handleDNATConfigurationForRouterDisassociation(String routerName, String vpnName, String externalNetwork)
230 throws ExecutionException, InterruptedException {
231 InstanceIdentifier<RouterPorts> routerPortsId = NatUtil.getRouterPortsId(routerName);
232 Optional<RouterPorts> optRouterPorts =
233 MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerPortsId);
234 if (!optRouterPorts.isPresent()) {
235 LOG.error("handleDNATConfigurationForRouterDisassociation : Could not read Router Ports "
236 + "data object with id: {} to handle disassociate vpn {}", routerName, vpnName);
239 Uuid networkId = Uuid.getDefaultInstance(externalNetwork);
240 for (Ports port : optRouterPorts.get().nonnullPorts()) {
241 String portName = port.getPortName();
242 Uint64 dpnId = NatUtil.getDpnForInterface(interfaceManager, portName);
243 if (dpnId.equals(Uint64.ZERO)) {
244 LOG.debug("handleDNATConfigurationForRouterDisassociation : DPN not found for {}, "
245 + "skip handling of router {} association with vpn {}", portName, routerName, vpnName);
248 for (InternalToExternalPortMap intExtPortMap : port.nonnullInternalToExternalPortMap()) {
249 //remove all NAT related entries with routerName
250 //floatingIpListener.removeNATOnlyFlowEntries(dpnId, portName, routerName, vpnName,
251 // intExtPortMap.getInternalIp(), externalIp);
252 //Create NAT entries with VPN Id
253 floatingIpListener.createNATOnlyFlowEntries(dpnId, routerName, null, networkId, intExtPortMap);