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.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
26 import org.opendaylight.netvirt.elanmanager.api.IElanService;
27 import org.opendaylight.netvirt.neutronvpn.api.enums.IpVersionChoice;
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.adjacency.list.Adjacency;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.ExternalGatewayInfo;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.external_gateway_info.ExternalFixedIps;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
66 public class NeutronvpnNatManager implements AutoCloseable {
67 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnNatManager.class);
68 private static final int EXTERNAL_NO_CHANGE = 0;
69 private static final int EXTERNAL_ADDED = 1;
70 private static final int EXTERNAL_REMOVED = 2;
71 private static final int EXTERNAL_CHANGED = 3;
73 private final DataBroker dataBroker;
74 private final NeutronvpnUtils neutronvpnUtils;
75 private final NeutronvpnManager nvpnManager;
76 private final IElanService elanService;
79 public NeutronvpnNatManager(final DataBroker dataBroker, final NeutronvpnUtils neutronvpnUtils,
80 final NeutronvpnManager neutronvpnManager, final IElanService elanService) {
81 this.dataBroker = dataBroker;
82 this.neutronvpnUtils = neutronvpnUtils;
83 this.nvpnManager = neutronvpnManager;
84 this.elanService = elanService;
90 LOG.info("{} close", getClass().getSimpleName());
93 public void handleExternalNetworkForRouter(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 = origExtGw.getExternalFixedIps();
213 HashSet<String> origFixedIpSet = new HashSet<>();
214 for (ExternalFixedIps fixedIps : origExtFixedIps) {
215 origFixedIpSet.add(fixedIps.getIpAddress().stringValue());
217 List<ExternalFixedIps> newExtFixedIps = newExtGw.getExternalFixedIps();
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();
331 if (rtrList == null) {
332 rtrList = new ArrayList<>();
334 rtrList.add(routerId);
335 builder.setRouterIds(rtrList);
336 if (NeutronvpnUtils.isFlatOrVlanNetwork(input)) {
337 builder.setVpnid(extNetId);
340 Networks networkss = builder.build();
341 // Add Networks object to the ExternalNetworks list
342 LOG.trace("Updating externalnetworks {}", networkss);
343 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier,
345 LOG.trace("Updated externalnetworks successfully to CONFIG Datastore");
346 //get vpn external form this network external to setup vpnInternet for ipv6
347 Uuid vpnExternal = neutronvpnUtils.getVpnForNetwork(extNetId);
348 if (vpnExternal == null) {
349 LOG.debug("addExternalNetworkToRouter : no vpnExternal for Network {}", extNetId);
351 LOG.debug("addExternalNetworkToRouter : the vpnExternal {}", vpnExternal);
352 //get subnetmap associate to the router, any subnetmap "external" could be existing
353 List<Subnetmap> snList = neutronvpnUtils.getNeutronRouterSubnetMaps(routerId);
354 LOG.debug("addExternalNetworkToRouter : the vpnExternal {} subnetmap to be set with vpnInternet {}",
355 vpnExternal, snList);
356 for (Subnetmap sn : snList) {
357 if (sn.getInternetVpnId() == null) {
360 IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(sn.getSubnetIp());
361 if (ipVers == IpVersionChoice.IPV6) {
362 LOG.debug("addExternalNetworkToRouter : setup vpnInternet IPv6 for vpnExternal {} subnetmap {}",
364 nvpnManager.updateVpnInternetForSubnet(sn, vpnExternal, true);
367 } catch (TransactionCommitFailedException | ReadFailedException ex) {
368 LOG.error("Creation of externalnetworks failed for {}",
369 extNetId.getValue(), ex);
373 public void removeExternalNetworkFromRouter(Uuid origExtNetId, Router update,
374 List<ExternalFixedIps> origExtFixedIps) {
375 Uuid routerId = update.getUuid();
377 // Remove the router to the ExtRouters list
378 removeExternalRouter(update);
380 //Remove router entry from floating-ip-info list
381 removeRouterFromFloatingIpInfo(update, dataBroker);
383 // Remove the router from External Subnets
384 removeRouterFromExternalSubnets(routerId, origExtNetId, origExtFixedIps);
386 // Remove the router from the ExternalNetworks list
387 InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
388 .child(Networks.class, new NetworksKey(origExtNetId)).build();
389 Optional<Networks> optionalNets = null;
391 optionalNets = SingleTransactionDataBroker.syncReadOptional(dataBroker,
392 LogicalDatastoreType.CONFIGURATION, netsIdentifier);
393 } catch (ReadFailedException ex) {
394 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
395 origExtNetId.getValue(), routerId.getValue(), ex);
398 if (!optionalNets.isPresent()) {
399 LOG.error("removeExternalNetworkFromRouter: Provider Network {} not present in the NVPN datamodel",
400 origExtNetId.getValue());
403 Networks nets = optionalNets.get();
405 NetworksBuilder builder = new NetworksBuilder(nets);
406 List<Uuid> rtrList = builder.getRouterIds();
407 if (rtrList != null) {
408 rtrList.remove(routerId);
409 builder.setRouterIds(rtrList);
410 Networks networkss = builder.build();
411 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
412 netsIdentifier, networkss);
413 LOG.trace("removeExternalNetworkFromRouter: Remove router {} from External Networks node {}",
414 routerId, origExtNetId.getValue());
416 } catch (TransactionCommitFailedException ex) {
417 LOG.error("removeExternalNetworkFromRouter: Failed to remove provider network {} from router {}",
418 origExtNetId.getValue(), routerId.getValue(), ex);
421 // Remove the vpnInternetId fromSubnetmap
422 Network net = neutronvpnUtils.getNeutronNetwork(nets.getId());
423 List<Uuid> submapIds = neutronvpnUtils.getPrivateSubnetsToExport(net, /*internetVpnId*/ null);
424 for (Uuid snId : submapIds) {
425 Subnetmap subnetMap = neutronvpnUtils.getSubnetmap(snId);
426 if (subnetMap == null || subnetMap.getInternetVpnId() == null) {
427 LOG.error("removeExternalNetworkFromRouter: Can not find Subnetmap for SubnetId {} in ConfigDS",
431 LOG.trace("removeExternalNetworkFromRouter: Remove Internet VPN Id {} from SubnetMap {}",
432 subnetMap.getInternetVpnId(), subnetMap.getId());
433 IpVersionChoice ipVers = NeutronvpnUtils.getIpVersionFromString(subnetMap.getSubnetIp());
434 if (ipVers == IpVersionChoice.IPV6) {
435 nvpnManager.updateVpnInternetForSubnet(subnetMap, subnetMap.getInternetVpnId(), false);
436 LOG.debug("removeExternalNetworkFromRouter: Withdraw IPv6 routes from VPN {}",
437 subnetMap.getInternetVpnId());
442 public void addExternalRouter(Router update) {
443 Uuid routerId = update.getUuid();
444 Uuid extNetId = update.getExternalGatewayInfo().getExternalNetworkId();
445 Uuid gatewayPortId = update.getGatewayPortId();
446 // Create and add Routers object for this Router to the ExtRouters list
448 // Create a Routers object
449 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
452 Network input = neutronvpnUtils.getNeutronNetwork(extNetId);
453 ProviderTypes providerNwType = NeutronvpnUtils.getProviderNetworkType(input);
454 if (providerNwType == null) {
455 LOG.error("Unable to get Network Provider Type for network {}", input.getUuid().getValue());
458 Optional<Routers> optionalRouters =
459 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
461 LOG.trace("Creating/Updating a new Routers node: {}", routerId.getValue());
462 RoutersBuilder builder = null;
463 if (optionalRouters.isPresent()) {
464 builder = new RoutersBuilder(optionalRouters.get());
466 builder = new RoutersBuilder().withKey(new RoutersKey(routerId.getValue()));
468 builder.setRouterName(routerId.getValue());
469 builder.setNetworkId(extNetId);
470 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
472 ArrayList<ExternalIps> externalIps = new ArrayList<>();
473 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
474 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
476 builder.setExternalIps(externalIps);
478 if (gatewayPortId != null) {
479 LOG.trace("Setting/Updating gateway Mac for router {}", routerId.getValue());
480 Port port = neutronvpnUtils.getNeutronPort(gatewayPortId);
481 if (port != null && port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_GATEWAY_INF)) {
482 builder.setExtGwMacAddress(port.getMacAddress().getValue());
485 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
486 builder.setSubnetIds(subList);
487 Routers routers = builder.build();
488 // Add Routers object to the ExtRouters list
489 LOG.trace("Creating extrouters {}", routers);
490 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
492 LOG.trace("Wrote successfully Routers to CONFIG Datastore");
494 } catch (ReadFailedException | TransactionCommitFailedException ex) {
495 LOG.error("Creation of extrouters failed for router {} failed",
496 routerId.getValue(), ex);
500 // TODO Clean up the exception handling
501 @SuppressWarnings("checkstyle:IllegalCatch")
502 private void removeExternalRouter(Router update) {
503 Uuid routerId = update.getUuid();
505 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
508 Optional<Routers> optionalRouters =
509 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
511 LOG.trace(" Removing Routers node {}", routerId.getValue());
512 if (optionalRouters.isPresent()) {
513 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
514 builder.setExternalIps(null);
515 builder.setSubnetIds(null);
516 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
518 LOG.trace("Removed router {} from extrouters", routerId.getValue());
520 } catch (TransactionCommitFailedException | ReadFailedException ex) {
521 LOG.error("Removing extrouter {} from extrouters failed", routerId.getValue(), ex);
525 private void removeRouterFromFloatingIpInfo(Router update, DataBroker broker) {
526 Uuid routerId = update.getUuid();
527 InstanceIdentifier.InstanceIdentifierBuilder<RouterPorts> routerPortsIdentifierBuilder = InstanceIdentifier
528 .builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId.getValue()));
530 Optional<RouterPorts> optionalRouterPorts =
531 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
532 routerPortsIdentifierBuilder.build());
533 if (optionalRouterPorts.isPresent()) {
534 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.CONFIGURATION,
535 routerPortsIdentifierBuilder.build());
537 } catch (ReadFailedException | TransactionCommitFailedException e) {
538 LOG.error("Failed to read from FloatingIpInfo DS for routerid {}", routerId, e);
542 // TODO Clean up the exception handling
543 @SuppressWarnings("checkstyle:IllegalCatch")
544 private void handleExternalFixedIpsForRouter(Router update) {
545 Uuid routerId = update.getUuid();
546 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
548 Optional<Routers> optionalRouters =
549 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
551 LOG.trace("Updating External Fixed IPs Routers node {}", routerId.getValue());
552 if (optionalRouters.isPresent()) {
553 RoutersBuilder builder = new RoutersBuilder(optionalRouters.get());
554 List<ExternalIps> externalIps = new ArrayList<>();
555 for (ExternalFixedIps fixedIps : update.getExternalGatewayInfo().getExternalFixedIps()) {
556 addExternalFixedIpToExternalIpsList(externalIps, fixedIps);
559 builder.setExternalIps(externalIps);
561 updateExternalSubnetsForRouter(routerId, update.getExternalGatewayInfo().getExternalNetworkId(),
562 update.getExternalGatewayInfo().getExternalFixedIps());
563 Routers routerss = builder.build();
564 LOG.trace("Updating external fixed ips for router {} with value {}", routerId.getValue(), routerss);
565 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routersIdentifier,
567 LOG.trace("Added External Fixed IPs successfully for Routers to CONFIG Datastore");
569 } catch (TransactionCommitFailedException | ReadFailedException ex) {
570 LOG.error("Updating extfixedips for {} in extrouters failed", routerId.getValue(), ex);
574 public void handleSubnetsForExternalRouter(Uuid routerId) {
575 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
578 Optional<Routers> optionalRouters =
579 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
581 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
582 RoutersBuilder builder = null;
583 if (optionalRouters.isPresent()) {
584 builder = new RoutersBuilder(optionalRouters.get());
586 LOG.debug("No Routers element found for router {}", routerId.getValue());
589 List<Uuid> subList = neutronvpnUtils.getNeutronRouterSubnetIds(routerId);
590 builder.setSubnetIds(subList);
591 Routers routerss = builder.build();
592 // Add Routers object to the ExtRouters list
593 LOG.trace("Updating extrouters {}", routerss);
594 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
595 routersIdentifier, routerss);
596 LOG.trace("Updated successfully Routers to CONFIG Datastore");
597 } catch (TransactionCommitFailedException | ReadFailedException ex) {
598 LOG.error("Updation of internal subnets for extrouters failed for router {}",
599 routerId.getValue(), ex);
603 private void handleSnatSettingChangeForRouter(Router update) {
604 Uuid routerId = update.getUuid();
606 InstanceIdentifier<Routers> routersIdentifier = NeutronvpnUtils.buildExtRoutersIdentifier(routerId);
609 Optional<Routers> optionalRouters =
610 SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
612 LOG.trace("Updating Internal subnets for Routers node: {}", routerId.getValue());
613 RoutersBuilder builder = null;
614 if (optionalRouters.isPresent()) {
615 builder = new RoutersBuilder(optionalRouters.get());
617 LOG.trace("No Routers element found for router name {}", routerId.getValue());
620 builder.setEnableSnat(update.getExternalGatewayInfo().isEnableSnat());
621 Routers routerss = builder.build();
622 // Add Routers object to the ExtRouters list
623 LOG.trace("Updating extrouters for snat change {}", routerss);
624 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
625 routersIdentifier, routerss);
626 LOG.trace("Updated successfully Routers to CONFIG Datastore");
628 } catch (TransactionCommitFailedException | ReadFailedException ex) {
629 LOG.error("Updation of snat for extrouters failed for router {}", routerId.getValue(), ex);
633 public void updateOrAddExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
634 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
635 if (optionalExternalSubnets.isPresent()) {
636 LOG.trace("Will update external subnet {} with networkId {} and routerIds {}",
637 subnetId, networkId, routerIds);
638 updateExternalSubnet(networkId, subnetId, routerIds);
640 LOG.trace("Will add external subnet {} with networkId {} and routerIds {}",
641 subnetId, networkId, routerIds);
642 addExternalSubnet(networkId, subnetId, routerIds);
646 public void addExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
647 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
648 .child(Subnets.class, new SubnetsKey(subnetId)).build();
650 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
651 LOG.debug("Creating external subnet {}", newExternalSubnets);
652 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
654 } catch (TransactionCommitFailedException ex) {
655 LOG.error("Creation of External Subnets {} failed", subnetId, ex);
659 public void updateExternalSubnet(Uuid networkId, Uuid subnetId, List<Uuid> routerIds) {
660 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
661 .child(Subnets.class, new SubnetsKey(subnetId)).build();
663 Subnets newExternalSubnets = createSubnets(subnetId, networkId, routerIds);
664 LOG.debug("Updating external subnet {}", newExternalSubnets);
665 SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier,
667 } catch (TransactionCommitFailedException ex) {
668 LOG.error("Update of External Subnets {} failed", subnetId, ex);
672 public void removeExternalSubnet(Uuid networkId, Uuid subnetId) {
673 removeAdjacencyAndLearnedEntriesforExternalSubnet(networkId, subnetId);
674 InstanceIdentifier<Subnets> subnetsIdentifier = InstanceIdentifier.builder(ExternalSubnets.class)
675 .child(Subnets.class, new SubnetsKey(subnetId)).build();
677 LOG.debug("Removing external subnet {}", subnetId);
678 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
679 } catch (TransactionCommitFailedException ex) {
680 LOG.error("Deletion of External Subnets {} failed", subnetId, ex);
684 public void addRouterIdToExternalSubnet(Uuid networkId, Uuid subnetId, Uuid routerId) {
685 Optional<Subnets> optionalExternalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
686 if (optionalExternalSubnets.isPresent()) {
687 Subnets subnets = optionalExternalSubnets.get();
688 List<Uuid> routerIds;
689 if (subnets.getRouterIds() != null) {
690 routerIds = subnets.getRouterIds();
692 routerIds = new ArrayList<>();
695 if (subnets.getExternalNetworkId() != null
696 && subnets.getExternalNetworkId().equals(networkId) && !routerIds.contains(routerId)) {
697 LOG.debug("Will add routerID {} for external subnet {}.", routerId, subnetId);
698 routerIds.add(routerId);
699 updateExternalSubnet(networkId, subnetId, routerIds);
704 private static Subnets createSubnets(Uuid subnetId, Uuid networkId, List<Uuid> routerIds) {
705 SubnetsBuilder subnetsBuilder = new SubnetsBuilder();
706 subnetsBuilder.withKey(new SubnetsKey(subnetId));
707 subnetsBuilder.setId(subnetId);
708 subnetsBuilder.setVpnId(subnetId);
709 subnetsBuilder.setExternalNetworkId(networkId);
710 if (routerIds != null) {
711 subnetsBuilder.setRouterIds(routerIds);
714 return subnetsBuilder.build();
717 private void updateExternalSubnetsForRouter(Uuid routerId, Uuid externalNetworkId,
718 List<ExternalFixedIps> externalFixedIps) {
719 LOG.debug("Updating external subnets for router {} for external network ID {}",
720 routerId, externalNetworkId);
721 Set<Uuid> subnetsUuidsSet = getExternalSubnetsUuidsSetForFixedIps(externalFixedIps);
722 for (Uuid subnetId : subnetsUuidsSet) {
723 addRouterIdToExternalSubnet(externalNetworkId, subnetId, routerId);
727 private void removeRouterFromExternalSubnets(Uuid routerId, Uuid externalNetworkId,
728 List<ExternalFixedIps> externalFixedIps) {
729 LOG.debug("Removing routerID {} from external subnets of external network{}",
730 routerId, externalNetworkId);
732 List<Subnets> fixedIpsSubnets = getSubnets(getExternalSubnetsUuidsSetForFixedIps(externalFixedIps));
733 for (Subnets subnets : fixedIpsSubnets) {
734 Uuid subnetId = subnets.getId();
735 List<Uuid> routerIds = subnets.getRouterIds();
736 if (routerIds != null) {
737 if (subnets.getExternalNetworkId() != null
738 && subnets.getExternalNetworkId().equals(externalNetworkId)
739 && routerIds.contains(routerId)) {
740 routerIds.remove(routerId);
741 LOG.debug("Will remove routerIDs {} from external subnet {} router ID {}",
742 routerIds, subnetId, routerId);
743 addExternalSubnet(externalNetworkId, subnetId, routerIds);
749 private static Set<Uuid> getExternalSubnetsUuidsSetForFixedIps(List<ExternalFixedIps> externalFixedIps) {
750 Set<Uuid> subnetsUuidsSet = new HashSet<>();
751 for (ExternalFixedIps externalFixedIp : externalFixedIps) {
752 subnetsUuidsSet.add(externalFixedIp.getSubnetId());
755 return subnetsUuidsSet;
758 private List<Subnets> getSubnets(Set<Uuid> subnetsUuidsSet) {
759 List<Subnets> subnetsList = new ArrayList<>();
760 for (Uuid subnetId : subnetsUuidsSet) {
761 Optional<Subnets> optionalSubnets = neutronvpnUtils.getOptionalExternalSubnets(subnetId);
762 if (optionalSubnets.isPresent()) {
763 subnetsList.add(optionalSubnets.get());
770 private static void addExternalFixedIpToExternalIpsList(List<ExternalIps> externalIps, ExternalFixedIps fixedIps) {
771 Uuid subnetId = fixedIps.getSubnetId();
772 String ip = fixedIps.getIpAddress().stringValue();
773 ExternalIpsBuilder externalIpsBuilder = new ExternalIpsBuilder();
774 externalIpsBuilder.withKey(new ExternalIpsKey(ip, subnetId));
775 externalIpsBuilder.setIpAddress(ip);
776 externalIpsBuilder.setSubnetId(subnetId);
777 externalIps.add(externalIpsBuilder.build());
780 private void removeAdjacencyAndLearnedEntriesforExternalSubnet(Uuid extNetId, Uuid extSubnetId) {
781 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
782 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
783 LOG.error("No external ports attached to external network {}", extNetId.getValue());
787 for (String infName : extElanInterfaces) {
788 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
789 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
790 InstanceIdentifier<Adjacencies> adjacenciesIdentifier = vpnIfIdentifier.augmentation(Adjacencies.class);
792 // Looking for existing prefix in MDSAL database
793 Optional<Adjacencies> optionalAdjacencies = SingleTransactionDataBroker.syncReadOptional(dataBroker,
794 LogicalDatastoreType.CONFIGURATION, adjacenciesIdentifier);
795 if (optionalAdjacencies.isPresent()) {
796 List<Adjacency> adjacencies = optionalAdjacencies.get().getAdjacency();
797 Iterator<Adjacency> adjacencyIter = adjacencies.iterator();
798 while (adjacencyIter.hasNext()) {
799 Adjacency adjacency = adjacencyIter.next();
800 if (!adjacency.getSubnetId().equals(extSubnetId)) {
803 InstanceIdentifier<Adjacency> adjacencyIdentifier =
804 adjacenciesIdentifier.child(Adjacency.class, new AdjacencyKey(adjacency.getIpAddress()));
805 SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
806 adjacencyIdentifier);
807 LOG.trace("Removed Adjacency for fixedIP {} for port {} on external subnet {} ",
808 adjacency.getIpAddress(), infName, extSubnetId);
809 String extNetVpnName = extNetId.getValue();
810 String learnedSrcIp = adjacency.getIpAddress().split("/")[0];
811 InstanceIdentifier<LearntVpnVipToPort> id =
812 NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(extNetVpnName, learnedSrcIp);
813 Optional<LearntVpnVipToPort> optionalLearntVpnVipToPort = SingleTransactionDataBroker
814 .syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
815 if (optionalLearntVpnVipToPort.isPresent()) {
816 neutronvpnUtils.removeLearntVpnVipToPort(extNetVpnName, learnedSrcIp);
817 LOG.trace("Removed Learnt Entry for fixedIP {} for port {}",
818 adjacency.getIpAddress(), infName);
822 } catch (TransactionCommitFailedException | ReadFailedException e) {
823 LOG.error("exception in removeAdjacencyAndLearnedEntriesforExternalSubnet for interface {}",