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.HashSet;
13 import java.util.List;
14 import java.util.Objects;
16 import javax.annotation.PreDestroy;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
22 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
23 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
24 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
25 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
56 public class NeutronvpnNatManager implements AutoCloseable {
57 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnNatManager.class);
58 private static final int EXTERNAL_NO_CHANGE = 0;
59 private static final int EXTERNAL_ADDED = 1;
60 private static final int EXTERNAL_REMOVED = 2;
61 private static final int EXTERNAL_CHANGED = 3;
63 private final DataBroker dataBroker;
64 private final NeutronvpnUtils neutronvpnUtils;
65 private final NeutronvpnManager nvpnManager;
68 public NeutronvpnNatManager(final DataBroker dataBroker, final NeutronvpnUtils neutronvpnUtils,
69 final NeutronvpnManager neutronvpnManager) {
70 this.dataBroker = dataBroker;
71 this.neutronvpnUtils = neutronvpnUtils;
72 this.nvpnManager = neutronvpnManager;
78 LOG.info("{} close", getClass().getSimpleName());
81 public void handleExternalNetworkForRouter(Router original, Router update) {
82 Uuid routerId = update.getUuid();
83 Uuid origExtNetId = null;
84 Uuid updExtNetId = null;
85 List<ExternalFixedIps> origExtFixedIps;
87 LOG.trace("handleExternalNetwork for router {}", routerId);
88 int extNetChanged = externalNetworkChanged(original, update);
89 if (extNetChanged != EXTERNAL_NO_CHANGE) {
90 if (extNetChanged == EXTERNAL_ADDED) {
91 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
92 LOG.trace("External Network {} addition detected for router {}", updExtNetId.getValue(),
94 addExternalNetworkToRouter(update);
97 if (extNetChanged == EXTERNAL_REMOVED) {
98 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
99 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
100 LOG.trace("External Network removal detected for router {}", routerId.getValue());
101 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
102 //gateway mac unset handled as part of gateway clear deleting top-level routers node
106 origExtNetId = original.getExternalGatewayInfo().getExternalNetworkId();
107 origExtFixedIps = original.getExternalGatewayInfo().getExternalFixedIps();
108 updExtNetId = update.getExternalGatewayInfo().getExternalNetworkId();
109 LOG.trace("External Network changed from {} to {} for router {}",
110 origExtNetId.getValue(), updExtNetId.getValue(), routerId.getValue());
111 removeExternalNetworkFromRouter(origExtNetId, update, origExtFixedIps);
112 addExternalNetworkToRouter(update);
116 if (snatSettingChanged(original, update)) {
117 LOG.trace("SNAT settings on gateway changed for router {}", routerId.getValue());
118 handleSnatSettingChangeForRouter(update);
121 if (externalFixedIpsChanged(original, update)) {
122 LOG.trace("External Fixed IPs changed for router {}", routerId.getValue());
123 handleExternalFixedIpsForRouter(update);
127 private int externalNetworkChanged(Router original, Router update) {
128 String origExtNet = null;
129 String newExtNet = null;
130 if (original != null && original.getExternalGatewayInfo() != null) {
131 origExtNet = original.getExternalGatewayInfo().getExternalNetworkId().getValue();
134 if (update != null && update.getExternalGatewayInfo() != null) {
135 newExtNet = update.getExternalGatewayInfo().getExternalNetworkId().getValue();
138 if (origExtNet == null) {
139 if (newExtNet == null) {
140 return EXTERNAL_NO_CHANGE;
142 return EXTERNAL_ADDED;
144 if (newExtNet == null) {
145 return EXTERNAL_REMOVED;
147 if (!origExtNet.equals(newExtNet)) {
148 return EXTERNAL_CHANGED;
150 return EXTERNAL_NO_CHANGE;
154 private boolean snatSettingChanged(Router orig, Router update) {
155 ExternalGatewayInfo origExtGw = null;
156 ExternalGatewayInfo newExtGw = null;
157 if (orig != null && orig.getExternalGatewayInfo() != null) {
158 origExtGw = orig.getExternalGatewayInfo();
161 if (update != null && update.getExternalGatewayInfo() != null) {
162 newExtGw = update.getExternalGatewayInfo();
165 if (origExtGw == null) {
166 if (newExtGw != null) {
169 } else if (newExtGw == null || !Objects.equals(origExtGw.isEnableSnat(), newExtGw.isEnableSnat())) {
175 private boolean externalFixedIpsChanged(Router orig, Router update) {
176 ExternalGatewayInfo origExtGw = null;
177 ExternalGatewayInfo newExtGw = null;
178 if (orig != null && orig.getExternalGatewayInfo() != null) {
179 origExtGw = orig.getExternalGatewayInfo();
182 if (update != null && update.getExternalGatewayInfo() != null) {
183 newExtGw = update.getExternalGatewayInfo();
186 if (origExtGw == null && newExtGw != null && newExtGw.getExternalFixedIps() != null && !newExtGw
187 .getExternalFixedIps().isEmpty()) {
191 if (newExtGw == null && origExtGw != null && origExtGw.getExternalFixedIps() != null && !origExtGw
192 .getExternalFixedIps().isEmpty()) {
196 if (origExtGw != null && newExtGw != null) {
197 if (origExtGw.getExternalFixedIps() != null) {
198 if (!origExtGw.getExternalFixedIps().isEmpty()) {
199 if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
200 List<ExternalFixedIps> origExtFixedIps = origExtGw.getExternalFixedIps();
201 HashSet<String> origFixedIpSet = new HashSet<>();
202 for (ExternalFixedIps fixedIps : origExtFixedIps) {
203 origFixedIpSet.add(fixedIps.getIpAddress().getIpv4Address().getValue());
205 List<ExternalFixedIps> newExtFixedIps = newExtGw.getExternalFixedIps();
206 HashSet<String> updFixedIpSet = new HashSet<>();
207 for (ExternalFixedIps fixedIps : newExtFixedIps) {
208 updFixedIpSet.add(fixedIps.getIpAddress().getIpv4Address().getValue());
210 // returns true if external subnets have changed
211 return !origFixedIpSet.equals(updFixedIpSet) ? true : false;
214 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
217 } else if (newExtGw.getExternalFixedIps() != null && !newExtGw.getExternalFixedIps().isEmpty()) {
224 public void addExternalNetwork(Network net) {
225 Uuid extNetId = net.getUuid();
227 // Create and add Networks object for this External Network to the ExternalNetworks list
228 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
229 .child(Networks.class, new NetworksKey(extNetId)).build();
232 LOG.trace(" Creating/Updating a new Networks node {}", extNetId.getValue());
233 Optional<Networks> optionalNets =
234 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
236 if (optionalNets.isPresent()) {
237 LOG.error("External Network {} already detected to be present", extNetId.getValue());
240 ProviderTypes provType = NeutronvpnUtils.getProviderNetworkType(net);
241 if (provType == null) {
242 LOG.error("Unable to get Network Provider Type for network {}", extNetId);
245 NetworksBuilder builder = null;
246 builder = new NetworksBuilder().withKey(new NetworksKey(extNetId)).setId(extNetId);
247 builder.setVpnid(neutronvpnUtils.getVpnForNetwork(extNetId));
248 builder.setRouterIds(new ArrayList<>());
249 builder.setProviderNetworkType(provType);
251 Networks networkss = builder.build();
252 // Add Networks object to the ExternalNetworks list
253 LOG.trace("Creating externalnetworks {}", networkss);
254 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
256 LOG.trace("Wrote externalnetwork successfully to CONFIG Datastore");
257 } catch (TransactionCommitFailedException | ReadFailedException ex) {
258 LOG.error("Creation of External Network {} failed", extNetId.getValue(), ex);
262 public void removeExternalNetwork(Network net) {
263 Uuid extNetId = net.getUuid();
265 // Create and add Networks object for this External Network to the ExternalNetworks list
266 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
267 .child(Networks.class, new NetworksKey(extNetId)).build();
270 Optional<Networks> optionalNets =
271 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
273 LOG.trace("Removing Networks node {}", extNetId.getValue());
274 if (!optionalNets.isPresent()) {
275 LOG.error("External Network {} not available in the datastore", extNetId.getValue());
278 // Delete Networks object from the ExternalNetworks list
279 LOG.trace("Deleting External Network {}", extNetId.getValue());
280 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
281 LOG.trace("Deleted External Network {} successfully from CONFIG Datastore", extNetId.getValue());
283 } catch (TransactionCommitFailedException | ReadFailedException ex) {
284 LOG.error("Deletion of External Network {} failed", extNetId.getValue(), ex);
288 private void addExternalNetworkToRouter(Router update) {
289 Uuid routerId = update.getUuid();
290 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
291 List<ExternalFixedIps> externalFixedIps = update.getExternalGatewayInfo().getExternalFixedIps();
294 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
295 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
296 if (providerNwType == null) {
297 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
300 // Add this router to the ExtRouters list
301 addExternalRouter(update);
303 // Update External Subnets for this router
304 updateExternalSubnetsForRouter(routerId, extNetId, externalFixedIps);
306 // Create and add Networks object for this External Network to the ExternalNetworks list
307 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
308 .child(Networks.class, new NetworksKey(extNetId)).build();
310 Optional<Networks> optionalNets =
311 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
313 if (!optionalNets.isPresent()) {
314 LOG.error("External Network {} not present in the NVPN datamodel", extNetId.getValue());
317 NetworksBuilder builder = new NetworksBuilder(optionalNets.get());
318 List<Uuid> rtrList = builder.getRouterIds();
319 if (rtrList == null) {
320 rtrList = new ArrayList<>();
322 rtrList.add(routerId);
323 builder.setRouterIds(rtrList);
324 if (NeutronvpnUtils.isFlatOrVlanNetwork(input)) {
325 builder.setVpnid(extNetId);
328 Networks networkss = builder.build();
329 // Add Networks object to the ExternalNetworks list
330 LOG.trace("Updating externalnetworks {}", networkss);
331 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
333 LOG.trace("Updated externalnetworks successfully to CONFIG Datastore");
334 //get vpn external form this network external to setup vpnInternet for ipv6
335 Uuid vpnExternal = neutronvpnUtils.getVpnForNetwork(extNetId);
336 if (vpnExternal == null) {
337 LOG.debug("addExternalNetworkToRouter : no vpnExternal for Network {}", extNetId);
339 LOG.debug("addExternalNetworkToRouter : the vpnExternal {}", vpnExternal);
340 //get subnetmap associate to the router, any subnetmap "external" could be existing
341 List<Subnetmap> snList = neutronvpnUtils.getNeutronRouterSubnetMaps(routerId);
342 LOG.debug("addExternalNetworkToRouter : the vpnExternal {} subnetmap to be set with vpnInternet {}",
343 vpnExternal, snList);
344 for (Subnetmap sn : snList) {
345 if (sn.getInternetVpnId() == null) {
348 IpVersionChoice ipVers = neutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
349 if (ipVers == IpVersionChoice.IPV6) {
350 LOG.debug("addExternalNetworkToRouter : setup vpnInternet IPv6 for vpnExternal {} subnetmap {}",
352 nvpnManager.updateVpnInternetForSubnet(sn, vpnExternal, true);
355 } catch (TransactionCommitFailedException | ReadFailedException ex) {
356 LOG.error("Creation of externalnetworks failed for {}",
357 extNetId.getValue(), ex);
361 public void removeExternalNetworkFromRouter(Uuid origExtNetId, Router update,
362 List<ExternalFixedIps> origExtFixedIps) {
363 Uuid routerId = update.getUuid();
365 // Remove the router to the ExtRouters list
366 removeExternalRouter(update);
368 //Remove router entry from floating-ip-info list
369 removeRouterFromFloatingIpInfo(update, dataBroker);
371 // Remove the router from External Subnets
372 removeRouterFromExternalSubnets(routerId, origExtNetId, origExtFixedIps);
374 // Remove the router from the ExternalNetworks list
375 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
376 .child(Networks.class, new NetworksKey(origExtNetId)).build();
377 Optional<Networks> optionalNets = null;
379 optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
380 LogicalDatastoreType.CONFIGURATION, netsIdentifier);
381 } catch (ReadFailedException ex) {
382 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
383 origExtNetId.getValue(), routerId.getValue(), ex);
386 if (!optionalNets.isPresent()) {
387 LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
388 origExtNetId.getValue());
391 Networks nets = optionalNets.get();
393 NetworksBuilder builder = new NetworksBuilder(nets);
394 List<Uuid> rtrList = builder.getRouterIds();
395 if (rtrList != null) {
396 rtrList.remove(routerId);
397 builder.setRouterIds(rtrList);
398 Networks networkss = builder.build();
399 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
400 netsIdentifier, networkss);
401 LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
402 routerId, origExtNetId.getValue());
404 } catch (TransactionCommitFailedException ex) {
405 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
406 origExtNetId.getValue(), routerId.getValue(), ex);
409 // Remove the vpnInternetId fromSubnetmap
410 Network net = neutronvpnUtils.getNeutronNetwork(nets.getId());
411 List<Uuid> submapIds = neutronvpnUtils.getPrivateSubnetsToExport(net);
412 for (Uuid snId : submapIds) {
413 Subnetmap subnetMap = neutronvpnUtils.getSubnetmap(snId);
414 if ((subnetMap == null) || (subnetMap.getInternetVpnId() == null)) {
415 LOG.error("removeExternalNetworkFromRouter: Can not find Subnetmap for SubnetId {} in ConfigDS",
419 LOG.trace("removeExternalNetworkFromRouter: Remove Internet VPN Id {} from SubnetMap {}",
420 subnetMap.getInternetVpnId(), subnetMap.getId());
421 IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(subnetMap.getSubnetIp());
422 if (ipVers == IpVersionChoice.IPV6) {
423 nvpnManager.updateVpnInternetForSubnet(subnetMap, subnetMap.getInternetVpnId(), false);
424 LOG.debug("removeExternalNetworkFromRouter: Withdraw IPv6 routes from VPN {}",
425 subnetMap.getInternetVpnId());
430 public void addExternalRouter(Router update) {
431 Uuid routerId = update.getUuid();
432 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
433 Uuid gatewayPortId = update.getGatewayPortId();
434 // Create and add Routers object for this Router to the ExtRouters list
436 // Create a Routers object
437 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
440 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
441 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
442 if (providerNwType == null) {
443 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
446 Optional<Routers> optionalRouters =
447 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
449 LOG.trace("Creating/Updating a new Routers node: {}", routerId.getValue());
450 RoutersBuilder builder = null;
451 if (optionalRouters.isPresent()) {
452 builder = new RoutersBuilder(optionalRouters.get());
454 builder = new RoutersBuilder().withKey(new RoutersKey(routerId.getValue()));
456 builder.setRouterName(routerId.getValue());
457 builder.setNetworkId(extNetId);
458 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
460 ArrayList<ExternalIps> externalIps = new ArrayList<>();
461 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
462 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
464 builder.setExternalIps(externalIps);
466 if (gatewayPortId != null) {
467 LOG.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
468 Port port = neutronvpnUtils.getNeutronPort(gatewayPortId);
469 if (port != null && port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
470 builder.setExtGwMacAddress(port.getMacAddress().getValue());
473 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
474 builder.setSubnetIds(subList);
475 Routers routers = builder.build();
476 // Add Routers object to the ExtRouters list
477 LOG.trace("Creating extrouters {}", routers);
478 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
480 LOG.trace("Wrote successfully Routers to CONFIG Datastore");
482 } catch (ReadFailedException | TransactionCommitFailedException ex) {
483 LOG.error("Creation of extrouters failed for router {} failed",
484 routerId.getValue(), ex);
488 // TODO Clean up the exception handling
489 @SuppressWarnings("checkstyle:IllegalCatch")
490 private void removeExternalRouter(Router update) {
491 Uuid routerId = update.getUuid();
493 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
496 Optional<Routers> optionalRouters =
497 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
499 LOG.trace(" Removing Routers node {}", routerId.getValue());
500 if (optionalRouters.isPresent()) {
501 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
502 builder.setExternalIps(null);
503 builder.setSubnetIds(null);
504 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
506 LOG.trace("Removed router {} from extrouters", routerId.getValue());
508 } catch (TransactionCommitFailedException | ReadFailedException ex) {
509 LOG.error("Removing extrouter {} from extrouters failed", routerId.getValue(), ex);
513 private void removeRouterFromFloatingIpInfo(Router update, DataBroker broker) {
514 Uuid routerId = update.getUuid();
515 InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder = InstanceIdentifier
516 .builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId.getValue()));
518 Optional<RouterPorts> optionalRouterPorts =
519 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
520 routerPortsIdentifierBuilder.build());
521 if (optionalRouterPorts.isPresent()) {
522 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
523 routerPortsIdentifierBuilder.build());
525 } catch (ReadFailedException | TransactionCommitFailedException e) {
526 LOG.error("Failed to read from FloatingIpInfo DS for routerid {}", routerId, e);
530 // TODO Clean up the exception handling
531 @SuppressWarnings("checkstyle:IllegalCatch")
532 private void handleExternalFixedIpsForRouter(Router update) {
533 Uuid routerId = update.getUuid();
534 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
536 Optional<Routers> optionalRouters =
537 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
539 LOG.trace("Updating External Fixed IPs Routers node {}", routerId.getValue());
540 if (optionalRouters.isPresent()) {
541 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
542 List<ExternalIps> externalIps = new ArrayList<>();
543 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
544 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
547 builder.setExternalIps(externalIps);
549 updateExternalSubnetsForRouter(routerId, update.getExternalGatewayInfo().getExternalNetworkId(),
550 update.getExternalGatewayInfo().getExternalFixedIps());
551 Routers routerss = builder.build();
552 LOG.trace("Updating external fixed ips for router {} with value {}", routerId.getValue(), routerss);
553 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
555 LOG.trace("Added External Fixed IPs successfully for Routers to CONFIG Datastore");
557 } catch (TransactionCommitFailedException | ReadFailedException ex) {
558 LOG.error("Updating extfixedips for {} in extrouters failed", routerId.getValue(), ex);
562 public void handleSubnetsForExternalRouter(Uuid routerId) {
563 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
566 Optional<Routers> optionalRouters =
567 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
569 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
570 RoutersBuilder builder = null;
571 if (optionalRouters.isPresent()) {
572 builder = new RoutersBuilder(optionalRouters.get());
574 LOG.debug("No Routers element found for router {}", routerId.getValue());
577 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
578 builder.setSubnetIds(subList);
579 Routers routerss = builder.build();
580 // Add Routers object to the ExtRouters list
581 LOG.trace("Updating extrouters {}", routerss);
582 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
583 routersIdentifier, routerss);
584 LOG.trace("Updated successfully Routers to CONFIG Datastore");
585 } catch (TransactionCommitFailedException | ReadFailedException ex) {
586 LOG.error("Updation of internal subnets for extrouters failed for router {}",
587 routerId.getValue(), ex);
591 private void handleSnatSettingChangeForRouter(Router update) {
592 Uuid routerId = update.getUuid();
594 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
597 Optional<Routers> optionalRouters =
598 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
600 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
601 RoutersBuilder builder = null;
602 if (optionalRouters.isPresent()) {
603 builder = new RoutersBuilder(optionalRouters.get());
605 LOG.trace("No Routers element found for router name {}", routerId.getValue());
608 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
609 Routers routerss = builder.build();
610 // Add Routers object to the ExtRouters list
611 LOG.trace("Updating extrouters for snat change {}", routerss);
612 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
613 routersIdentifier, routerss);
614 LOG.trace("Updated successfully Routers to CONFIG Datastore");
616 } catch (TransactionCommitFailedException | ReadFailedException ex) {
617 LOG.error("Updation of snat for extrouters failed for router {}", routerId.getValue(), ex);
621 public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
622 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
623 if (optionalExternalSubnets.isPresent()) {
624 LOG.trace("Will update external subnet {} with networkId {} and routerIds {}",
625 subnetId, networkId, routerIds);
626 updateExternalSubnet(networkId, subnetId, routerIds);
628 LOG.trace("Will add external subnet {} with networkId {} and routerIds {}",
629 subnetId, networkId, routerIds);
630 addExternalSubnet(networkId, subnetId, routerIds);
634 public void addExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
635 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
636 .child(Subnets.class, new SubnetsKey(subnetId)).build();
638 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
639 LOG.debug("Creating external subnet {}", newExternalSubnets);
640 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
642 } catch (TransactionCommitFailedException ex) {
643 LOG.error("Creation of External Subnets {} failed", subnetId, ex);
647 public void updateExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
648 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
649 .child(Subnets.class, new SubnetsKey(subnetId)).build();
651 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
652 LOG.debug("Updating external subnet {}", newExternalSubnets);
653 SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
655 } catch (TransactionCommitFailedException ex) {
656 LOG.error("Update of External Subnets {} failed", subnetId, ex);
660 public void removeExternalSubnet(Uuid subnetId) {
661 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
662 .child(Subnets.class, new SubnetsKey(subnetId)).build();
664 LOG.debug("Removing external subnet {}", subnetId);
665 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
666 } catch (TransactionCommitFailedException ex) {
667 LOG.error("Deletion of External Subnets {} failed", subnetId, ex);
671 public void addRouterIdToExternalSubnet(Uuid networkId, Uuid subnetId, Uuid routerId) {
672 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
673 if (optionalExternalSubnets.isPresent()) {
674 Subnets subnets = optionalExternalSubnets.get();
675 List<Uuid> routerIds;
676 if (subnets.getRouterIds() != null) {
677 routerIds = subnets.getRouterIds();
679 routerIds = new ArrayList<>();
682 if (subnets.getExternalNetworkId() != null
683 && subnets.getExternalNetworkId().equals(networkId) && !routerIds.contains(routerId)) {
684 LOG.debug("Will add routerID {} for external subnet {}.", routerId, subnetId);
685 routerIds.add(routerId);
686 updateExternalSubnet(networkId, subnetId, routerIds);
691 private Subnets createSubnets(Uuid subnetId, Uuid networkId, List<Uuid> routerIds) {
692 SubnetsBuilder subnetsBuilder = new SubnetsBuilder();
693 subnetsBuilder.withKey(new SubnetsKey(subnetId));
694 subnetsBuilder.setId(subnetId);
695 subnetsBuilder.setVpnId(subnetId);
696 subnetsBuilder.setExternalNetworkId(networkId);
697 if (routerIds != null) {
698 subnetsBuilder.setRouterIds(routerIds);
701 return subnetsBuilder.build();
704 private void updateExternalSubnetsForRouter(Uuid routerId, Uuid externalNetworkId,
705 List<ExternalFixedIps> externalFixedIps) {
706 LOG.debug("Updating external subnets for router {} for external network ID {}",
707 routerId, externalNetworkId);
708 Set<Uuid> subnetsUuidsSet = getExternalSubnetsUuidsSetForFixedIps(externalFixedIps);
709 for (Uuid subnetId : subnetsUuidsSet) {
710 addRouterIdToExternalSubnet(externalNetworkId, subnetId, routerId);
714 private void removeRouterFromExternalSubnets(Uuid routerId, Uuid externalNetworkId,
715 List<ExternalFixedIps> externalFixedIps) {
716 LOG.debug("Removing routerID {} from external subnets of external network{}",
717 routerId, externalNetworkId);
719 List<Subnets> fixedIpsSubnets = getSubnets(getExternalSubnetsUuidsSetForFixedIps(externalFixedIps));
720 for (Subnets subnets : fixedIpsSubnets) {
721 Uuid subnetId = subnets.getId();
722 List<Uuid> routerIds = subnets.getRouterIds();
723 if (routerIds != null) {
724 if (subnets.getExternalNetworkId() != null
725 && subnets.getExternalNetworkId().equals(externalNetworkId)
726 && routerIds.contains(routerId)) {
727 routerIds.remove(routerId);
728 LOG.debug("Will remove routerIDs {} from external subnet {} router ID {}",
729 routerIds, subnetId, routerId);
730 addExternalSubnet(externalNetworkId, subnetId, routerIds);
736 private Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
737 Set<Uuid> subnetsUuidsSet = new HashSet<>();
738 for (ExternalFixedIps externalFixedIp : externalFixedIps) {
739 subnetsUuidsSet.add(externalFixedIp.getSubnetId());
742 return subnetsUuidsSet;
745 private List<Subnets> getSubnets(Set<Uuid> subnetsUuidsSet) {
746 List<Subnets> subnetsList = new ArrayList<>();
747 for (Uuid subnetId : subnetsUuidsSet) {
748 Optional<Subnets> optionalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
749 if (optionalSubnets.isPresent()) {
750 subnetsList.add(optionalSubnets.get());
757 private void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
758 Uuid subnetId = fixedIps.getSubnetId();
759 String ip = fixedIps.getIpAddress().getIpv4Address().getValue();
760 ExternalIpsBuilder externalIpsBuilder = new ExternalIpsBuilder();
761 externalIpsBuilder.withKey(new ExternalIpsKey(ip, subnetId));
762 externalIpsBuilder.setIpAddress(ip);
763 externalIpsBuilder.setSubnetId(subnetId);
764 externalIps.add(externalIpsBuilder.build());