2 * Copyright © 2015, 2017 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 com.google.common.util.concurrent.ListenableFuture;
12 import com.google.common.util.concurrent.SettableFuture;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.EventListener;
17 import java.util.HashMap;
18 import java.util.Iterator;
19 import java.util.List;
21 import java.util.Objects;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.Future;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
26 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
29 import org.opendaylight.genius.mdsalutil.MDSALUtil;
30 import org.opendaylight.netvirt.elanmanager.api.IElanService;
31 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
35 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
37 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
38 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
39 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
40 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
41 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
42 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
43 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
44 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
45 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.config.rev160806.NeutronvpnConfig;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutputBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutputBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutputBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateRouterInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpn;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpnBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpn;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpnBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteOutput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
115 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
116 import org.opendaylight.yangtools.yang.common.RpcError;
117 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
118 import org.opendaylight.yangtools.yang.common.RpcResult;
119 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
120 import org.slf4j.Logger;
121 import org.slf4j.LoggerFactory;
123 public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, EventListener {
124 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnManager.class);
125 private final DataBroker dataBroker;
126 private final NeutronvpnNatManager nvpnNatManager;
127 private final NotificationPublishService notificationPublishService;
128 private final VpnRpcService vpnRpcService;
129 private final NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
130 private final NeutronvpnConfig neutronvpnConfig;
131 private final IElanService elanService;
133 public NeutronvpnManager(
134 final DataBroker dataBroker, final NotificationPublishService notiPublishService,
135 final NeutronvpnNatManager vpnNatMgr, final VpnRpcService vpnRpcSrv, final IElanService elanService,
136 final NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener,
137 final NeutronvpnConfig neutronvpnConfig) {
138 this.dataBroker = dataBroker;
139 nvpnNatManager = vpnNatMgr;
140 notificationPublishService = notiPublishService;
141 vpnRpcService = vpnRpcSrv;
142 this.elanService = elanService;
143 floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
144 LOG.info("neutronvpnConfig: {}", neutronvpnConfig);
145 this.neutronvpnConfig = neutronvpnConfig;
149 public void close() throws Exception {
150 LOG.info("{} close", getClass().getSimpleName());
153 public NeutronvpnConfig getNeutronvpnConfig() {
154 return neutronvpnConfig;
157 // TODO Clean up the exception handling
158 @SuppressWarnings("checkstyle:IllegalCatch")
159 protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
160 Uuid routerInterfaceName, String fixedIp,
161 String routerIntfMacAddress) {
162 Subnetmap subnetmap = null;
163 SubnetmapBuilder builder = null;
164 InstanceIdentifier<Subnetmap> id =
165 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
167 synchronized (subnetId.getValue().intern()) {
168 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
169 if (sn.isPresent()) {
170 builder = new SubnetmapBuilder(sn.get());
171 LOG.debug("WithRouterFixedIPs: Updating existing subnetmap node for subnet ID {}",
172 subnetId.getValue());
174 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
175 LOG.debug("WithRouterFixedIPs: creating new subnetmap node for subnet ID {}",
176 subnetId.getValue());
178 builder.setRouterId(routerId);
179 builder.setRouterInterfaceName(routerInterfaceName);
180 builder.setRouterIntfMacAddress(routerIntfMacAddress);
181 if (fixedIp != null) {
182 List<String> fixedIps = builder.getRouterInterfaceFixedIps();
183 if (fixedIps == null) {
184 fixedIps = new ArrayList<>();
186 fixedIps.add(fixedIp);
187 builder.setRouterInterfaceFixedIps(fixedIps);
189 builder.setRouterInterfaceFixedIps(null);
191 subnetmap = builder.build();
192 LOG.debug("WithRouterFixedIPs Creating/Updating subnetMap node for Router FixedIps: {} ",
193 subnetId.getValue());
194 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
196 } catch (Exception e) {
197 LOG.error("WithRouterFixedIPs: Updation of subnetMap for Router FixedIps failed for node: {}",
198 subnetId.getValue());
202 // TODO Clean up the exception handling
203 @SuppressWarnings("checkstyle:IllegalCatch")
204 protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
206 Subnetmap subnetmap = null;
207 SubnetmapBuilder builder = null;
208 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
209 .child(Subnetmap.class, new SubnetmapKey(subnetId))
212 synchronized (subnetId.getValue().intern()) {
213 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
214 if (sn.isPresent()) {
215 builder = new SubnetmapBuilder(sn.get());
216 LOG.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
218 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
219 LOG.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
222 if (subnetIp != null) {
223 builder.setSubnetIp(subnetIp);
225 if (routerId != null) {
226 builder.setRouterId(routerId);
228 if (networkId != null) {
229 builder.setNetworkId(networkId);
232 builder.setVpnId(vpnId);
234 if (tenantId != null) {
235 builder.setTenantId(tenantId);
238 subnetmap = builder.build();
239 LOG.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
240 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
242 } catch (Exception e) {
243 LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
248 // TODO Clean up the exception handling
249 @SuppressWarnings("checkstyle:IllegalCatch")
250 protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
251 Subnetmap subnetmap = null;
252 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
253 .child(Subnetmap.class, new SubnetmapKey(subnetId))
256 synchronized (subnetId.getValue().intern()) {
257 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
258 if (sn.isPresent()) {
259 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
260 if (routerId != null) {
261 builder.setRouterId(null);
263 if (networkId != null) {
264 builder.setNetworkId(null);
267 builder.setVpnId(null);
269 if (portId != null && builder.getPortList() != null) {
270 List<Uuid> portList = builder.getPortList();
271 portList.remove(portId);
272 builder.setPortList(portList);
275 subnetmap = builder.build();
276 LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
277 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
279 LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
282 } catch (Exception e) {
283 LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
288 // TODO Clean up the exception handling
289 @SuppressWarnings("checkstyle:IllegalCatch")
290 protected Subnetmap updateSubnetmapNodeWithPorts(Uuid subnetId, Uuid portId, Uuid directPortId) {
291 Subnetmap subnetmap = null;
292 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
293 new SubnetmapKey(subnetId)).build();
295 synchronized (subnetId.getValue().intern()) {
296 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
297 if (sn.isPresent()) {
298 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
299 if (null != portId) {
300 List<Uuid> portList = builder.getPortList();
301 if (null == portList) {
302 portList = new ArrayList<>();
304 portList.add(portId);
305 builder.setPortList(portList);
306 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
309 if (null != directPortId) {
310 List<Uuid> directPortList = builder.getDirectPortList();
311 if (null == directPortList) {
312 directPortList = new ArrayList<>();
314 directPortList.add(directPortId);
315 builder.setDirectPortList(directPortList);
316 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
317 directPortId.getValue());
319 subnetmap = builder.build();
320 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
322 LOG.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
325 } catch (Exception e) {
326 LOG.error("Updating port list of a given subnetMap failed for node: {} with exception{}",
327 subnetId.getValue(), e);
332 // TODO Clean up the exception handling
333 @SuppressWarnings("checkstyle:IllegalCatch")
334 protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
335 Subnetmap subnetmap = null;
336 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
337 new SubnetmapKey(subnetId)).build();
339 synchronized (subnetId.getValue().intern()) {
340 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
341 if (sn.isPresent()) {
342 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
343 if (null != portId && null != builder.getPortList()) {
344 List<Uuid> portList = builder.getPortList();
345 portList.remove(portId);
346 builder.setPortList(portList);
347 LOG.debug("Removing port {} from existing subnetmap node: {} ", portId.getValue(),
348 subnetId.getValue());
350 if (null != directPortId && null != builder.getDirectPortList()) {
351 List<Uuid> directPortList = builder.getDirectPortList();
352 directPortList.remove(directPortId);
353 builder.setDirectPortList(directPortList);
354 LOG.debug("Removing direct port {} from existing subnetmap node: {} ", directPortId
355 .getValue(), subnetId.getValue());
357 subnetmap = builder.build();
358 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
360 LOG.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
363 } catch (Exception e) {
364 LOG.error("Removing a port from port list of a subnetmap failed for node: {} with expection {}",
365 subnetId.getValue(), e);
370 // TODO Clean up the exception handling
371 @SuppressWarnings("checkstyle:IllegalCatch")
372 protected void deleteSubnetMapNode(Uuid subnetId) {
373 InstanceIdentifier<Subnetmap> subnetMapIdentifier =
374 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,new SubnetmapKey(subnetId)).build();
375 LOG.debug("removing subnetMap node: {} ", subnetId.getValue());
377 synchronized (subnetId.getValue().intern()) {
378 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
380 } catch (Exception e) {
381 LOG.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
385 // TODO Clean up the exception handling
386 @SuppressWarnings("checkstyle:IllegalCatch")
387 private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert,
388 VpnInstance.Type type, long l3vni) {
389 VpnInstanceBuilder builder = null;
390 List<VpnTarget> vpnTargetList = new ArrayList<>();
391 boolean isLockAcquired = false;
392 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
393 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
395 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
397 LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
398 if (optionalVpn.isPresent()) {
399 builder = new VpnInstanceBuilder(optionalVpn.get());
400 LOG.debug("updating existing vpninstance node");
402 builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName)
403 .setType(type).setL3vni(l3vni);
405 if (irt != null && !irt.isEmpty()) {
406 if (ert != null && !ert.isEmpty()) {
407 List<String> commonRT = new ArrayList<>(irt);
408 commonRT.retainAll(ert);
410 for (String common : commonRT) {
413 VpnTarget vpnTarget =
414 new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue(common)
415 .setVrfRTType(VpnTarget.VrfRTType.Both).build();
416 vpnTargetList.add(vpnTarget);
419 for (String importRT : irt) {
420 VpnTarget vpnTarget =
421 new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue(importRT)
422 .setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
423 vpnTargetList.add(vpnTarget);
427 if (ert != null && !ert.isEmpty()) {
428 for (String exportRT : ert) {
429 VpnTarget vpnTarget =
430 new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue(exportRT)
431 .setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
432 vpnTargetList.add(vpnTarget);
436 VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
438 Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
440 if (rd != null && !rd.isEmpty()) {
441 ipv4vpnBuilder.setRouteDistinguisher(rd);
444 VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
445 isLockAcquired = NeutronvpnUtils.lock(vpnName);
446 LOG.debug("Creating/Updating vpn-instance for {} ", vpnName);
447 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
448 } catch (Exception e) {
449 LOG.error("Update VPN Instance node failed for node: {} {} {} {}", vpnName, rd, irt, ert);
451 if (isLockAcquired) {
452 NeutronvpnUtils.unlock(vpnName);
457 // TODO Clean up the exception handling
458 @SuppressWarnings("checkstyle:IllegalCatch")
459 private void deleteVpnMapsNode(Uuid vpnid) {
460 boolean isLockAcquired = false;
461 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
462 .child(VpnMap.class, new VpnMapKey(vpnid))
464 LOG.debug("removing vpnMaps node: {} ", vpnid.getValue());
466 isLockAcquired = NeutronvpnUtils.lock(vpnid.getValue());
467 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
468 } catch (Exception e) {
469 LOG.error("Delete vpnMaps node failed for vpn : {} ", vpnid.getValue());
471 if (isLockAcquired) {
472 NeutronvpnUtils.unlock(vpnid.getValue());
477 // TODO Clean up the exception handling
478 @SuppressWarnings("checkstyle:IllegalCatch")
479 private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
480 VpnMapBuilder builder;
481 boolean isLockAcquired = false;
482 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
483 .child(VpnMap.class, new VpnMapKey(vpnId))
486 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
488 if (optionalVpnMap.isPresent()) {
489 builder = new VpnMapBuilder(optionalVpnMap.get());
491 builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
495 builder.setName(name);
497 if (tenantId != null) {
498 builder.setTenantId(tenantId);
500 if (router != null) {
501 builder.setRouterId(router);
503 if (networks != null) {
504 List<Uuid> nwList = builder.getNetworkIds();
505 if (nwList == null) {
506 nwList = new ArrayList<>();
508 nwList.addAll(networks);
509 builder.setNetworkIds(nwList);
512 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
513 LOG.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
514 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
515 LOG.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
516 } catch (Exception e) {
517 LOG.error("UpdateVpnMaps failed for node: {} ", vpnId.getValue());
519 if (isLockAcquired) {
520 NeutronvpnUtils.unlock(vpnId.getValue());
525 // TODO Clean up the exception handling
526 @SuppressWarnings("checkstyle:IllegalCatch")
527 private void clearFromVpnMaps(Uuid vpnId, Uuid routerId, List<Uuid> networkIds) {
528 boolean isLockAcquired = false;
529 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
530 .child(VpnMap.class, new VpnMapKey(vpnId))
532 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
534 if (optionalVpnMap.isPresent()) {
535 VpnMap vpnMap = optionalVpnMap.get();
536 VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
537 if (routerId != null) {
538 if (vpnMap.getNetworkIds() == null && routerId.equals(vpnMap.getVpnId())) {
540 // remove entire node in case of internal VPN
541 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
542 LOG.debug("removing vpnMaps node: {} ", vpnId);
543 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
544 } catch (Exception e) {
545 LOG.error("Deletion of vpnMaps node failed for vpn {}", vpnId.getValue());
547 if (isLockAcquired) {
548 NeutronvpnUtils.unlock(vpnId.getValue());
553 vpnMapBuilder.setRouterId(null);
555 if (networkIds != null) {
556 List<Uuid> vpnNw = vpnMap.getNetworkIds();
557 for (Uuid nw : networkIds) {
560 if (vpnNw.isEmpty()) {
561 LOG.debug("setting networks null in vpnMaps node: {} ", vpnId.getValue());
562 vpnMapBuilder.setNetworkIds(null);
564 vpnMapBuilder.setNetworkIds(vpnNw);
569 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
570 LOG.debug("clearing from vpnMaps node: {} ", vpnId.getValue());
571 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier,
572 vpnMapBuilder.build());
573 } catch (Exception e) {
574 LOG.error("Clearing from vpnMaps node failed for vpn {}", vpnId.getValue());
576 if (isLockAcquired) {
577 NeutronvpnUtils.unlock(vpnId.getValue());
581 LOG.error("VPN : {} not found", vpnId.getValue());
583 LOG.debug("Clear from VPNMaps DS successful for VPN {} ", vpnId.getValue());
586 // TODO Clean up the exception handling
587 @SuppressWarnings("checkstyle:IllegalCatch")
588 private void deleteVpnInstance(Uuid vpnId) {
589 boolean isLockAcquired = false;
590 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
591 .child(VpnInstance.class,
592 new VpnInstanceKey(vpnId.getValue()))
595 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
596 LOG.debug("Deleting vpnInstance {}", vpnId.getValue());
597 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
598 } catch (Exception e) {
599 LOG.error("Deletion of VPNInstance node failed for VPN {}", vpnId.getValue());
601 if (isLockAcquired) {
602 NeutronvpnUtils.unlock(vpnId.getValue());
607 protected void createVpnInterface(Uuid vpnId, Uuid routerId, Port port,
608 WriteTransaction wrtConfigTxn) {
609 String infName = port.getUuid().getValue();
610 List<Adjacency> adjList = new ArrayList<>();
611 Boolean isRouterInterface = false;
612 if (port.getDeviceOwner() != null) {
613 isRouterInterface = port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF);
615 LOG.trace("createVpnInterface - isRouterInterface:{}", isRouterInterface);
617 if (routerId != null) {
618 rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
620 List<FixedIps> ips = port.getFixedIps();
621 // create adjacency list
622 for (FixedIps ip : ips) {
623 // create vm adjacency
624 String ipValue = String.valueOf(ip.getIpAddress().getValue());
625 String ipPrefix = (ip.getIpAddress().getIpv4Address() != null) ? ipValue + "/32" : ipValue + "/128";
626 Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
627 .setMacAddress(port.getMacAddress().getValue()).setPrimaryAdjacency(true)
628 .setSubnetId(ip.getSubnetId()).build();
630 // create extra route adjacency
631 if (rtr != null && rtr.getRoutes() != null) {
632 List<Routes> routeList = rtr.getRoutes();
633 List<Adjacency> erAdjList = getAdjacencyforExtraRoute(vpnId, routeList, ipValue);
634 if (erAdjList != null && !erAdjList.isEmpty()) {
635 adjList.addAll(erAdjList);
638 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
639 .getMacAddress().getValue(), isRouterInterface, wrtConfigTxn);
641 // create vpn-interface on this neutron port
642 Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
643 writeVpnInterfaceToDs(vpnId, infName, adjs, isRouterInterface, wrtConfigTxn);
644 if (routerId != null) {
645 addToNeutronRouterInterfacesMap(routerId, infName);
649 // TODO Clean up the exception handling
650 @SuppressWarnings("checkstyle:IllegalCatch")
651 protected void deleteVpnInterface(Uuid vpnId, Uuid routerId, Port port, WriteTransaction wrtConfigTxn) {
652 Boolean wrtConfigTxnPresent = true;
653 if (wrtConfigTxn == null) {
654 wrtConfigTxnPresent = false;
655 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
657 String infName = port.getUuid().getValue();
658 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
660 LOG.debug("Deleting vpn interface {}", infName);
661 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
663 List<FixedIps> ips = port.getFixedIps();
664 for (FixedIps ip : ips) {
665 String ipValue = String.valueOf(ip.getIpAddress().getValue());
666 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(),
667 ipValue, wrtConfigTxn);
669 } catch (Exception ex) {
670 LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
672 if (routerId != null) {
673 removeFromNeutronRouterInterfacesMap(routerId, infName);
675 if (!wrtConfigTxnPresent) {
676 wrtConfigTxn.submit();
680 // TODO Clean up the exception handling
681 @SuppressWarnings("checkstyle:IllegalCatch")
682 protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean isBeingAssociated,
683 boolean isSubnetIp) {
684 if (vpnId == null || port == null) {
687 boolean isLockAcquired = false;
688 String infName = port.getUuid().getValue();
689 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
692 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
693 isLockAcquired = NeutronvpnUtils.lock(infName);
694 Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
695 .CONFIGURATION, vpnIfIdentifier);
696 if (optionalVpnInterface.isPresent()) {
697 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get())
698 .setVpnInstanceName(vpnId.getValue());
699 LOG.debug("Updating vpn interface {}", infName);
700 if (!isBeingAssociated) {
701 Adjacencies adjs = vpnIfBuilder.getAugmentation(Adjacencies.class);
702 List<Adjacency> adjacencyList = (adjs != null) ? adjs.getAdjacency() : new ArrayList<>();
703 Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
704 while (adjacencyIter.hasNext()) {
705 Adjacency adjacency = adjacencyIter.next();
706 String mipToQuery = adjacency.getIpAddress().split("/")[0];
707 InstanceIdentifier<LearntVpnVipToPort> id =
708 NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(oldVpnId.getValue(), mipToQuery);
709 Optional<LearntVpnVipToPort> optionalVpnVipToPort =
710 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
711 if (optionalVpnVipToPort.isPresent()) {
712 LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} "
713 + "from VPN " + "{}", infName, vpnId, oldVpnId);
714 adjacencyIter.remove();
715 NeutronvpnUtils.removeLearntVpnVipToPort(dataBroker, oldVpnId.getValue(), mipToQuery);
716 LOG.trace("Entry for fixedIP {} for port {} on VPN removed from "
717 + "VpnPortFixedIPToPortData", mipToQuery, infName, vpnId.getValue());
720 Adjacencies adjacencies = new AdjacenciesBuilder().setAdjacency(adjacencyList).build();
721 vpnIfBuilder.addAugmentation(Adjacencies.class, adjacencies);
723 List<FixedIps> ips = port.getFixedIps();
724 for (FixedIps ip : ips) {
725 String ipValue = String.valueOf(ip.getIpAddress().getValue());
726 if (oldVpnId != null) {
727 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(),
728 ipValue, writeConfigTxn);
730 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
731 .getMacAddress().getValue(), isSubnetIp, writeConfigTxn);
733 writeConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
735 writeConfigTxn.submit();
737 LOG.error("VPN Interface {} not found", infName);
739 } catch (Exception ex) {
740 LOG.error("Updation of vpninterface {} failed due to {}", infName, ex);
742 if (isLockAcquired) {
743 NeutronvpnUtils.unlock(infName);
748 public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt,
749 List<String> ert, Uuid router, List<Uuid> networks) {
751 // Update VPN Instance node
752 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert, VpnInstance.Type.L3, 0 /*l3vni*/);
754 // Update local vpn-subnet DS
755 updateVpnMaps(vpn, name, router, tenant, networks);
757 if (router != null) {
758 Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(dataBroker, router, true);
759 if (existingVpn != null) {
760 // use case when a cluster is rebooted and router add DCN is received, triggering #createL3InternalVpn
762 // if before reboot, router was already associated to VPN, should not proceed associating router to
763 // internal VPN. Adding to RouterInterfacesMap is also not needed since it's a config DS and will be
764 // preserved upon reboot.
765 // For a non-reboot case #associateRouterToInternalVPN already takes care of adding to
766 // RouterInterfacesMap via #createVPNInterface call.
767 LOG.info("Associating router to Internal VPN skipped for VPN {} due to router {} already associated "
768 + "to external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
771 associateRouterToInternalVpn(vpn, router);
776 * Performs the creation of a Neutron L3VPN, associating the new VPN to the
777 * specified Neutron Networks and Routers.
779 * @param vpn Uuid of the VPN tp be created
780 * @param name Representative name of the new VPN
781 * @param tenant Uuid of the Tenant under which the VPN is going to be created
782 * @param rd Route-distinguisher for the VPN
783 * @param irt A list of Import Route Targets
784 * @param ert A list of Export Route Targets
785 * @param router UUID of the neutron router the VPN may be associated to
786 * @param networks UUID of the neutron network the VPN may be associated to
787 * @param type Type of the VPN Instance
788 * @param l3vni L3VNI for the VPN Instance using VxLAN as the underlay
789 * @throws Exception if association of L3VPN failed
791 public void createVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
792 Uuid router, List<Uuid> networks, VpnInstance.Type type, long l3vni) throws Exception {
794 // Update VPN Instance node
795 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert, type, l3vni);
797 // Please note that router and networks will be filled into VPNMaps
798 // by subsequent calls here to associateRouterToVpn and
799 // associateNetworksToVpn
800 updateVpnMaps(vpn, name, null, tenant, null);
802 if (router != null) {
803 associateRouterToVpn(vpn, router);
805 if (networks != null) {
806 List<String> failStrings = associateNetworksToVpn(vpn, networks);
807 if (failStrings != null && !failStrings.isEmpty()) {
808 LOG.error("VPN {} association to networks failed with error message {}. ",
809 vpn.getValue(), failStrings.get(0));
810 throw new Exception(failStrings.get(0));
816 * It handles the invocations to the createVPN RPC method.
819 // TODO Clean up the exception handling
820 @SuppressWarnings("checkstyle:IllegalCatch")
821 public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
823 CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
824 SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
825 List<RpcError> errorList = new ArrayList<>();
826 int failurecount = 0;
827 int warningcount = 0;
829 List<L3vpn> vpns = input.getL3vpn();
830 for (L3vpn vpn : vpns) {
831 RpcError error = null;
833 if (NeutronvpnUtils.doesVpnExist(dataBroker, vpn.getId())) {
834 msg = String.format("Creation of L3VPN failed for VPN %s due to VPN with the same ID already present",
835 vpn.getId().getValue());
837 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
838 errorList.add(error);
842 if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
843 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
844 vpn.getId().getValue());
846 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
847 errorList.add(error);
851 VpnInstance.Type vpnInstanceType = VpnInstance.Type.L3;
853 if (vpn.getL3vni() != null) {
854 l3vni = vpn.getL3vni();
857 if (vpn.getRouteDistinguisher().size() > 1) {
858 msg = String.format("Creation of VPN failed for VPN %s due to multiple RD input %s",
859 vpn.getId().getValue(), vpn.getRouteDistinguisher());
861 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
862 errorList.add(error);
866 List<String> existingRDs = NeutronvpnUtils.getExistingRDs(dataBroker);
867 if (existingRDs.contains(vpn.getRouteDistinguisher().get(0))) {
868 msg = String.format("Creation of L3VPN failed for VPN %s as another VPN with the same RD %s "
869 + "is already configured",
870 vpn.getId().getValue(), vpn.getRouteDistinguisher().get(0));
872 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
873 errorList.add(error);
877 if (vpn.getRouterId() != null) {
878 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
879 msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
880 vpn.getId().getValue(), vpn.getRouterId().getValue());
882 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
883 errorList.add(error);
887 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
889 msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
890 + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
893 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
894 errorList.add(error);
899 if (vpn.getNetworkIds() != null) {
900 for (Uuid nw : vpn.getNetworkIds()) {
901 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
902 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
903 if (network == null) {
904 msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
905 vpn.getId().getValue(), nw.getValue());
907 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
908 errorList.add(error);
910 } else if (vpnId != null) {
911 msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
912 + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
915 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
916 errorList.add(error);
925 createVpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
926 vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds(),
927 vpnInstanceType, l3vni);
928 } catch (Exception ex) {
929 msg = String.format("Creation of VPN failed for VPN %s", vpn.getId().getValue());
931 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
932 errorList.add(error);
936 // if at least one succeeds; result is success
937 // if none succeeds; result is failure
938 if (failurecount + warningcount == vpns.size()) {
939 result.set(RpcResultBuilder.<CreateL3VPNOutput>failed().withRpcErrors(errorList).build());
941 List<String> errorResponseList = new ArrayList<>();
942 if (!errorList.isEmpty()) {
943 for (RpcError rpcError : errorList) {
944 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
945 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
946 errorResponseList.add(errorResponse);
949 errorResponseList.add("Operation successful with no errors");
951 opBuilder.setResponse(errorResponseList);
952 result.set(RpcResultBuilder.<CreateL3VPNOutput>success().withResult(opBuilder.build()).build());
958 * It handles the invocations to the neutronvpn:getL3VPN RPC method.
961 // TODO Clean up the exception handling
962 @SuppressWarnings("checkstyle:IllegalCatch")
963 public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
965 GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
966 SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
967 Uuid inputVpnId = input.getId();
968 List<VpnInstance> vpns = new ArrayList<>();
971 if (inputVpnId == null) {
973 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
975 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
976 .CONFIGURATION, vpnsIdentifier);
977 if (optionalVpns.isPresent() && !optionalVpns.get().getVpnInstance().isEmpty()) {
978 for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
979 // eliminating implicitly created (router and VLAN provider external network specific) VPNs
980 // from getL3VPN output
981 if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
987 result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
991 String name = inputVpnId.getValue();
992 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
993 .child(VpnInstance.class, new VpnInstanceKey(name)).build();
994 // read VpnInstance Info
995 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
997 // eliminating implicitly created (router or VLAN provider external network specific) VPN from
999 if (optionalVpn.isPresent() && optionalVpn.get().getIpv4Family().getRouteDistinguisher() != null) {
1000 vpns.add(optionalVpn.get());
1002 String message = String.format("GetL3VPN failed because VPN %s is not present", name);
1004 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
1005 "invalid-value", message).build());
1008 List<L3vpnInstances> l3vpnList = new ArrayList<>();
1009 for (VpnInstance vpnInstance : vpns) {
1010 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
1011 // create VpnMaps id
1012 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
1014 List<String> rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
1015 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
1017 List<String> ertList = new ArrayList<>();
1018 List<String> irtList = new ArrayList<>();
1020 for (VpnTarget vpnTarget : vpnTargetList) {
1021 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
1022 ertList.add(vpnTarget.getVrfRTValue());
1024 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
1025 irtList.add(vpnTarget.getVrfRTValue());
1027 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
1028 ertList.add(vpnTarget.getVrfRTValue());
1029 irtList.add(vpnTarget.getVrfRTValue());
1033 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1034 if (vpnInstance.getL3vni() != null) {
1035 l3vpn.setL3vni(vpnInstance.getL3vni());
1037 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
1038 .class, new VpnMapKey(vpnId)).build();
1039 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1041 if (optionalVpnMap.isPresent()) {
1042 VpnMap vpnMap = optionalVpnMap.get();
1043 l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1044 .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1046 l3vpnList.add(l3vpn.build());
1049 opBuilder.setL3vpnInstances(l3vpnList);
1050 result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
1052 } catch (Exception ex) {
1053 String message = String.format("GetVPN failed due to %s", ex.getMessage());
1054 LOG.error(message, ex);
1055 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withError(ErrorType.APPLICATION, message).build());
1061 * It handles the invocations to the neutronvpn:deleteL3VPN RPC method.
1064 // TODO Clean up the exception handling
1065 @SuppressWarnings("checkstyle:IllegalCatch")
1066 public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1068 DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1069 SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1070 List<RpcError> errorList = new ArrayList<>();
1072 int failurecount = 0;
1073 int warningcount = 0;
1074 List<Uuid> vpns = input.getId();
1075 for (Uuid vpn : vpns) {
1079 InstanceIdentifier<VpnInstance> vpnIdentifier =
1080 InstanceIdentifier.builder(VpnInstances.class)
1081 .child(VpnInstance.class, new VpnInstanceKey(vpn.getValue())).build();
1082 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1083 .CONFIGURATION, vpnIdentifier);
1084 if (optionalVpn.isPresent()) {
1087 msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1089 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1090 errorList.add(error);
1093 } catch (Exception ex) {
1094 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1096 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1097 errorList.add(error);
1101 // if at least one succeeds; result is success
1102 // if none succeeds; result is failure
1103 if (failurecount + warningcount == vpns.size()) {
1104 result.set(RpcResultBuilder.<DeleteL3VPNOutput>failed().withRpcErrors(errorList).build());
1106 List<String> errorResponseList = new ArrayList<>();
1107 if (!errorList.isEmpty()) {
1108 for (RpcError rpcError : errorList) {
1109 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1110 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1111 errorResponseList.add(errorResponse);
1114 errorResponseList.add("Operation successful with no errors");
1116 opBuilder.setResponse(errorResponseList);
1117 result.set(RpcResultBuilder.<DeleteL3VPNOutput>success().withResult(opBuilder.build()).build());
1122 public void createVpnInstanceForSubnet(Uuid subnetId) {
1123 LOG.debug("Creating/Updating L3 internalVPN for subnetID {} ", subnetId);
1124 createL3InternalVpn(subnetId, subnetId.getValue(), null, null, null, null, null, null);
1127 public void removeVpnInstanceForSubnet(Uuid subnetId) {
1128 LOG.debug("Removing vpn-instance for subnetID {} ", subnetId);
1129 removeVpn(subnetId);
1132 protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
1133 LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1134 Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1135 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1136 if (vpnMap == null) {
1137 LOG.error("No vpnMap for vpnId {}, cannot add subnet {} to VPN", vpnId.getValue(), subnet.getValue());
1141 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1142 // Check if there are ports on this subnet and add corresponding
1144 List<Uuid> portList = sn.getPortList();
1145 if (portList != null) {
1146 for (final Uuid portId : sn.getPortList()) {
1147 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1148 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1149 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1150 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1151 List<ListenableFuture<Void>> futures = new ArrayList<>();
1152 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1154 futures.add(wrtConfigTxn.submit());
1161 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1162 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1163 // Read the subnet first to see if its already associated to a VPN
1164 Uuid oldVpnId = null;
1165 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class)
1166 .child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1167 Subnetmap sn = null;
1168 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1169 if (optSn.isPresent()) {
1171 oldVpnId = sn.getVpnId();
1172 List<String> ips = sn.getRouterInterfaceFixedIps();
1173 for (String ipValue : ips) {
1174 // Update the association of router-interface to external vpn
1176 NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, oldVpnId.getValue(), ipValue);
1177 if (portName != null) {
1178 updateVpnInterface(vpnId, oldVpnId,
1179 NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(portName)),
1180 isBeingAssociated, true);
1184 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1185 // Check for ports on this subnet and update association of
1186 // corresponding vpn-interfaces to external vpn
1187 List<Uuid> portList = sn.getPortList();
1188 if (portList != null) {
1189 for (Uuid port : sn.getPortList()) {
1190 LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}",
1191 port.getValue(), isBeingAssociated);
1192 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port),
1193 isBeingAssociated, false);
1198 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1199 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1200 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1203 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1204 synchronized (routerId.getValue().intern()) {
1205 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1206 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1207 .CONFIGURATION, routerInterfacesId);
1208 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName))
1209 .setInterfaceId(interfaceName).build();
1210 if (optRouterInterfaces.isPresent()) {
1211 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1212 .class, new InterfacesKey(interfaceName)), routerInterface);
1214 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1215 List<Interfaces> interfaces = new ArrayList<>();
1216 interfaces.add(routerInterface);
1217 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1218 .class, new InterfacesKey(interfaceName)), routerInterface);
1223 protected void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1224 synchronized (routerId.getValue().intern()) {
1225 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1226 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1227 .CONFIGURATION, routerInterfacesId);
1228 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName))
1229 .setInterfaceId(interfaceName).build();
1230 if (optRouterInterfaces.isPresent()) {
1231 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1232 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1233 if (interfaces != null && interfaces.remove(routerInterface)) {
1234 if (interfaces.isEmpty()) {
1235 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1237 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1238 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1246 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1247 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1248 * route will be ignored.
1250 * @param vpnName the VPN identifier
1251 * @param interVpnLinkRoutes The list of static routes
1252 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1254 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1255 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1256 for (Routes route : interVpnLinkRoutes) {
1257 String nexthop = String.valueOf(route.getNexthop().getValue());
1258 String destination = String.valueOf(route.getDestination().getValue());
1259 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1260 if (isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink)) {
1261 AddStaticRouteInput rpcInput =
1262 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1263 .setVpnInstanceName(vpnName.getValue())
1265 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1266 RpcResult<AddStaticRouteOutput> rpcResult;
1268 rpcResult = labelOuputFtr.get();
1269 if (rpcResult.isSuccessful()) {
1270 LOG.debug("Label generated for destination {} is: {}",
1271 destination, rpcResult.getResult().getLabel());
1273 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1274 destination, nexthop, rpcResult.getErrors());
1276 } catch (InterruptedException | ExecutionException e) {
1277 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1280 // Any other case is a fault.
1281 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1282 String.valueOf(route.getDestination().getValue()), nexthop);
1289 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1290 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1292 * @param vpnName the VPN identifier
1293 * @param interVpnLinkRoutes The list of static routes
1294 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1296 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1297 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1298 for (Routes route : interVpnLinkRoutes) {
1299 String nexthop = String.valueOf(route.getNexthop().getValue());
1300 String destination = String.valueOf(route.getDestination().getValue());
1301 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1302 if (isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink)) {
1303 RemoveStaticRouteInput rpcInput =
1304 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1305 .setVpnInstanceName(vpnName.getValue())
1307 vpnRpcService.removeStaticRoute(rpcInput);
1309 // Any other case is a fault.
1310 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1311 String.valueOf(route.getDestination().getValue()), nexthop);
1318 * Returns true if the specified nexthop is the other endpoint in an
1319 * InterVpnLink, regarding one of the VPN's point of view.
1321 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1323 interVpnLink != null
1324 && ((interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1325 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1326 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1327 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)));
1330 protected List<Adjacency> getAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList, String fixedIp) {
1331 List<Adjacency> adjList = new ArrayList<>();
1332 Map<String, List<String>> adjMap = new HashMap<>();
1333 for (Routes route : routeList) {
1334 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1335 LOG.error("Incorrect input received for extra route. {}", route);
1337 String nextHop = String.valueOf(route.getNexthop().getValue());
1338 String destination = String.valueOf(route.getDestination().getValue());
1339 if (!nextHop.equals(fixedIp)) {
1340 LOG.trace("FixedIP {} is not extra route nexthop for destination {}", fixedIp, destination);
1343 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} ", destination,
1344 vpnId.getValue(), nextHop);
1345 List<String> hops = adjMap.computeIfAbsent(destination, k -> new ArrayList<>());
1346 if (!hops.contains(nextHop)) {
1352 for (String destination : adjMap.keySet()) {
1353 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination)
1354 .setNextHopIpList(adjMap.get(destination)).setKey(new AdjacencyKey(destination)).build();
1360 // TODO Clean up the exception handling
1361 @SuppressWarnings("checkstyle:IllegalCatch")
1362 protected void updateVpnInterfaceWithExtraRouteAdjacency(Uuid vpnId, List<Routes> routeList) {
1363 for (Routes route : routeList) {
1364 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1365 LOG.error("Incorrect input received for extra route. {}", route);
1367 String nextHop = String.valueOf(route.getNexthop().getValue());
1368 String destination = String.valueOf(route.getDestination().getValue());
1369 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1371 if (infName != null) {
1372 LOG.trace("Updating extra route for destination {} onto vpn {} with nexthop {} and infName {}",
1373 destination, vpnId.getValue(), nextHop, infName);
1374 boolean isLockAcquired = false;
1376 InstanceIdentifier<VpnInterface> identifier = InstanceIdentifier.builder(VpnInterfaces.class)
1377 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1378 InstanceIdentifier<Adjacency> path = identifier.augmentation(Adjacencies.class)
1379 .child(Adjacency.class, new AdjacencyKey(destination));
1380 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination)
1381 .setNextHopIpList(Collections.singletonList(nextHop)).setKey(new AdjacencyKey(destination))
1383 isLockAcquired = NeutronvpnUtils.lock(infName);
1384 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, erAdj);
1385 } catch (Exception e) {
1386 LOG.error("exception in adding extra route with destination: {}, next hop: {}",
1387 destination, nextHop, e);
1389 if (isLockAcquired) {
1390 NeutronvpnUtils.unlock(infName);
1394 LOG.debug("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} "
1395 + "with nexthop {}", destination, vpnId.getValue(), nextHop);
1401 // TODO Clean up the exception handling
1402 @SuppressWarnings("checkstyle:IllegalCatch")
1403 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1404 for (Routes route : routeList) {
1405 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1406 boolean isLockAcquired = false;
1407 String nextHop = String.valueOf(route.getNexthop().getValue());
1408 String destination = String.valueOf(route.getDestination().getValue());
1409 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1411 if (infName == null) {
1412 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} "
1413 + "with nexthop {}", destination, vpnId.getValue(), nextHop);
1414 // Proceed to remove the next extra-route
1417 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1418 destination, vpnId.getValue(), nextHop, infName);
1420 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1421 InstanceIdentifier.builder(VpnInterfaces.class)
1422 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1423 .augmentation(Adjacencies.class)
1424 .child(Adjacency.class, new AdjacencyKey(destination))
1427 // Looking for existing prefix in MDSAL database
1428 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1429 adjacencyIdentifier);
1430 boolean updateNextHops = false;
1431 List<String> nextHopList = new ArrayList<>();
1432 if (adjacency.isPresent()) {
1433 List<String> nhListRead = adjacency.get().getNextHopIpList();
1434 if (nhListRead.size() > 1) { // ECMP case
1435 for (String nextHopRead : nhListRead) {
1436 if (nextHopRead.equals(nextHop)) {
1437 updateNextHops = true;
1439 nextHopList.add(nextHopRead);
1446 isLockAcquired = NeutronvpnUtils.lock(infName);
1447 if (updateNextHops) {
1448 // An update must be done, not including the current next hop
1449 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1450 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1451 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1452 .setNextHopIpList(nextHopList)
1453 .setKey(new AdjacencyKey(destination))
1455 Adjacencies erAdjs =
1456 new AdjacenciesBuilder().setAdjacency(Collections.singletonList(newAdj)).build();
1457 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1458 .addAugmentation(Adjacencies.class, erAdjs).build();
1459 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1461 // Remove the whole route
1462 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1463 LOG.trace("extra route {} deleted successfully", route);
1465 } catch (Exception e) {
1466 LOG.error("exception in deleting extra route: {}" + e);
1468 if (isLockAcquired) {
1469 NeutronvpnUtils.unlock(infName);
1473 LOG.error("Incorrect input received for extra route. {}", route);
1478 protected void removeVpn(Uuid id) {
1480 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1481 Uuid router = (vpnMap != null) ? vpnMap.getRouterId() : null;
1482 // dissociate router
1483 if (router != null) {
1484 dissociateRouterFromVpn(id, router);
1486 // dissociate networks
1487 if (!id.equals(router)) {
1488 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1490 // remove entire vpnMaps node
1491 deleteVpnMapsNode(id);
1493 // remove vpn-instance
1494 deleteVpnInstance(id);
1497 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1498 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1499 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1500 if (vpnMap == null) {
1501 LOG.error("No vpnMap for vpnId {}, cannot remove subnet {} from VPN",
1502 vpnId.getValue(), subnet.getValue());
1506 final Uuid routerId = vpnMap.getRouterId();
1507 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1509 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1510 List<Uuid> portList = sn.getPortList();
1511 if (portList != null) {
1512 for (final Uuid portId : sn.getPortList()) {
1513 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1514 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1515 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1516 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1517 List<ListenableFuture<Void>> futures = new ArrayList<>();
1518 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1520 deleteVpnInterface(vpnId, routerId, port, wrtConfigTxn);
1522 LOG.error("Cannot proceed with deleteVpnInterface for port {} in subnet {} since port is "
1523 + "absent in Neutron config DS", portId.getValue(), subnet.getValue());
1525 futures.add(wrtConfigTxn.submit());
1530 // update subnet-vpn association
1531 removeFromSubnetNode(subnet, null, null, vpnId, null);
1533 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1537 // TODO Clean up the exception handling
1538 @SuppressWarnings("checkstyle:IllegalCatch")
1539 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1540 updateVpnMaps(vpnId, null, routerId, null, null);
1541 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1542 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1543 if (routerSubnets != null) {
1544 for (Uuid subnetId : routerSubnets) {
1545 updateVpnForSubnet(vpnId, subnetId, true);
1549 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1550 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1552 } catch (Exception e) {
1553 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1554 .getValue(), vpnId.getValue(), e);
1558 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1559 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1560 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1561 for (Uuid subnet : routerSubnets) {
1562 addSubnetToVpn(vpnId, subnet);
1566 // TODO Clean up the exception handling
1567 @SuppressWarnings("checkstyle:IllegalCatch")
1568 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1570 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1571 if (routerSubnets != null) {
1572 for (Uuid subnetId : routerSubnets) {
1573 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1574 updateVpnForSubnet(routerId, subnetId, false);
1577 clearFromVpnMaps(vpnId, routerId, null);
1579 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1580 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1582 } catch (Exception e) {
1583 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1584 .getValue(), vpnId.getValue(), e);
1588 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1589 List<String> failedNwList = new ArrayList<>();
1590 List<Uuid> passedNwList = new ArrayList<>();
1591 if (!networks.isEmpty()) {
1592 // process corresponding subnets for VPN
1593 for (Uuid nw : networks) {
1594 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1595 NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
1596 if (providerExtension.getSegments() != null && providerExtension.getSegments().size() > 1) {
1597 LOG.error("MultiSegmented networks not supported in VPN. Failed to associate network {} on vpn {}",
1598 nw.getValue(), vpn.getValue());
1599 failedNwList.add(String.format("Failed to associate network %s on vpn %s as it is multisegmented.",
1600 nw.getValue(), vpn.getValue()));
1603 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1604 if (network == null) {
1605 failedNwList.add(String.format("network %s not found", nw.getValue()));
1606 } else if (vpnId != null) {
1607 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1610 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1611 LOG.debug("Adding network subnets...{}", networkSubnets);
1612 if (networkSubnets != null) {
1613 for (Uuid subnet : networkSubnets) {
1614 // check if subnet added as router interface to some router
1615 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1616 if (subnetVpnId == null) {
1617 addSubnetToVpn(vpn, subnet);
1618 passedNwList.add(nw);
1620 failedNwList.add(String.format("subnet %s already added as router interface bound to "
1621 + "internal/external VPN %s", subnet.getValue(), subnetVpnId.getValue()));
1625 if (NeutronvpnUtils.getIsExternal(network)) {
1626 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1630 updateVpnMaps(vpn, null, null, null, passedNwList);
1632 return failedNwList;
1635 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1636 List<String> failedNwList = new ArrayList<>();
1637 List<Uuid> passedNwList = new ArrayList<>();
1638 if (networks != null && !networks.isEmpty()) {
1639 // process corresponding subnets for VPN
1640 for (Uuid nw : networks) {
1641 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1642 if (network == null) {
1643 failedNwList.add(String.format("network %s not found", nw.getValue()));
1645 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1646 if (vpn.equals(vpnId)) {
1647 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1648 LOG.debug("Removing network subnets...");
1649 if (networkSubnets != null) {
1650 for (Uuid subnet : networkSubnets) {
1651 removeSubnetFromVpn(vpn, subnet);
1652 passedNwList.add(nw);
1656 if (vpnId == null) {
1657 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1660 failedNwList.add(String.format("input network %s associated to a another vpn %s instead "
1661 + "of the one given as input", nw.getValue(), vpnId.getValue()));
1664 if (NeutronvpnUtils.getIsExternal(network)) {
1665 nvpnNatManager.removeExternalNetworkFromVpn(network);
1669 clearFromVpnMaps(vpn, null, passedNwList);
1671 return failedNwList;
1675 * It handles the invocations to the neutronvpn:associateNetworks RPC method.
1678 // TODO Clean up the exception handling
1679 @SuppressWarnings("checkstyle:IllegalCatch")
1680 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1682 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1683 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1684 LOG.debug("associateNetworks {}", input);
1685 StringBuilder returnMsg = new StringBuilder();
1686 Uuid vpnId = input.getVpnId();
1689 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1690 List<Uuid> netIds = input.getNetworkId();
1691 if (netIds != null && !netIds.isEmpty()) {
1692 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1693 if (!failed.isEmpty()) {
1694 returnMsg.append(failed);
1698 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1700 if (returnMsg.length() != 0) {
1701 String message = String.format("associate Networks to vpn %s failed due to %s",
1702 vpnId.getValue(), returnMsg);
1704 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1706 opBuilder.setResponse(errorResponse);
1707 result.set(RpcResultBuilder.<AssociateNetworksOutput>success().withResult(opBuilder.build()).build());
1709 result.set(RpcResultBuilder.<AssociateNetworksOutput>success().build());
1711 } catch (Exception ex) {
1712 String message = String.format("associate Networks to vpn %s failed due to %s",
1713 input.getVpnId().getValue(), ex.getMessage());
1714 LOG.error(message, ex);
1715 result.set(RpcResultBuilder.<AssociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
1718 LOG.debug("associateNetworks returns..");
1723 * It handles the invocations to the neutronvpn:associateRouter RPC method.
1726 // TODO Clean up the exception handling
1727 @SuppressWarnings("checkstyle:IllegalCatch")
1728 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1730 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1731 LOG.debug("associateRouter {}", input);
1732 StringBuilder returnMsg = new StringBuilder();
1733 Uuid vpnId = input.getVpnId();
1734 Uuid routerId = input.getRouterId();
1736 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1737 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1738 if (vpnMap != null) {
1740 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1741 if (vpnMap.getRouterId() != null) {
1742 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1743 .append(vpnMap.getRouterId().getValue());
1744 } else if (extVpnId != null) {
1745 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to "
1746 + "another VPN ").append(extVpnId.getValue());
1748 associateRouterToVpn(vpnId, routerId);
1751 returnMsg.append("router not found : ").append(routerId.getValue());
1754 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1756 if (returnMsg.length() != 0) {
1757 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1760 result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1763 result.set(RpcResultBuilder.<Void>success().build());
1765 } catch (Exception ex) {
1766 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1767 vpnId.getValue(), ex.getMessage());
1768 LOG.error(message, ex);
1769 result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
1771 LOG.debug("associateRouter returns..");
1775 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method.
1778 // TODO Clean up the exception handling
1779 @SuppressWarnings("checkstyle:IllegalCatch")
1780 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(
1781 GetFixedIPsForNeutronPortInput input) {
1782 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1783 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1784 Uuid portId = input.getPortId();
1785 StringBuilder returnMsg = new StringBuilder();
1787 List<String> fixedIPList = new ArrayList<>();
1788 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1790 List<FixedIps> fixedIPs = port.getFixedIps();
1791 for (FixedIps ip : fixedIPs) {
1792 fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
1795 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1797 if (returnMsg.length() != 0) {
1798 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1800 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed()
1801 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1803 opBuilder.setFixedIPs(fixedIPList);
1804 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().withResult(opBuilder.build())
1806 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().build());
1808 } catch (Exception ex) {
1809 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1810 portId.getValue(), ex.getMessage());
1811 LOG.error(message, ex);
1812 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed()
1813 .withError(ErrorType.APPLICATION, message).build());
1819 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method.
1822 // TODO Clean up the exception handling
1823 @SuppressWarnings("checkstyle:IllegalCatch")
1824 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1826 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1827 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1829 LOG.debug("dissociateNetworks {}", input);
1830 StringBuilder returnMsg = new StringBuilder();
1831 Uuid vpnId = input.getVpnId();
1834 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1835 List<Uuid> netIds = input.getNetworkId();
1836 if (netIds != null && !netIds.isEmpty()) {
1837 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1838 if (!failed.isEmpty()) {
1839 returnMsg.append(failed);
1843 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1845 if (returnMsg.length() != 0) {
1846 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1849 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1851 opBuilder.setResponse(errorResponse);
1852 result.set(RpcResultBuilder.<DissociateNetworksOutput>success().withResult(opBuilder.build()).build());
1854 result.set(RpcResultBuilder.<DissociateNetworksOutput>success().build());
1856 } catch (Exception ex) {
1857 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1858 input.getVpnId().getValue(), ex.getMessage());
1859 LOG.error(message, ex);
1860 result.set(RpcResultBuilder.<DissociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
1863 LOG.debug("dissociateNetworks returns..");
1868 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1871 // TODO Clean up the exception handling
1872 @SuppressWarnings("checkstyle:IllegalCatch")
1873 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1875 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1877 LOG.debug("dissociateRouter {}", input);
1878 StringBuilder returnMsg = new StringBuilder();
1879 Uuid vpnId = input.getVpnId();
1880 Uuid routerId = input.getRouterId();
1882 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1883 if (routerId != null) {
1884 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1886 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1887 if (vpnId.equals(routerVpnId)) {
1888 dissociateRouterFromVpn(vpnId, routerId);
1890 if (routerVpnId == null) {
1891 returnMsg.append("input router ").append(routerId.getValue())
1892 .append(" not associated to any vpn yet");
1894 returnMsg.append("input router ").append(routerId.getValue())
1895 .append(" associated to vpn ")
1896 .append(routerVpnId.getValue()).append("instead of the vpn given as input");
1900 returnMsg.append("router not found : ").append(routerId.getValue());
1904 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1906 if (returnMsg.length() != 0) {
1907 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1908 vpnId.getValue(), returnMsg);
1910 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1912 result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1915 result.set(RpcResultBuilder.<Void>success().build());
1917 } catch (Exception ex) {
1918 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1919 vpnId.getValue(), ex.getMessage());
1920 LOG.error(message, ex);
1921 result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
1923 LOG.debug("dissociateRouter returns..");
1928 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1929 // check if the router is associated to some VPN
1930 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1931 if (vpnId != null) {
1932 // remove existing external vpn interfaces
1933 for (Uuid subnetId : routerSubnetIds) {
1934 removeSubnetFromVpn(vpnId, subnetId);
1936 clearFromVpnMaps(vpnId, routerId, null);
1938 // remove existing internal vpn interfaces
1939 for (Uuid subnetId : routerSubnetIds) {
1940 removeSubnetFromVpn(routerId, subnetId);
1943 // delete entire vpnMaps node for internal VPN
1944 deleteVpnMapsNode(routerId);
1946 // delete vpn-instance for internal VPN
1947 deleteVpnInstance(routerId);
1950 protected Subnet getNeutronSubnet(Uuid subnetId) {
1951 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1954 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1955 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1957 return sn.getGatewayIp();
1963 protected Network getNeutronNetwork(Uuid networkId) {
1964 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1967 protected Port getNeutronPort(String name) {
1968 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1971 protected Port getNeutronPort(Uuid portId) {
1972 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1975 protected Uuid getNetworkForSubnet(Uuid subnetId) {
1976 return NeutronvpnUtils.getNetworkForSubnet(dataBroker, subnetId);
1979 protected List<Uuid> getNetworksForVpn(Uuid vpnId) {
1980 return NeutronvpnUtils.getNetworksforVpn(dataBroker, vpnId);
1984 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command.
1986 * @return a List of String to be printed on screen
1988 // TODO Clean up the exception handling and the console output
1989 @SuppressWarnings({"checkstyle:IllegalCatch", "checkstyle:RegexpSinglelineJava"})
1990 public List<String> showNeutronPortsCLI() {
1991 List<String> result = new ArrayList<>();
1992 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length",
1994 result.add("-------------------------------------------------------------------------------------------");
1995 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
1997 Optional<Ports> ports =
1998 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
1999 if (ports.isPresent() && ports.get().getPort() != null) {
2000 for (Port port : ports.get().getPort()) {
2001 List<FixedIps> fixedIPs = port.getFixedIps();
2003 if (fixedIPs != null && !fixedIPs.isEmpty()) {
2004 List<String> ipList = new ArrayList<>();
2005 for (FixedIps fixedIp : fixedIPs) {
2006 IpAddress ipAddress = fixedIp.getIpAddress();
2007 if (ipAddress.getIpv4Address() != null) {
2008 ipList.add(ipAddress.getIpv4Address().getValue());
2010 ipList.add((ipAddress.getIpv6Address().getValue()));
2013 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2014 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
2015 ipList.toString()));
2017 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2018 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
2020 } catch (Exception e) {
2021 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
2023 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
2024 .getValue() + ": " + e.getMessage());
2028 } catch (Exception e) {
2029 LOG.error("Failed to retrieve neutronPorts info : ", e);
2030 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2036 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command.
2038 * @param vpnuuid Uuid of the VPN whose config must be shown
2039 * @return formatted output list
2041 @SuppressWarnings("checkstyle:RegexpSinglelineJava")
2042 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2043 List<String> result = new ArrayList<>();
2044 if (vpnuuid == null) {
2045 System.out.println("");
2046 System.out.println("Displaying VPN config for all VPNs");
2047 System.out.println("To display VPN config for a particular VPN, use the following syntax");
2048 System.out.println(getshowVpnConfigCLIHelp());
2051 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2052 if (rpcResult.isSuccessful()) {
2054 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2056 result.add(String.format(" %-80s ", "Import-RTs"));
2058 result.add(String.format(" %-80s ", "Export-RTs"));
2060 result.add(String.format(" %-76s ", "Subnet IDs"));
2062 result.add("------------------------------------------------------------------------------------");
2064 List<L3vpnInstances> vpnList = rpcResult.getResult().getL3vpnInstances();
2065 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
2066 .rev150602.VpnInstance vpn : vpnList) {
2067 String tenantId = vpn.getTenantId() != null ? vpn.getTenantId().getValue()
2069 result.add(String.format(" %-37s %-37s %-7s ", vpn.getId().getValue(), tenantId,
2070 vpn.getRouteDistinguisher()));
2072 result.add(String.format(" %-80s ", vpn.getImportRT()));
2074 result.add(String.format(" %-80s ", vpn.getExportRT()));
2077 Uuid vpnid = vpn.getId();
2078 List<Uuid> subnetList = NeutronvpnUtils.getSubnetsforVpn(dataBroker, vpnid);
2079 if (!subnetList.isEmpty()) {
2080 for (Uuid subnetuuid : subnetList) {
2081 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2084 result.add(String.format(" %-76s ", "\" \""));
2087 result.add("----------------------------------------");
2091 String errortag = rpcResult.getErrors().iterator().next().getTag();
2092 if (Objects.equals(errortag, "")) {
2093 System.out.println("");
2094 System.out.println("No VPN has been configured yet");
2095 } else if (Objects.equals(errortag, "invalid-value")) {
2096 System.out.println("");
2097 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2099 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2100 System.out.println(getshowVpnConfigCLIHelp());
2103 } catch (InterruptedException | ExecutionException e) {
2104 LOG.error("error getting VPN info : ", e);
2105 System.out.println("error getting VPN info : " + e.getMessage());
2110 protected void createExternalVpnInterfaces(Uuid extNetId) {
2111 if (extNetId == null) {
2112 LOG.trace("external network is null");
2116 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2117 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2118 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2122 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2123 for (String elanInterface : extElanInterfaces) {
2124 createExternalVpnInterface(extNetId, elanInterface, wrtConfigTxn);
2126 wrtConfigTxn.submit();
2129 // TODO Clean up the exception handling
2130 @SuppressWarnings("checkstyle:IllegalCatch")
2131 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2132 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2133 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2134 LOG.trace("No external ports attached for external network {}", extNetId);
2139 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2140 for (String elanInterface : extElanInterfaces) {
2141 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2142 .buildVpnInterfaceIdentifier(elanInterface);
2143 LOG.info("Removing vpn interface {}", elanInterface);
2144 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2146 wrtConfigTxn.submit();
2148 } catch (Exception ex) {
2149 LOG.error("Removal of vpninterfaces {} failed due to {}", extElanInterfaces, ex);
2153 private void createExternalVpnInterface(Uuid vpnId, String infName, WriteTransaction wrtConfigTxn) {
2154 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, wrtConfigTxn);
2157 // TODO Clean up the exception handling
2158 @SuppressWarnings("checkstyle:IllegalCatch")
2159 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2160 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2161 if (vpnId == null || infName == null) {
2162 LOG.debug("vpn id or interface is null");
2166 Boolean wrtConfigTxnPresent = true;
2167 if (wrtConfigTxn == null) {
2168 wrtConfigTxnPresent = false;
2169 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2172 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2173 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2175 .setVpnInstanceName(vpnId.getValue())
2176 .setIsRouterInterface(isRouterInterface);
2177 if (adjacencies != null) {
2178 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2180 VpnInterface vpnIf = vpnb.build();
2182 LOG.info("Creating vpn interface {}", vpnIf);
2183 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2184 } catch (Exception ex) {
2185 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2188 if (!wrtConfigTxnPresent) {
2189 wrtConfigTxn.submit();
2193 private String getshowVpnConfigCLIHelp() {
2194 StringBuilder help = new StringBuilder("Usage:");
2195 help.append("display vpn-config [-vid/--vpnid <id>]");
2196 return help.toString();
2199 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2200 InterruptedException {
2201 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2202 .setVpnId(vpnId).build();
2203 LOG.info("publishing notification upon association of router to VPN");
2204 notificationPublishService.putNotification(routerAssociatedToVpn);
2207 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2208 InterruptedException {
2209 RouterDisassociatedFromVpn routerDisassociatedFromVpn =
2210 new RouterDisassociatedFromVpnBuilder().setRouterId(routerId).setVpnId(vpnId).build();
2211 LOG.info("publishing notification upon disassociation of router from VPN");
2212 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2215 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2216 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);