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 NeutronvpnManager nvpnManager;
78 private final IElanService elanService;
81 public NeutronvpnNatManager(final DataBroker dataBroker, final NeutronvpnUtils neutronvpnUtils,
82 final NeutronvpnManager neutronvpnManager, final IElanService elanService) {
83 this.dataBroker = dataBroker;
84 this.neutronvpnUtils = neutronvpnUtils;
85 this.nvpnManager = neutronvpnManager;
86 this.elanService = elanService;
92 LOG.info("{} close", getClass().getSimpleName());
95 public void handleExternalNetworkForRouter(@Nullable Router original, Router update) {
96 Uuid routerId = update.getUuid();
97 Uuid origExtNetId = null;
98 Uuid updExtNetId = null;
99 List<ExternalFixedIps> origExtFixedIps;
101 LOG.trace("handleExternalNetwork for router {}", routerId);
102 int extNetChanged = externalNetworkChanged(original, update);
103 if (extNetChanged != EXTERNAL_NO_CHANGE) {
104 if (extNetChanged == EXTERNAL_ADDED) {
105 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
106 LOG.trace("External Network {} addition detected for router {}", updExtNetId.getValue(),
107 routerId.getValue());
108 addExternalNetworkToRouter(update);
111 if (extNetChanged == EXTERNAL_REMOVED) {
112 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
113 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
114 LOG.trace("External Network removal detected for router {}", routerId.getValue());
115 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
116 //gateway mac unset handled as part of gateway clear deleting top-level routers node
120 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
121 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
122 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
123 LOG.trace("External Network changed from {} to {} for router {}",
124 origExtNetId.getValue(), updExtNetId.getValue(), routerId.getValue());
125 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
126 addExternalNetworkToRouter(update);
130 if (snatSettingChanged(original, update)) {
131 LOG.trace("SNAT settings on gateway changed for router {}", routerId.getValue());
132 handleSnatSettingChangeForRouter(update);
135 if (externalFixedIpsChanged(original, update)) {
136 LOG.trace("External Fixed IPs changed for router {}", routerId.getValue());
137 handleExternalFixedIpsForRouter(update);
141 private static int externalNetworkChanged(Router original, Router update) {
142 String origExtNet = null;
143 String newExtNet = null;
144 if (original != null && original.getExternalGatewayInfo() != null) {
145 origExtNet = original.getExternalGatewayInfo().getExternalNetworkId().getValue();
148 if (update != null && update.getExternalGatewayInfo() != null) {
149 newExtNet = update.getExternalGatewayInfo().getExternalNetworkId().getValue();
152 if (origExtNet == null) {
153 if (newExtNet == null) {
154 return EXTERNAL_NO_CHANGE;
156 return EXTERNAL_ADDED;
158 if (newExtNet == null) {
159 return EXTERNAL_REMOVED;
161 if (!origExtNet.equals(newExtNet)) {
162 return EXTERNAL_CHANGED;
164 return EXTERNAL_NO_CHANGE;
168 private static boolean snatSettingChanged(Router orig, Router update) {
169 ExternalGatewayInfo origExtGw = null;
170 ExternalGatewayInfo newExtGw = null;
171 if (orig != null && orig.getExternalGatewayInfo() != null) {
172 origExtGw = orig.getExternalGatewayInfo();
175 if (update != null && update.getExternalGatewayInfo() != null) {
176 newExtGw = update.getExternalGatewayInfo();
179 if (origExtGw == null) {
180 if (newExtGw != null) {
183 } else if (newExtGw == null || !Objects.equals(origExtGw.isEnableSnat(), newExtGw.isEnableSnat())) {
189 private static boolean externalFixedIpsChanged(Router orig, Router update) {
190 ExternalGatewayInfo origExtGw = null;
191 ExternalGatewayInfo newExtGw = null;
192 if (orig != null && orig.getExternalGatewayInfo() != null) {
193 origExtGw = orig.getExternalGatewayInfo();
196 if (update != null && update.getExternalGatewayInfo() != null) {
197 newExtGw = update.getExternalGatewayInfo();
200 if (origExtGw == null && newExtGw != null && newExtGw.getExternalFixedIps() != null && !newExtGw
201 .getExternalFixedIps().isEmpty()) {
205 if (newExtGw == null && origExtGw != null && origExtGw.getExternalFixedIps() != null && !origExtGw
206 .getExternalFixedIps().isEmpty()) {
210 if (origExtGw != null && newExtGw != null) {
211 if (origExtGw.getExternalFixedIps() != null) {
212 if (!origExtGw.getExternalFixedIps().isEmpty()) {
213 if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
214 List<ExternalFixedIps> origExtFixedIps = origExtGw.getExternalFixedIps();
215 HashSet<String> origFixedIpSet = new HashSet<>();
216 for (ExternalFixedIps fixedIps : origExtFixedIps) {
217 origFixedIpSet.add(fixedIps.getIpAddress().stringValue());
219 List<ExternalFixedIps> newExtFixedIps = newExtGw.getExternalFixedIps();
220 HashSet<String> updFixedIpSet = new HashSet<>();
221 for (ExternalFixedIps fixedIps : newExtFixedIps) {
222 updFixedIpSet.add(fixedIps.getIpAddress().stringValue());
224 // returns true if external subnets have changed
225 return !origFixedIpSet.equals(updFixedIpSet) ? true : false;
228 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
231 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
238 public void addExternalNetwork(Network net) {
239 Uuid extNetId = net.getUuid();
241 // Create and add Networks object for this External Network to the ExternalNetworks list
242 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
243 .child(Networks.class, new NetworksKey(extNetId)).build();
246 LOG.trace(" Creating/Updating a new Networks node {}", extNetId.getValue());
247 Optional<Networks> optionalNets =
248 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
250 if (optionalNets.isPresent()) {
251 LOG.error("External Network {} already detected to be present", extNetId.getValue());
254 ProviderTypes provType = NeutronvpnUtils.getProviderNetworkType(net);
255 if (provType == null) {
256 LOG.error("Unable to get Network Provider Type for network {}", extNetId);
259 NetworksBuilder builder = null;
260 builder = new NetworksBuilder().withKey(new NetworksKey(extNetId)).setId(extNetId);
261 builder.setVpnid(neutronvpnUtils.getVpnForNetwork(extNetId));
262 builder.setRouterIds(new ArrayList<>());
263 builder.setProviderNetworkType(provType);
265 Networks networkss = builder.build();
266 // Add Networks object to the ExternalNetworks list
267 LOG.trace("Creating externalnetworks {}", networkss);
268 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
270 LOG.trace("Wrote externalnetwork successfully to CONFIG Datastore");
271 } catch (TransactionCommitFailedException | ReadFailedException ex) {
272 LOG.error("Creation of External Network {} failed", extNetId.getValue(), ex);
276 public void removeExternalNetwork(Network net) {
277 Uuid extNetId = net.getUuid();
279 // Create and add Networks object for this External Network to the ExternalNetworks list
280 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
281 .child(Networks.class, new NetworksKey(extNetId)).build();
284 Optional<Networks> optionalNets =
285 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
287 LOG.trace("Removing Networks node {}", extNetId.getValue());
288 if (!optionalNets.isPresent()) {
289 LOG.error("External Network {} not available in the datastore", extNetId.getValue());
292 // Delete Networks object from the ExternalNetworks list
293 LOG.trace("Deleting External Network {}", extNetId.getValue());
294 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
295 LOG.trace("Deleted External Network {} successfully from CONFIG Datastore", extNetId.getValue());
297 } catch (TransactionCommitFailedException | ReadFailedException ex) {
298 LOG.error("Deletion of External Network {} failed", extNetId.getValue(), ex);
302 private void addExternalNetworkToRouter(Router update) {
303 Uuid routerId = update.getUuid();
304 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
305 List<ExternalFixedIps> externalFixedIps = update.getExternalGatewayInfo().getExternalFixedIps();
308 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
309 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
310 if (providerNwType == null) {
311 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
314 // Add this router to the ExtRouters list
315 addExternalRouter(update);
317 // Update External Subnets for this router
318 updateExternalSubnetsForRouter(routerId, extNetId, externalFixedIps);
320 // Create and add Networks object for this External Network to the ExternalNetworks list
321 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
322 .child(Networks.class, new NetworksKey(extNetId)).build();
324 Optional<Networks> optionalNets =
325 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
327 if (!optionalNets.isPresent()) {
328 LOG.error("External Network {} not present in the NVPN datamodel", extNetId.getValue());
331 NetworksBuilder builder = new NetworksBuilder(optionalNets.get());
332 List<Uuid> rtrList = builder.getRouterIds();
333 if (rtrList == null) {
334 rtrList = new ArrayList<>();
336 rtrList.add(routerId);
337 builder.setRouterIds(rtrList);
338 if (NeutronvpnUtils.isFlatOrVlanNetwork(input)) {
339 builder.setVpnid(extNetId);
342 Networks networkss = builder.build();
343 // Add Networks object to the ExternalNetworks list
344 LOG.trace("Updating externalnetworks {}", networkss);
345 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
347 LOG.trace("Updated externalnetworks successfully to CONFIG Datastore");
348 } catch (TransactionCommitFailedException | ReadFailedException ex) {
349 LOG.error("Creation of externalnetworks failed for {}",
350 extNetId.getValue(), ex);
354 public void removeExternalNetworkFromRouter(Uuid origExtNetId, Router update,
355 List<ExternalFixedIps> origExtFixedIps) {
356 Uuid routerId = update.getUuid();
358 // Remove the router to the ExtRouters list
359 removeExternalRouter(update);
361 //Remove router entry from floating-ip-info list
362 removeRouterFromFloatingIpInfo(update, dataBroker);
364 // Remove the router from External Subnets
365 removeRouterFromExternalSubnets(routerId, origExtNetId, origExtFixedIps);
367 // Remove the router from the ExternalNetworks list
368 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
369 .child(Networks.class, new NetworksKey(origExtNetId)).build();
370 Optional<Networks> optionalNets = null;
372 optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
373 LogicalDatastoreType.CONFIGURATION, netsIdentifier);
374 } catch (ReadFailedException ex) {
375 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
376 origExtNetId.getValue(), routerId.getValue(), ex);
379 if (!optionalNets.isPresent()) {
380 LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
381 origExtNetId.getValue());
384 Networks nets = optionalNets.get();
386 NetworksBuilder builder = new NetworksBuilder(nets);
387 List<Uuid> rtrList = builder.getRouterIds();
388 if (rtrList != null) {
389 rtrList.remove(routerId);
390 builder.setRouterIds(rtrList);
391 Networks networkss = builder.build();
392 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
393 netsIdentifier, networkss);
394 LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
395 routerId, origExtNetId.getValue());
397 } catch (TransactionCommitFailedException ex) {
398 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
399 origExtNetId.getValue(), routerId.getValue(), ex);
403 public void addExternalRouter(Router update) {
404 Uuid routerId = update.getUuid();
405 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
406 Uuid gatewayPortId = update.getGatewayPortId();
407 // Create and add Routers object for this Router to the ExtRouters list
409 // Create a Routers object
410 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
413 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
414 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
415 if (providerNwType == null) {
416 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
419 Optional<Routers> optionalRouters =
420 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
422 LOG.trace("Creating/Updating a new Routers node: {}", routerId.getValue());
423 RoutersBuilder builder = null;
424 if (optionalRouters.isPresent()) {
425 builder = new RoutersBuilder(optionalRouters.get());
427 builder = new RoutersBuilder().withKey(new RoutersKey(routerId.getValue()));
429 builder.setRouterName(routerId.getValue());
430 builder.setNetworkId(extNetId);
431 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
433 ArrayList<ExternalIps> externalIps = new ArrayList<>();
434 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().nonnullExternalFixedIps()) {
435 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
437 builder.setExternalIps(externalIps);
439 if (gatewayPortId != null) {
440 LOG.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
441 Port port = neutronvpnUtils.getNeutronPort(gatewayPortId);
442 if (port != null && port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
443 builder.setExtGwMacAddress(port.getMacAddress().getValue());
446 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
447 builder.setSubnetIds(subList);
448 Routers routers = builder.build();
449 // Add Routers object to the ExtRouters list
450 LOG.trace("Creating extrouters {}", routers);
451 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
453 LOG.trace("Wrote successfully Routers to CONFIG Datastore");
455 } catch (ReadFailedException | TransactionCommitFailedException ex) {
456 LOG.error("Creation of extrouters failed for router {} failed",
457 routerId.getValue(), ex);
461 // TODO Clean up the exception handling
462 @SuppressWarnings("checkstyle:IllegalCatch")
463 private void removeExternalRouter(Router update) {
464 Uuid routerId = update.getUuid();
466 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
469 Optional<Routers> optionalRouters =
470 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
472 LOG.trace(" Removing Routers node {}", routerId.getValue());
473 if (optionalRouters.isPresent()) {
474 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
475 builder.setExternalIps(null);
476 builder.setSubnetIds(null);
477 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
479 LOG.trace("Removed router {} from extrouters", routerId.getValue());
481 } catch (TransactionCommitFailedException | ReadFailedException ex) {
482 LOG.error("Removing extrouter {} from extrouters failed", routerId.getValue(), ex);
486 public void removeNeutronRouterDpns(Router router) {
487 Uuid routerId = router.getUuid();
488 InstanceIdentifier<RouterDpnList> iid = InstanceIdentifier.builder(NeutronRouterDpns.class)
489 .child(RouterDpnList.class, new RouterDpnListKey(routerId.getValue())).build();
490 neutronvpnUtils.asyncReadAndExecute(LogicalDatastoreType.OPERATIONAL, iid, router.getUuid().toString(),
491 (routerDpnListOptional) -> {
492 if (routerDpnListOptional.isPresent()) {
493 if (routerDpnListOptional.get().getDpnVpninterfacesList() != null) {
494 routerDpnListOptional.get().getDpnVpninterfacesList().stream()
495 .filter((dpnList) -> (dpnList != null))
496 .forEach((dpnList) -> {
497 LOG.warn("DPN {} presence exists while deleting router instance {}",
498 dpnList.getDpnId(), routerId);
501 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, iid);
502 } catch (TransactionCommitFailedException e) {
503 LOG.warn("Failed to read from NeutronRouterDpn DS for routerid {}", routerId, e);
511 private void removeRouterFromFloatingIpInfo(Router update, DataBroker broker) {
512 Uuid routerId = update.getUuid();
513 InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder = InstanceIdentifier
514 .builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId.getValue()));
516 Optional<RouterPorts> optionalRouterPorts =
517 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
518 routerPortsIdentifierBuilder.build());
519 if (optionalRouterPorts.isPresent()) {
520 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
521 routerPortsIdentifierBuilder.build());
523 } catch (ReadFailedException | TransactionCommitFailedException e) {
524 LOG.error("Failed to read from FloatingIpInfo DS for routerid {}", routerId, e);
528 // TODO Clean up the exception handling
529 @SuppressWarnings("checkstyle:IllegalCatch")
530 private void handleExternalFixedIpsForRouter(Router update) {
531 Uuid routerId = update.getUuid();
532 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
534 Optional<Routers> optionalRouters =
535 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
537 LOG.trace("Updating External Fixed IPs Routers node {}", routerId.getValue());
538 if (optionalRouters.isPresent()) {
539 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
540 List<ExternalIps> externalIps = new ArrayList<>();
541 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
542 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
545 builder.setExternalIps(externalIps);
547 updateExternalSubnetsForRouter(routerId, update.getExternalGatewayInfo().getExternalNetworkId(),
548 update.getExternalGatewayInfo().getExternalFixedIps());
549 Routers routerss = builder.build();
550 LOG.trace("Updating external fixed ips for router {} with value {}", routerId.getValue(), routerss);
551 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
553 LOG.trace("Added External Fixed IPs successfully for Routers to CONFIG Datastore");
555 } catch (TransactionCommitFailedException | ReadFailedException ex) {
556 LOG.error("Updating extfixedips for {} in extrouters failed", routerId.getValue(), ex);
560 public void handleSubnetsForExternalRouter(Uuid routerId) {
561 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
564 Optional<Routers> optionalRouters =
565 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
567 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
568 RoutersBuilder builder = null;
569 if (optionalRouters.isPresent()) {
570 builder = new RoutersBuilder(optionalRouters.get());
572 LOG.debug("No Routers element found for router {}", routerId.getValue());
575 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
576 builder.setSubnetIds(subList);
577 Routers routerss = builder.build();
578 // Add Routers object to the ExtRouters list
579 LOG.trace("Updating extrouters {}", routerss);
580 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
581 routersIdentifier, routerss);
582 LOG.trace("Updated successfully Routers to CONFIG Datastore");
583 } catch (TransactionCommitFailedException | ReadFailedException ex) {
584 LOG.error("Updation of internal subnets for extrouters failed for router {}",
585 routerId.getValue(), ex);
589 private void handleSnatSettingChangeForRouter(Router update) {
590 Uuid routerId = update.getUuid();
592 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
595 Optional<Routers> optionalRouters =
596 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
598 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
599 RoutersBuilder builder = null;
600 if (optionalRouters.isPresent()) {
601 builder = new RoutersBuilder(optionalRouters.get());
603 LOG.trace("No Routers element found for router name {}", routerId.getValue());
606 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
607 Routers routerss = builder.build();
608 // Add Routers object to the ExtRouters list
609 LOG.trace("Updating extrouters for snat change {}", routerss);
610 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
611 routersIdentifier, routerss);
612 LOG.trace("Updated successfully Routers to CONFIG Datastore");
614 } catch (TransactionCommitFailedException | ReadFailedException ex) {
615 LOG.error("Updation of snat for extrouters failed for router {}", routerId.getValue(), ex);
619 public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
620 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
621 if (optionalExternalSubnets.isPresent()) {
622 LOG.trace("Will update external subnet {} with networkId {} and routerIds {}",
623 subnetId, networkId, routerIds);
624 updateExternalSubnet(networkId, subnetId, routerIds);
626 LOG.trace("Will add external subnet {} with networkId {} and routerIds {}",
627 subnetId, networkId, routerIds);
628 addExternalSubnet(networkId, subnetId, routerIds);
632 public void addExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
633 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
634 .child(Subnets.class, new SubnetsKey(subnetId)).build();
636 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
637 LOG.debug("Creating external subnet {}", newExternalSubnets);
638 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
640 } catch (TransactionCommitFailedException ex) {
641 LOG.error("Creation of External Subnets {} failed", subnetId, ex);
645 public void updateExternalSubnet(Uuid networkId, Uuid subnetId, @Nullable List<Uuid> routerIds) {
646 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
647 .child(Subnets.class, new SubnetsKey(subnetId)).build();
649 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
650 LOG.debug("Updating external subnet {}", newExternalSubnets);
651 SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
653 } catch (TransactionCommitFailedException ex) {
654 LOG.error("Update of External Subnets {} failed", subnetId, ex);
658 public void removeExternalSubnet(Uuid networkId, Uuid subnetId) {
659 removeAdjacencyAndLearnedEntriesforExternalSubnet(networkId, subnetId);
660 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
661 .child(Subnets.class, new SubnetsKey(subnetId)).build();
663 LOG.debug("Removing external subnet {}", subnetId);
664 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
665 } catch (TransactionCommitFailedException ex) {
666 LOG.error("Deletion of External Subnets {} failed", subnetId, ex);
670 public void addRouterIdToExternalSubnet(Uuid networkId, Uuid subnetId, Uuid routerId) {
671 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
672 if (optionalExternalSubnets.isPresent()) {
673 Subnets subnets = optionalExternalSubnets.get();
674 List<Uuid> routerIds;
675 if (subnets.getRouterIds() != null) {
676 routerIds = subnets.getRouterIds();
678 routerIds = new ArrayList<>();
681 if (subnets.getExternalNetworkId() != null
682 && subnets.getExternalNetworkId().equals(networkId) && !routerIds.contains(routerId)) {
683 LOG.debug("Will add routerID {} for external subnet {}.", routerId, subnetId);
684 routerIds.add(routerId);
685 updateExternalSubnet(networkId, subnetId, routerIds);
690 private static Subnets createSubnets(Uuid subnetId, Uuid networkId, @Nullable List<Uuid> routerIds) {
691 SubnetsBuilder subnetsBuilder = new SubnetsBuilder();
692 subnetsBuilder.withKey(new SubnetsKey(subnetId));
693 subnetsBuilder.setId(subnetId);
694 subnetsBuilder.setVpnId(subnetId);
695 subnetsBuilder.setExternalNetworkId(networkId);
696 if (routerIds != null) {
697 subnetsBuilder.setRouterIds(routerIds);
700 return subnetsBuilder.build();
703 private void updateExternalSubnetsForRouter(Uuid routerId, Uuid externalNetworkId,
704 List<ExternalFixedIps> externalFixedIps) {
705 LOG.debug("Updating external subnets for router {} for external network ID {}",
706 routerId, externalNetworkId);
707 Set<Uuid> subnetsUuidsSet = getExternalSubnetsUuidsSetForFixedIps(externalFixedIps);
708 for (Uuid subnetId : subnetsUuidsSet) {
709 addRouterIdToExternalSubnet(externalNetworkId, subnetId, routerId);
713 private void removeRouterFromExternalSubnets(Uuid routerId, Uuid externalNetworkId,
714 List<ExternalFixedIps> externalFixedIps) {
715 LOG.debug("Removing routerID {} from external subnets of external network{}",
716 routerId, externalNetworkId);
718 List<Subnets> fixedIpsSubnets = getSubnets(getExternalSubnetsUuidsSetForFixedIps(externalFixedIps));
719 for (Subnets subnets : fixedIpsSubnets) {
720 Uuid subnetId = subnets.getId();
721 List<Uuid> routerIds = subnets.getRouterIds();
722 if (routerIds != null) {
723 if (subnets.getExternalNetworkId() != null
724 && subnets.getExternalNetworkId().equals(externalNetworkId)
725 && routerIds.contains(routerId)) {
726 routerIds.remove(routerId);
727 LOG.debug("Will remove routerIDs {} from external subnet {} router ID {}",
728 routerIds, subnetId, routerId);
729 addExternalSubnet(externalNetworkId, subnetId, routerIds);
735 private static Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
736 Set<Uuid> subnetsUuidsSet = new HashSet<>();
737 for (ExternalFixedIps externalFixedIp : externalFixedIps) {
738 subnetsUuidsSet.add(externalFixedIp.getSubnetId());
741 return subnetsUuidsSet;
744 private List<Subnets> getSubnets(Set<Uuid> subnetsUuidsSet) {
745 List<Subnets> subnetsList = new ArrayList<>();
746 for (Uuid subnetId : subnetsUuidsSet) {
747 Optional<Subnets> optionalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
748 if (optionalSubnets.isPresent()) {
749 subnetsList.add(optionalSubnets.get());
756 private static void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
757 Uuid subnetId = fixedIps.getSubnetId();
758 String ip = fixedIps.getIpAddress().stringValue();
759 ExternalIpsBuilder externalIpsBuilder = new ExternalIpsBuilder();
760 externalIpsBuilder.withKey(new ExternalIpsKey(ip, subnetId));
761 externalIpsBuilder.setIpAddress(ip);
762 externalIpsBuilder.setSubnetId(subnetId);
763 externalIps.add(externalIpsBuilder.build());
766 private void removeAdjacencyAndLearnedEntriesforExternalSubnet(Uuid extNetId, Uuid extSubnetId) {
767 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
768 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
769 LOG.error("No external ports attached to external network {}", extNetId.getValue());
773 for (String infName : extElanInterfaces) {
774 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
775 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
776 InstanceIdentifier<Adjacencies> adjacenciesIdentifier = vpnIfIdentifier.augmentation(Adjacencies.class);
778 // Looking for existing prefix in MDSAL database
779 Optional<Adjacencies> optionalAdjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker,
780 LogicalDatastoreType.CONFIGURATION, adjacenciesIdentifier);
781 if (optionalAdjacencies.isPresent()) {
782 List<Adjacency> adjacencies = optionalAdjacencies.get().getAdjacency();
783 Iterator<Adjacency> adjacencyIter = adjacencies.iterator();
784 while (adjacencyIter.hasNext()) {
785 Adjacency adjacency = adjacencyIter.next();
786 if (!adjacency.getSubnetId().equals(extSubnetId)) {
789 InstanceIdentifier<Adjacency> adjacencyIdentifier =
790 adjacenciesIdentifier.child(Adjacency.class, new AdjacencyKey(adjacency.getIpAddress()));
791 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
792 adjacencyIdentifier);
793 LOG.trace("Removed Adjacency for fixedIP {} for port {} on external subnet {} ",
794 adjacency.getIpAddress(), infName, extSubnetId);
795 String extNetVpnName = extNetId.getValue();
796 String learnedSrcIp = adjacency.getIpAddress().split("/")[0];
797 InstanceIdentifier<LearntVpnVipToPort> id =
798 NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(extNetVpnName, learnedSrcIp);
799 Optional<LearntVpnVipToPort> optionalLearntVpnVipToPort = SingleTransactionDataBroker
800 .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
801 if (optionalLearntVpnVipToPort.isPresent()) {
802 neutronvpnUtils.removeLearntVpnVipToPort(extNetVpnName, learnedSrcIp);
803 LOG.trace("Removed Learnt Entry for fixedIP {} for port {}",
804 adjacency.getIpAddress(), infName);
808 } catch (TransactionCommitFailedException | ReadFailedException e) {
809 LOG.error("exception in removeAdjacencyAndLearnedEntriesforExternalSubnet for interface {}",