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.neutronvpn;
10 import com.google.common.base.Optional;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Objects;
18 import javax.annotation.PreDestroy;
19 import javax.inject.Inject;
20 import javax.inject.Singleton;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
25 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
26 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
27 import org.opendaylight.netvirt.elanmanager.api.IElanService;
28 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
29 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
30 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
63 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
68 public class NeutronvpnNatManager implements AutoCloseable {
69 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnNatManager.class);
70 private static final int EXTERNAL_NO_CHANGE = 0;
71 private static final int EXTERNAL_ADDED = 1;
72 private static final int EXTERNAL_REMOVED = 2;
73 private static final int EXTERNAL_CHANGED = 3;
75 private final DataBroker dataBroker;
76 private final NeutronvpnUtils neutronvpnUtils;
77 private final IElanService elanService;
80 public NeutronvpnNatManager(final DataBroker dataBroker, final NeutronvpnUtils neutronvpnUtils,
81 final IElanService elanService) {
82 this.dataBroker = dataBroker;
83 this.neutronvpnUtils = neutronvpnUtils;
84 this.elanService = elanService;
90 LOG.info("{} close", getClass().getSimpleName());
93 public void handleExternalNetworkForRouter(@Nullable Router original, Router update) {
94 Uuid routerId = update.getUuid();
95 Uuid origExtNetId = null;
96 Uuid updExtNetId = null;
97 List<ExternalFixedIps> origExtFixedIps;
99 LOG.trace("handleExternalNetwork for router {}", routerId);
100 int extNetChanged = externalNetworkChanged(original, update);
101 if (extNetChanged != EXTERNAL_NO_CHANGE) {
102 if (extNetChanged == EXTERNAL_ADDED) {
103 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
104 LOG.trace("External Network {} addition detected for router {}", updExtNetId.getValue(),
105 routerId.getValue());
106 addExternalNetworkToRouter(update);
109 if (extNetChanged == EXTERNAL_REMOVED) {
110 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
111 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
112 LOG.trace("External Network removal detected for router {}", routerId.getValue());
113 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
114 //gateway mac unset handled as part of gateway clear deleting top-level routers node
118 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
119 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
120 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
121 LOG.trace("External Network changed from {} to {} for router {}",
122 origExtNetId.getValue(), updExtNetId.getValue(), routerId.getValue());
123 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
124 addExternalNetworkToRouter(update);
128 if (snatSettingChanged(original, update)) {
129 LOG.trace("SNAT settings on gateway changed for router {}", routerId.getValue());
130 handleSnatSettingChangeForRouter(update);
133 if (externalFixedIpsChanged(original, update)) {
134 LOG.trace("External Fixed IPs changed for router {}", routerId.getValue());
135 handleExternalFixedIpsForRouter(update);
139 private static int externalNetworkChanged(Router original, Router update) {
140 String origExtNet = null;
141 String newExtNet = null;
142 if (original != null && original.getExternalGatewayInfo() != null) {
143 origExtNet = original.getExternalGatewayInfo().getExternalNetworkId().getValue();
146 if (update != null && update.getExternalGatewayInfo() != null) {
147 newExtNet = update.getExternalGatewayInfo().getExternalNetworkId().getValue();
150 if (origExtNet == null) {
151 if (newExtNet == null) {
152 return EXTERNAL_NO_CHANGE;
154 return EXTERNAL_ADDED;
156 if (newExtNet == null) {
157 return EXTERNAL_REMOVED;
159 if (!origExtNet.equals(newExtNet)) {
160 return EXTERNAL_CHANGED;
162 return EXTERNAL_NO_CHANGE;
166 private static boolean snatSettingChanged(Router orig, Router update) {
167 ExternalGatewayInfo origExtGw = null;
168 ExternalGatewayInfo newExtGw = null;
169 if (orig != null && orig.getExternalGatewayInfo() != null) {
170 origExtGw = orig.getExternalGatewayInfo();
173 if (update != null && update.getExternalGatewayInfo() != null) {
174 newExtGw = update.getExternalGatewayInfo();
177 if (origExtGw == null) {
178 if (newExtGw != null) {
181 } else if (newExtGw == null || !Objects.equals(origExtGw.isEnableSnat(), newExtGw.isEnableSnat())) {
187 private static boolean externalFixedIpsChanged(Router orig, Router update) {
188 ExternalGatewayInfo origExtGw = null;
189 ExternalGatewayInfo newExtGw = null;
190 if (orig != null && orig.getExternalGatewayInfo() != null) {
191 origExtGw = orig.getExternalGatewayInfo();
194 if (update != null && update.getExternalGatewayInfo() != null) {
195 newExtGw = update.getExternalGatewayInfo();
198 if (origExtGw == null && newExtGw != null && newExtGw.getExternalFixedIps() != null && !newExtGw
199 .getExternalFixedIps().isEmpty()) {
203 if (newExtGw == null && origExtGw != null && origExtGw.getExternalFixedIps() != null && !origExtGw
204 .getExternalFixedIps().isEmpty()) {
208 if (origExtGw != null && newExtGw != null) {
209 if (origExtGw.getExternalFixedIps() != null) {
210 if (!origExtGw.getExternalFixedIps().isEmpty()) {
211 if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
212 List<ExternalFixedIps> origExtFixedIps = new ArrayList<>(origExtGw.nonnullExternalFixedIps());
213 HashSet<String> origFixedIpSet = new HashSet<>();
214 for (ExternalFixedIps fixedIps : origExtFixedIps) {
215 origFixedIpSet.add(fixedIps.getIpAddress().stringValue());
217 List<ExternalFixedIps> newExtFixedIps = new ArrayList<>(newExtGw.nonnullExternalFixedIps());
218 HashSet<String> updFixedIpSet = new HashSet<>();
219 for (ExternalFixedIps fixedIps : newExtFixedIps) {
220 updFixedIpSet.add(fixedIps.getIpAddress().stringValue());
222 // returns true if external subnets have changed
223 return !origFixedIpSet.equals(updFixedIpSet) ? true : false;
226 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
229 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
236 public void addExternalNetwork(Network net) {
237 Uuid extNetId = net.getUuid();
239 // Create and add Networks object for this External Network to the ExternalNetworks list
240 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
241 .child(Networks.class, new NetworksKey(extNetId)).build();
244 LOG.trace(" Creating/Updating a new Networks node {}", extNetId.getValue());
245 Optional<Networks> optionalNets =
246 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
248 if (optionalNets.isPresent()) {
249 LOG.error("External Network {} already detected to be present", extNetId.getValue());
252 ProviderTypes provType = NeutronvpnUtils.getProviderNetworkType(net);
253 if (provType == null) {
254 LOG.error("Unable to get Network Provider Type for network {}", extNetId);
257 NetworksBuilder builder = null;
258 builder = new NetworksBuilder().withKey(new NetworksKey(extNetId)).setId(extNetId);
259 builder.setVpnid(neutronvpnUtils.getVpnForNetwork(extNetId));
260 builder.setRouterIds(new ArrayList<>());
261 builder.setProviderNetworkType(provType);
263 Networks networkss = builder.build();
264 // Add Networks object to the ExternalNetworks list
265 LOG.trace("Creating externalnetworks {}", networkss);
266 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
268 LOG.trace("Wrote externalnetwork successfully to CONFIG Datastore");
269 } catch (TransactionCommitFailedException | ReadFailedException ex) {
270 LOG.error("Creation of External Network {} failed", extNetId.getValue(), ex);
274 public void removeExternalNetwork(Network net) {
275 Uuid extNetId = net.getUuid();
277 // Create and add Networks object for this External Network to the ExternalNetworks list
278 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
279 .child(Networks.class, new NetworksKey(extNetId)).build();
282 Optional<Networks> optionalNets =
283 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
285 LOG.trace("Removing Networks node {}", extNetId.getValue());
286 if (!optionalNets.isPresent()) {
287 LOG.error("External Network {} not available in the datastore", extNetId.getValue());
290 // Delete Networks object from the ExternalNetworks list
291 LOG.trace("Deleting External Network {}", extNetId.getValue());
292 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
293 LOG.trace("Deleted External Network {} successfully from CONFIG Datastore", extNetId.getValue());
295 } catch (TransactionCommitFailedException | ReadFailedException ex) {
296 LOG.error("Deletion of External Network {} failed", extNetId.getValue(), ex);
300 private void addExternalNetworkToRouter(Router update) {
301 Uuid routerId = update.getUuid();
302 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
303 List<ExternalFixedIps> externalFixedIps = update.getExternalGatewayInfo().getExternalFixedIps();
306 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
307 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
308 if (providerNwType == null) {
309 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
312 // Add this router to the ExtRouters list
313 addExternalRouter(update);
315 // Update External Subnets for this router
316 updateExternalSubnetsForRouter(routerId, extNetId, externalFixedIps);
318 // Create and add Networks object for this External Network to the ExternalNetworks list
319 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
320 .child(Networks.class, new NetworksKey(extNetId)).build();
322 Optional<Networks> optionalNets =
323 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
325 if (!optionalNets.isPresent()) {
326 LOG.error("External Network {} not present in the NVPN datamodel", extNetId.getValue());
329 NetworksBuilder builder = new NetworksBuilder(optionalNets.get());
330 List<Uuid> rtrList = (builder.getRouterIds() != null && !builder.getRouterIds().isEmpty())
331 ? new ArrayList<>(builder.getRouterIds()) : new ArrayList<>();
332 rtrList.add(routerId);
333 builder.setRouterIds(rtrList);
334 if (NeutronvpnUtils.isFlatOrVlanNetwork(input)) {
335 builder.setVpnid(extNetId);
338 Networks networkss = builder.build();
339 // Add Networks object to the ExternalNetworks list
340 LOG.trace("Updating externalnetworks {}", networkss);
341 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
343 LOG.trace("Updated externalnetworks successfully to CONFIG Datastore");
344 } catch (TransactionCommitFailedException | ReadFailedException ex) {
345 LOG.error("Creation of externalnetworks failed for {}",
346 extNetId.getValue(), ex);
350 public void removeExternalNetworkFromRouter(Uuid origExtNetId, Router update,
351 List<ExternalFixedIps> origExtFixedIps) {
352 Uuid routerId = update.getUuid();
354 // Remove the router to the ExtRouters list
355 removeExternalRouter(update);
357 //Remove router entry from floating-ip-info list
358 removeRouterFromFloatingIpInfo(update, dataBroker);
360 // Remove the router from External Subnets
361 removeRouterFromExternalSubnets(routerId, origExtNetId, origExtFixedIps);
363 // Remove the router from the ExternalNetworks list
364 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
365 .child(Networks.class, new NetworksKey(origExtNetId)).build();
366 Optional<Networks> optionalNets = null;
368 optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
369 LogicalDatastoreType.CONFIGURATION, netsIdentifier);
370 } catch (ReadFailedException ex) {
371 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
372 origExtNetId.getValue(), routerId.getValue(), ex);
375 if (!optionalNets.isPresent()) {
376 LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
377 origExtNetId.getValue());
380 Networks nets = optionalNets.get();
382 NetworksBuilder builder = new NetworksBuilder(nets);
383 List<Uuid> rtrList = new ArrayList<>();
384 rtrList = builder.getRouterIds() != null ? new ArrayList<>(builder.getRouterIds()) : rtrList;
385 if (rtrList != null) {
386 rtrList.remove(routerId);
387 builder.setRouterIds(rtrList);
388 Networks networkss = builder.build();
389 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
390 netsIdentifier, networkss);
391 LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
392 routerId, origExtNetId.getValue());
394 } catch (TransactionCommitFailedException ex) {
395 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
396 origExtNetId.getValue(), routerId.getValue(), ex);
400 public void addExternalRouter(Router update) {
401 Uuid routerId = update.getUuid();
402 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
403 Uuid gatewayPortId = update.getGatewayPortId();
404 // Create and add Routers object for this Router to the ExtRouters list
406 // Create a Routers object
407 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
410 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
411 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
412 if (providerNwType == null) {
413 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
416 Optional<Routers> optionalRouters =
417 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
419 LOG.trace("Creating/Updating a new Routers node: {}", routerId.getValue());
420 RoutersBuilder builder = null;
421 if (optionalRouters.isPresent()) {
422 builder = new RoutersBuilder(optionalRouters.get());
424 builder = new RoutersBuilder().withKey(new RoutersKey(routerId.getValue()));
426 builder.setRouterName(routerId.getValue());
427 builder.setNetworkId(extNetId);
428 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
430 ArrayList<ExternalIps> externalIps = new ArrayList<>();
431 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().nonnullExternalFixedIps()) {
432 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
434 builder.setExternalIps(externalIps);
436 if (gatewayPortId != null) {
437 LOG.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
438 Port port = neutronvpnUtils.getNeutronPort(gatewayPortId);
439 if (port != null && port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
440 builder.setExtGwMacAddress(port.getMacAddress().getValue());
443 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
444 builder.setSubnetIds(subList);
445 Routers routers = builder.build();
446 // Add Routers object to the ExtRouters list
447 LOG.trace("Creating extrouters {}", routers);
448 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
450 LOG.trace("Wrote successfully Routers to CONFIG Datastore");
452 } catch (ReadFailedException | TransactionCommitFailedException ex) {
453 LOG.error("Creation of extrouters failed for router {} failed",
454 routerId.getValue(), ex);
458 // TODO Clean up the exception handling
459 @SuppressWarnings("checkstyle:IllegalCatch")
460 private void removeExternalRouter(Router update) {
461 Uuid routerId = update.getUuid();
463 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
466 Optional<Routers> optionalRouters =
467 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
469 LOG.trace(" Removing Routers node {}", routerId.getValue());
470 if (optionalRouters.isPresent()) {
471 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
472 builder.setExternalIps(null);
473 builder.setSubnetIds(null);
474 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
476 LOG.trace("Removed router {} from extrouters", routerId.getValue());
478 } catch (TransactionCommitFailedException | ReadFailedException ex) {
479 LOG.error("Removing extrouter {} from extrouters failed", routerId.getValue(), ex);
483 public void removeNeutronRouterDpns(Router router) {
484 Uuid routerId = router.getUuid();
485 InstanceIdentifier<RouterDpnList> iid = InstanceIdentifier.builder(NeutronRouterDpns.class)
486 .child(RouterDpnList.class, new RouterDpnListKey(routerId.getValue())).build();
487 neutronvpnUtils.asyncReadAndExecute(LogicalDatastoreType.OPERATIONAL, iid, router.getUuid().toString(),
488 (routerDpnListOptional) -> {
489 if (routerDpnListOptional.isPresent()) {
490 if (routerDpnListOptional.get().getDpnVpninterfacesList() != null) {
491 routerDpnListOptional.get().getDpnVpninterfacesList().stream()
492 .filter((dpnList) -> (dpnList != null))
493 .forEach((dpnList) -> {
494 LOG.warn("DPN {} presence exists while deleting router instance {}",
495 dpnList.getDpnId(), routerId);
498 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, iid);
499 } catch (TransactionCommitFailedException e) {
500 LOG.warn("Failed to read from NeutronRouterDpn DS for routerid {}", routerId, e);
508 private void removeRouterFromFloatingIpInfo(Router update, DataBroker broker) {
509 Uuid routerId = update.getUuid();
510 InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder = InstanceIdentifier
511 .builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId.getValue()));
513 Optional<RouterPorts> optionalRouterPorts =
514 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
515 routerPortsIdentifierBuilder.build());
516 if (optionalRouterPorts.isPresent()) {
517 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
518 routerPortsIdentifierBuilder.build());
520 } catch (ReadFailedException | TransactionCommitFailedException e) {
521 LOG.error("Failed to read from FloatingIpInfo DS for routerid {}", routerId, e);
525 // TODO Clean up the exception handling
526 @SuppressWarnings("checkstyle:IllegalCatch")
527 private void handleExternalFixedIpsForRouter(Router update) {
528 Uuid routerId = update.getUuid();
529 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
531 Optional<Routers> optionalRouters =
532 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
534 LOG.trace("Updating External Fixed IPs Routers node {}", routerId.getValue());
535 if (optionalRouters.isPresent()) {
536 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
537 List<ExternalIps> externalIps = new ArrayList<>();
538 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
539 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
542 builder.setExternalIps(externalIps);
544 updateExternalSubnetsForRouter(routerId, update.getExternalGatewayInfo().getExternalNetworkId(),
545 update.getExternalGatewayInfo().getExternalFixedIps());
546 Routers routerss = builder.build();
547 LOG.trace("Updating external fixed ips for router {} with value {}", routerId.getValue(), routerss);
548 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
550 LOG.trace("Added External Fixed IPs successfully for Routers to CONFIG Datastore");
552 } catch (TransactionCommitFailedException | ReadFailedException ex) {
553 LOG.error("Updating extfixedips for {} in extrouters failed", routerId.getValue(), ex);
557 public void handleSubnetsForExternalRouter(Uuid routerId) {
558 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
561 Optional<Routers> optionalRouters =
562 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
564 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
565 RoutersBuilder builder = null;
566 if (optionalRouters.isPresent()) {
567 builder = new RoutersBuilder(optionalRouters.get());
569 LOG.debug("No Routers element found for router {}", routerId.getValue());
572 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
573 builder.setSubnetIds(subList);
574 Routers routerss = builder.build();
575 // Add Routers object to the ExtRouters list
576 LOG.trace("Updating extrouters {}", routerss);
577 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
578 routersIdentifier, routerss);
579 LOG.trace("Updated successfully Routers to CONFIG Datastore");
580 } catch (TransactionCommitFailedException | ReadFailedException ex) {
581 LOG.error("Updation of internal subnets for extrouters failed for router {}",
582 routerId.getValue(), ex);
586 private void handleSnatSettingChangeForRouter(Router update) {
587 Uuid routerId = update.getUuid();
589 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
592 Optional<Routers> optionalRouters =
593 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
595 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
596 RoutersBuilder builder = null;
597 if (optionalRouters.isPresent()) {
598 builder = new RoutersBuilder(optionalRouters.get());
600 LOG.trace("No Routers element found for router name {}", routerId.getValue());
603 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
604 Routers routerss = builder.build();
605 // Add Routers object to the ExtRouters list
606 LOG.trace("Updating extrouters for snat change {}", routerss);
607 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
608 routersIdentifier, routerss);
609 LOG.trace("Updated successfully Routers to CONFIG Datastore");
611 } catch (TransactionCommitFailedException | ReadFailedException ex) {
612 LOG.error("Updation of snat for extrouters failed for router {}", routerId.getValue(), ex);
616 public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
617 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
618 if (optionalExternalSubnets.isPresent()) {
619 LOG.trace("Will update external subnet {} with networkId {} and routerIds {}",
620 subnetId, networkId, routerIds);
621 updateExternalSubnet(networkId, subnetId, routerIds);
623 LOG.trace("Will add external subnet {} with networkId {} and routerIds {}",
624 subnetId, networkId, routerIds);
625 addExternalSubnet(networkId, subnetId, routerIds);
629 public void addExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
630 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
631 .child(Subnets.class, new SubnetsKey(subnetId)).build();
633 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
634 LOG.debug("Creating external subnet {}", newExternalSubnets);
635 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
637 } catch (TransactionCommitFailedException ex) {
638 LOG.error("Creation of External Subnets {} failed", subnetId, ex);
642 public void updateExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
643 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
644 .child(Subnets.class, new SubnetsKey(subnetId)).build();
646 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
647 LOG.debug("Updating external subnet {}", newExternalSubnets);
648 SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
650 } catch (TransactionCommitFailedException ex) {
651 LOG.error("Update of External Subnets {} failed", subnetId, ex);
655 public void removeExternalSubnet(Uuid networkId, Uuid subnetId) {
656 removeAdjacencyAndLearnedEntriesforExternalSubnet(networkId, subnetId);
657 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
658 .child(Subnets.class, new SubnetsKey(subnetId)).build();
660 LOG.debug("Removing external subnet {}", subnetId);
661 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
662 } catch (TransactionCommitFailedException ex) {
663 LOG.error("Deletion of External Subnets {} failed", subnetId, ex);
667 public void addRouterIdToExternalSubnet(Uuid networkId, Uuid subnetId, Uuid routerId) {
668 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
669 if (optionalExternalSubnets.isPresent()) {
670 Subnets subnets = optionalExternalSubnets.get();
671 List<Uuid> routerIds;
672 if (subnets.getRouterIds() != null && !subnets.getRouterIds().isEmpty()) {
673 routerIds = new ArrayList<>(subnets.getRouterIds());
675 routerIds = new ArrayList<>();
678 if (subnets.getExternalNetworkId() != null
679 && subnets.getExternalNetworkId().equals(networkId) && !routerIds.contains(routerId)) {
680 LOG.debug("Will add routerID {} for external subnet {}.", routerId, subnetId);
681 routerIds.add(routerId);
682 updateExternalSubnet(networkId, subnetId, routerIds);
687 private static Subnets createSubnets(Uuid subnetId, Uuid networkId, @Nullable List<Uuid> routerIds) {
688 SubnetsBuilder subnetsBuilder = new SubnetsBuilder();
689 subnetsBuilder.withKey(new SubnetsKey(subnetId));
690 subnetsBuilder.setId(subnetId);
691 subnetsBuilder.setVpnId(subnetId);
692 subnetsBuilder.setExternalNetworkId(networkId);
693 if (routerIds != null) {
694 subnetsBuilder.setRouterIds(routerIds);
697 return subnetsBuilder.build();
700 private void updateExternalSubnetsForRouter(Uuid routerId, Uuid externalNetworkId,
701 List<ExternalFixedIps> externalFixedIps) {
702 LOG.debug("Updating external subnets for router {} for external network ID {}",
703 routerId, externalNetworkId);
704 Set<Uuid> subnetsUuidsSet = getExternalSubnetsUuidsSetForFixedIps(externalFixedIps);
705 for (Uuid subnetId : subnetsUuidsSet) {
706 addRouterIdToExternalSubnet(externalNetworkId, subnetId, routerId);
710 private void removeRouterFromExternalSubnets(Uuid routerId, Uuid externalNetworkId,
711 List<ExternalFixedIps> externalFixedIps) {
712 LOG.debug("Removing routerID {} from external subnets of external network{}",
713 routerId, externalNetworkId);
715 List<Subnets> fixedIpsSubnets = getSubnets(getExternalSubnetsUuidsSetForFixedIps(externalFixedIps));
716 for (Subnets subnets : fixedIpsSubnets) {
717 Uuid subnetId = subnets.getId();
718 List<Uuid> routerIds = new ArrayList<>();
719 routerIds = subnets.getRouterIds() != null ? new ArrayList<>(subnets.getRouterIds()) : routerIds;
720 if (routerIds != null) {
721 if (subnets.getExternalNetworkId() != null
722 && subnets.getExternalNetworkId().equals(externalNetworkId)
723 && routerIds.contains(routerId)) {
724 routerIds.remove(routerId);
725 LOG.debug("Will remove routerIDs {} from external subnet {} router ID {}",
726 routerIds, subnetId, routerId);
727 addExternalSubnet(externalNetworkId, subnetId, routerIds);
733 private static Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
734 Set<Uuid> subnetsUuidsSet = new HashSet<>();
735 for (ExternalFixedIps externalFixedIp : externalFixedIps) {
736 subnetsUuidsSet.add(externalFixedIp.getSubnetId());
739 return subnetsUuidsSet;
742 private List<Subnets> getSubnets(Set<Uuid> subnetsUuidsSet) {
743 List<Subnets> subnetsList = new ArrayList<>();
744 for (Uuid subnetId : subnetsUuidsSet) {
745 Optional<Subnets> optionalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
746 if (optionalSubnets.isPresent()) {
747 subnetsList.add(optionalSubnets.get());
754 private static void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
755 Uuid subnetId = fixedIps.getSubnetId();
756 String ip = fixedIps.getIpAddress().stringValue();
757 ExternalIpsBuilder externalIpsBuilder = new ExternalIpsBuilder();
758 externalIpsBuilder.withKey(new ExternalIpsKey(ip, subnetId));
759 externalIpsBuilder.setIpAddress(ip);
760 externalIpsBuilder.setSubnetId(subnetId);
761 externalIps.add(externalIpsBuilder.build());
764 private void removeAdjacencyAndLearnedEntriesforExternalSubnet(Uuid extNetId, Uuid extSubnetId) {
765 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
766 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
767 LOG.error("No external ports attached to external network {}", extNetId.getValue());
771 for (String infName : extElanInterfaces) {
772 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
773 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
774 InstanceIdentifier<Adjacencies> adjacenciesIdentifier = vpnIfIdentifier.augmentation(Adjacencies.class);
776 // Looking for existing prefix in MDSAL database
777 Optional<Adjacencies> optionalAdjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker,
778 LogicalDatastoreType.CONFIGURATION, adjacenciesIdentifier);
779 if (optionalAdjacencies.isPresent()) {
780 List<Adjacency> adjacencies = optionalAdjacencies.get().getAdjacency();
781 Iterator<Adjacency> adjacencyIter = adjacencies.iterator();
782 while (adjacencyIter.hasNext()) {
783 Adjacency adjacency = adjacencyIter.next();
784 if (!adjacency.getSubnetId().equals(extSubnetId)) {
787 InstanceIdentifier<Adjacency> adjacencyIdentifier =
788 adjacenciesIdentifier.child(Adjacency.class, new AdjacencyKey(adjacency.getIpAddress()));
789 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
790 adjacencyIdentifier);
791 LOG.trace("Removed Adjacency for fixedIP {} for port {} on external subnet {} ",
792 adjacency.getIpAddress(), infName, extSubnetId);
793 String extNetVpnName = extNetId.getValue();
794 String learnedSrcIp = adjacency.getIpAddress().split("/")[0];
795 InstanceIdentifier<LearntVpnVipToPort> id =
796 NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(extNetVpnName, learnedSrcIp);
797 Optional<LearntVpnVipToPort> optionalLearntVpnVipToPort = SingleTransactionDataBroker
798 .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
799 if (optionalLearntVpnVipToPort.isPresent()) {
800 neutronvpnUtils.removeLearntVpnVipToPort(extNetVpnName, learnedSrcIp);
801 LOG.trace("Removed Learnt Entry for fixedIP {} for port {}",
802 adjacency.getIpAddress(), infName);
806 } catch (TransactionCommitFailedException | ReadFailedException e) {
807 LOG.error("exception in removeAdjacencyAndLearnedEntriesforExternalSubnet for interface {}",