2 * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.neutronvpn;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.EventListener;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Future;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
27 import org.opendaylight.genius.mdsalutil.MDSALUtil;
28 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
29 import org.opendaylight.netvirt.elanmanager.api.IElanService;
30 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
31 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
32 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
36 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
37 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
38 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
39 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
40 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
41 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
42 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
43 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
44 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.config.rev160806.NeutronvpnConfig;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutputBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateRouterInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.L3vpnInstance;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpn;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpnBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpn;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpnBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
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.rev150712.Neutron;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
114 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
115 import org.opendaylight.yangtools.yang.common.RpcError;
116 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
117 import org.opendaylight.yangtools.yang.common.RpcResult;
118 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
119 import org.slf4j.Logger;
120 import org.slf4j.LoggerFactory;
122 import com.google.common.base.Optional;
123 import com.google.common.util.concurrent.ListenableFuture;
124 import com.google.common.util.concurrent.SettableFuture;
126 public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, EventListener {
127 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnManager.class);
128 private final DataBroker dataBroker;
129 private final NeutronvpnNatManager nvpnNatManager;
130 private final NotificationPublishService notificationPublishService;
131 private final VpnRpcService vpnRpcService;
132 private final NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
133 private final NeutronvpnConfig neutronvpnConfig;
134 private final IMdsalApiManager mdsalUtil;
135 private final IElanService elanService;
136 Boolean isExternalVpn;
139 * @param dataBroker DataBroker reference
140 * @param mdsalManager MDSAL Util API access
141 * @param notiPublishService notificationPublishService
142 * @param vpnNatMgr VPN NAT manager service
143 * @param vpnRpcSrv VPN RPC service
144 * @param elanService ELAN service
145 * @param neutronFloatingToFixedIpMappingChangeListener FIP to FixedIP listener
146 * @param neutronvpnConfig Neutronvpn configuration service
148 public NeutronvpnManager(
149 final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
150 final NotificationPublishService notiPublishService, final NeutronvpnNatManager vpnNatMgr,
151 final VpnRpcService vpnRpcSrv, final IElanService elanService,
152 final NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener,
153 final NeutronvpnConfig neutronvpnConfig) {
154 this.dataBroker = dataBroker;
155 mdsalUtil = mdsalManager;
156 nvpnNatManager = vpnNatMgr;
157 notificationPublishService = notiPublishService;
158 vpnRpcService = vpnRpcSrv;
159 this.elanService = elanService;
160 floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
161 LOG.info("neutronvpnConfig: {}", neutronvpnConfig);
162 this.neutronvpnConfig = neutronvpnConfig;
166 public void close() throws Exception {
167 LOG.info("{} close", getClass().getSimpleName());
170 public NeutronvpnConfig getNeutronvpnConfig() {
171 return neutronvpnConfig;
174 protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
175 Uuid routerInterfaceName, String fixedIp,
176 String routerIntfMacAddress) {
177 Subnetmap subnetmap = null;
178 SubnetmapBuilder builder = null;
179 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
180 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
182 synchronized (subnetId.getValue().intern()) {
183 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
184 if (sn.isPresent()) {
185 builder = new SubnetmapBuilder(sn.get());
186 LOG.debug("WithRouterFixedIPs: Updating existing subnetmap node for subnet ID {}", subnetId.getValue());
188 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
189 LOG.debug("WithRouterFixedIPs: creating new subnetmap node for subnet ID {}", subnetId.getValue());
192 builder.setRouterId(routerId);
193 builder.setRouterInterfaceName(routerInterfaceName);
194 builder.setRouterIntfMacAddress(routerIntfMacAddress);
196 if (fixedIp != null) {
197 List<String> fixedIps = builder.getRouterInterfaceFixedIps();
198 if (fixedIps == null) {
199 fixedIps = new ArrayList<>();
201 fixedIps.add(fixedIp);
202 builder.setRouterInterfaceFixedIps(fixedIps);
204 builder.setRouterInterfaceFixedIps(null);
206 subnetmap = builder.build();
207 LOG.debug("WithRouterFixedIPs Creating/Updating subnetMap node for Router FixedIps: {} ", subnetId.getValue());
208 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
210 } catch (Exception e) {
211 LOG.error("WithRouterFixedIPs: Updation of subnetMap for Router FixedIps failed for node: {}", subnetId.getValue());
215 protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
217 Subnetmap subnetmap = null;
218 SubnetmapBuilder builder = null;
219 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
220 .child(Subnetmap.class, new SubnetmapKey(subnetId))
223 synchronized (subnetId.getValue().intern()) {
224 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
225 if (sn.isPresent()) {
226 builder = new SubnetmapBuilder(sn.get());
227 LOG.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
229 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
230 LOG.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
233 if (subnetIp != null) {
234 builder.setSubnetIp(subnetIp);
236 if (routerId != null) {
237 builder.setRouterId(routerId);
239 if (networkId != null) {
240 builder.setNetworkId(networkId);
243 builder.setVpnId(vpnId);
245 if (tenantId != null) {
246 builder.setTenantId(tenantId);
249 subnetmap = builder.build();
250 LOG.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
251 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
253 } catch (Exception e) {
254 LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
259 protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
260 Subnetmap subnetmap = null;
261 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
262 .child(Subnetmap.class, new SubnetmapKey(subnetId))
265 synchronized (subnetId.getValue().intern()) {
266 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
267 if (sn.isPresent()) {
268 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
269 if (routerId != null) {
270 builder.setRouterId(null);
272 if (networkId != null) {
273 builder.setNetworkId(null);
276 builder.setVpnId(null);
278 if (portId != null && builder.getPortList() != null) {
279 List<Uuid> portList = builder.getPortList();
280 portList.remove(portId);
281 builder.setPortList(portList);
284 subnetmap = builder.build();
285 LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
286 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
288 LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
291 } catch (Exception e) {
292 LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
297 protected Subnetmap updateSubnetmapNodeWithPorts(Uuid subnetId, Uuid portId, Uuid directPortId) {
298 Subnetmap subnetmap = null;
299 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
300 new SubnetmapKey(subnetId)).build();
302 synchronized (subnetId.getValue().intern()) {
303 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
304 if (sn.isPresent()) {
305 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
306 if (null != portId) {
307 List<Uuid> portList = builder.getPortList();
308 if (null == portList) {
309 portList = new ArrayList<Uuid>();
311 portList.add(portId);
312 builder.setPortList(portList);
313 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
316 if (null != directPortId) {
317 List<Uuid> directPortList = builder.getDirectPortList();
318 if (null == directPortList) {
319 directPortList = new ArrayList<Uuid>();
321 directPortList.add(directPortId);
322 builder.setDirectPortList(directPortList);
323 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
324 directPortId.getValue());
326 subnetmap = builder.build();
327 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
329 LOG.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
332 } catch (Exception e) {
333 LOG.error("Updating port list of a given subnetMap failed for node: {} with exception{}",
334 subnetId.getValue(), e);
339 protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
340 Subnetmap subnetmap = null;
341 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
342 new SubnetmapKey(subnetId)).build();
344 synchronized (subnetId.getValue().intern()) {
345 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
346 if (sn.isPresent()) {
347 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
348 if (null != portId && null != builder.getPortList()) {
349 List<Uuid> portList = builder.getPortList();
350 portList.remove(portId);
351 builder.setPortList(portList);
352 LOG.debug("Removing port {} from existing subnetmap node: {} ", portId.getValue(),
353 subnetId.getValue());
355 if (null != directPortId && null != builder.getDirectPortList()) {
356 List<Uuid> directPortList = builder.getDirectPortList();
357 directPortList.remove(directPortId);
358 builder.setDirectPortList(directPortList);
359 LOG.debug("Removing direct port {} from existing subnetmap node: {} ", directPortId
360 .getValue(), subnetId.getValue());
362 subnetmap = builder.build();
363 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
365 LOG.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
368 } catch (Exception e) {
369 LOG.error("Removing a port from port list of a subnetmap failed for node: {} with expection {}",
370 subnetId.getValue(), e);
375 protected void deleteSubnetMapNode(Uuid subnetId) {
376 InstanceIdentifier<Subnetmap> subnetMapIdentifier =
377 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,new SubnetmapKey(subnetId)).build();
378 LOG.debug("removing subnetMap node: {} ", subnetId.getValue());
380 synchronized (subnetId.getValue().intern()) {
381 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
383 } catch (Exception e) {
384 LOG.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
388 private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
390 VpnInstanceBuilder builder = null;
391 List<VpnTarget> vpnTargetList = new ArrayList<>();
392 boolean isLockAcquired = false;
393 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).child
394 (VpnInstance.class, new VpnInstanceKey(vpnName)).build();
396 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
398 LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
399 if (optionalVpn.isPresent()) {
400 builder = new VpnInstanceBuilder(optionalVpn.get());
401 LOG.debug("updating existing vpninstance node");
403 builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName);
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.get(0));
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 private void deleteVpnMapsNode(Uuid vpnid) {
458 boolean isLockAcquired = false;
459 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
460 .child(VpnMap.class, new VpnMapKey(vpnid))
462 LOG.debug("removing vpnMaps node: {} ", vpnid.getValue());
464 isLockAcquired = NeutronvpnUtils.lock(vpnid.getValue());
465 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
466 } catch (Exception e) {
467 LOG.error("Delete vpnMaps node failed for vpn : {} ", vpnid.getValue());
469 if (isLockAcquired) {
470 NeutronvpnUtils.unlock(vpnid.getValue());
475 private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
476 VpnMapBuilder builder;
477 boolean isLockAcquired = false;
478 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
479 .child(VpnMap.class, new VpnMapKey(vpnId))
482 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
484 if (optionalVpnMap.isPresent()) {
485 builder = new VpnMapBuilder(optionalVpnMap.get());
487 builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
491 builder.setName(name);
493 if (tenantId != null) {
494 builder.setTenantId(tenantId);
496 if (router != null) {
497 builder.setRouterId(router);
499 if (networks != null) {
500 List<Uuid> nwList = builder.getNetworkIds();
501 if (nwList == null) {
502 nwList = new ArrayList<>();
504 nwList.addAll(networks);
505 builder.setNetworkIds(nwList);
508 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
509 LOG.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
510 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
511 LOG.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
512 } catch (Exception e) {
513 LOG.error("UpdateVpnMaps failed for node: {} ", vpnId.getValue());
515 if (isLockAcquired) {
516 NeutronvpnUtils.unlock(vpnId.getValue());
521 private void clearFromVpnMaps(Uuid vpnId, Uuid routerId, List<Uuid> networkIds) {
522 boolean isLockAcquired = false;
523 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
524 .child(VpnMap.class, new VpnMapKey(vpnId))
526 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
528 if (optionalVpnMap.isPresent()) {
529 VpnMap vpnMap = optionalVpnMap.get();
530 VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
531 if (routerId != null) {
532 if (vpnMap.getNetworkIds() == null && routerId.equals(vpnMap.getVpnId())) {
534 // remove entire node in case of internal VPN
535 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
536 LOG.debug("removing vpnMaps node: {} ", vpnId);
537 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
538 } catch (Exception e) {
539 LOG.error("Deletion of vpnMaps node failed for vpn {}", vpnId.getValue());
541 if (isLockAcquired) {
542 NeutronvpnUtils.unlock(vpnId.getValue());
547 vpnMapBuilder.setRouterId(null);
549 if (networkIds != null) {
550 List<Uuid> vpnNw = vpnMap.getNetworkIds();
551 for (Uuid nw : networkIds) {
554 if (vpnNw.isEmpty()) {
555 LOG.debug("setting networks null in vpnMaps node: {} ", vpnId.getValue());
556 vpnMapBuilder.setNetworkIds(null);
558 vpnMapBuilder.setNetworkIds(vpnNw);
563 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
564 LOG.debug("clearing from vpnMaps node: {} ", vpnId.getValue());
565 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier,
566 vpnMapBuilder.build());
567 } catch (Exception e) {
568 LOG.error("Clearing from vpnMaps node failed for vpn {}", vpnId.getValue());
570 if (isLockAcquired) {
571 NeutronvpnUtils.unlock(vpnId.getValue());
575 LOG.error("VPN : {} not found", vpnId.getValue());
577 LOG.debug("Clear from VPNMaps DS successful for VPN {} ", vpnId.getValue());
580 private void deleteVpnInstance(Uuid vpnId) {
581 boolean isLockAcquired = false;
582 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
583 .child(VpnInstance.class,
584 new VpnInstanceKey(vpnId.getValue()))
587 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
588 LOG.debug("Deleting vpnInstance {}", vpnId.getValue());
589 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
590 } catch (Exception e) {
591 LOG.error("Deletion of VPNInstance node failed for VPN {}", vpnId.getValue());
593 if (isLockAcquired) {
594 NeutronvpnUtils.unlock(vpnId.getValue());
599 protected void createVpnInterface(Uuid vpnId, Uuid routerId, Port port,
600 WriteTransaction wrtConfigTxn) {
601 String infName = port.getUuid().getValue();
602 List<Adjacency> adjList = new ArrayList<>();
603 List<FixedIps> ips = port.getFixedIps();
604 Boolean isRouterInterface = false;
605 if (port.getDeviceOwner() != null) {
606 isRouterInterface = port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF);
608 LOG.trace("createVpnInterface - isRouterInterface:{}", isRouterInterface);
610 if (routerId != null) {
611 rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
613 // create adjacency list
614 for (FixedIps ip : ips) {
615 // create vm adjacency
616 String ipValue = String.valueOf(ip.getIpAddress().getValue());
617 String ipPrefix = (ip.getIpAddress().getIpv4Address() != null) ? ipValue + "/32" : ipValue + "/128";
618 Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
619 .setMacAddress(port.getMacAddress().getValue()).setPrimaryAdjacency(true)
620 .setSubnetId(ip.getSubnetId()).build();
622 // create extra route adjacency
623 if (rtr != null && rtr.getRoutes() != null) {
624 List<Routes> routeList = rtr.getRoutes();
625 List<Adjacency> erAdjList = getAdjacencyforExtraRoute(vpnId, routeList, ipValue);
626 if (erAdjList != null && !erAdjList.isEmpty()) {
627 adjList.addAll(erAdjList);
630 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
631 .getMacAddress().getValue(), isRouterInterface, true, false);
633 // create vpn-interface on this neutron port
634 Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
635 writeVpnInterfaceToDs(vpnId, infName, adjs, isRouterInterface, wrtConfigTxn);
636 if (routerId != null) {
637 addToNeutronRouterInterfacesMap(routerId, infName);
641 protected void deleteVpnInterface(Uuid vpnId, Uuid routerId, Port port, WriteTransaction wrtConfigTxn) {
642 Boolean wrtConfigTxnPresent = true;
643 if (wrtConfigTxn == null) {
644 wrtConfigTxnPresent = false;
645 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
647 String infName = port.getUuid().getValue();
648 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
650 LOG.debug("Deleting vpn interface {}", infName);
651 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
653 List<FixedIps> ips = port.getFixedIps();
654 for (FixedIps ip : ips) {
655 String ipValue = String.valueOf(ip.getIpAddress().getValue());
656 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue);
658 } catch (Exception ex) {
659 LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
661 if (routerId != null) {
662 removeFromNeutronRouterInterfacesMap(routerId, infName);
664 if (!wrtConfigTxnPresent) {
665 wrtConfigTxn.submit();
669 protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean isBeingAssociated, boolean isSubnetIp) {
670 if (vpnId == null || port == null) {
673 boolean isLockAcquired = false;
674 String infName = port.getUuid().getValue();
675 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
677 isLockAcquired = NeutronvpnUtils.lock(infName);
678 Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
679 .CONFIGURATION, vpnIfIdentifier);
680 if (optionalVpnInterface.isPresent()) {
681 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get())
682 .setVpnInstanceName(vpnId.getValue());
683 LOG.debug("Updating vpn interface {}", infName);
684 if (!isBeingAssociated) {
685 Adjacencies adjs = vpnIfBuilder.getAugmentation(Adjacencies.class);
686 List<Adjacency> adjacencyList = (adjs != null) ? adjs.getAdjacency() : new ArrayList<Adjacency>();
687 Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
688 while (adjacencyIter.hasNext()) {
689 Adjacency adjacency = adjacencyIter.next();
690 String mipToQuery = adjacency.getIpAddress().split("/")[0];
691 InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier
692 (oldVpnId.getValue(), mipToQuery);
693 Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker,
696 if (!optionalVpnPort.isPresent() || optionalVpnPort.get().isLearnt()) {
697 LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} " +
698 "from VPN " + "{}", infName, vpnId, oldVpnId);
699 adjacencyIter.remove();
700 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), mipToQuery);
701 LOG.trace("Entry for fixedIP {} for port {} on VPN removed from " +
702 "VpnPortFixedIPToPortData", mipToQuery, infName, vpnId.getValue());
705 Adjacencies adjacencies = new AdjacenciesBuilder().setAdjacency(adjacencyList).build();
706 vpnIfBuilder.addAugmentation(Adjacencies.class, adjacencies);
708 List<FixedIps> ips = port.getFixedIps();
709 for (FixedIps ip : ips) {
710 String ipValue = String.valueOf(ip.getIpAddress().getValue());
711 if (oldVpnId != null) {
712 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
714 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
715 .getMacAddress().getValue(), isSubnetIp, true, false);
717 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
720 LOG.error("VPN Interface {} not found", infName);
722 } catch (Exception ex) {
723 LOG.error("Updation of vpninterface {} failed due to {}", infName, ex);
725 if (isLockAcquired) {
726 NeutronvpnUtils.unlock(infName);
731 public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt,
732 List<String> ert, Uuid router, List<Uuid> networks) {
734 // Update VPN Instance node
735 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
737 // Update local vpn-subnet DS
738 updateVpnMaps(vpn, name, router, tenant, networks);
740 if (router != null) {
741 Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(dataBroker, router, true);
742 if (existingVpn != null) {
743 // use case when a cluster is rebooted and router add DCN is received, triggering #createL3InternalVpn
745 // if before reboot, router was already associated to VPN, should not proceed associating router to
746 // internal VPN. Adding to RouterInterfacesMap is also not needed since it's a config DS and will be
747 // preserved upon reboot.
748 // For a non-reboot case #associateRouterToInternalVPN already takes care of adding to
749 // RouterInterfacesMap via #createVPNInterface call.
750 LOG.info("Associating router to Internal VPN skipped for VPN {} due to router {} already associated " +
751 "to external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
754 associateRouterToInternalVpn(vpn, router);
759 * Performs the creation of a Neutron L3VPN, associating the new VPN to the
760 * specified Neutron Networks and Routers
762 * @param vpn Uuid of the VPN tp be created
763 * @param name Representative name of the new VPN
764 * @param tenant Uuid of the Tenant under which the VPN is going to be created
765 * @param rd Route-distinguisher for the VPN
766 * @param irt A list of Import Route Targets
767 * @param ert A list of Export Route Targets
768 * @param router UUID of the neutron router the VPN may be associated to
769 * @param networks UUID of the neutron network the VPN may be associated to
770 * @throws Exception if association of L3VPN failed
772 public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
773 Uuid router, List<Uuid> networks) throws Exception {
775 // Update VPN Instance node
776 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
778 // Please note that router and networks will be filled into VPNMaps
779 // by subsequent calls here to associateRouterToVpn and
780 // associateNetworksToVpn
781 updateVpnMaps(vpn, name, null, tenant, null);
783 if (router != null) {
784 associateRouterToVpn(vpn, router);
786 if (networks != null) {
787 List<String> failStrings = associateNetworksToVpn(vpn, networks);
788 if (failStrings != null && !failStrings.isEmpty()) {
789 LOG.error("L3VPN {} association to networks failed with error message {}. ",
790 vpn.getValue(), failStrings.get(0));
791 throw new Exception(failStrings.get(0));
797 * It handles the invocations to the createL3VPN RPC method
799 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#createL3VPN
800 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput)
803 public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
805 CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
806 SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
807 List<RpcError> errorList = new ArrayList<>();
808 int failurecount = 0;
809 int warningcount = 0;
811 List<L3vpn> vpns = input.getL3vpn();
812 for (L3vpn vpn : vpns) {
813 List<String> existingRDs = NeutronvpnUtils.getExistingRDs(dataBroker);
814 RpcError error = null;
816 if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
817 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
818 vpn.getId().getValue());
820 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
821 errorList.add(error);
825 if (vpn.getRouteDistinguisher().size() > 1) {
826 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
827 vpn.getId().getValue(), vpn.getRouteDistinguisher());
829 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
830 errorList.add(error);
834 if (existingRDs.contains(vpn.getRouteDistinguisher().get(0))) {
835 msg = String.format("Creation of L3VPN failed for VPN %s as another VPN with the same RD %s is already configured",
836 vpn.getId().getValue(), vpn.getRouteDistinguisher().get(0));
838 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
839 errorList.add(error);
843 if (vpn.getRouterId() != null) {
844 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
845 msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
846 vpn.getId().getValue(), vpn.getRouterId().getValue());
848 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
849 errorList.add(error);
853 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
855 msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
856 + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
859 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
860 errorList.add(error);
865 if (vpn.getNetworkIds() != null) {
866 for (Uuid nw : vpn.getNetworkIds()) {
867 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
868 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
869 if (network == null) {
870 msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
871 vpn.getId().getValue(), nw.getValue());
873 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
874 errorList.add(error);
876 } else if (vpnId != null) {
877 msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
878 + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
881 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
882 errorList.add(error);
891 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
892 vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
893 } catch (Exception ex) {
894 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
896 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
897 errorList.add(error);
901 // if at least one succeeds; result is success
902 // if none succeeds; result is failure
903 if (failurecount + warningcount == vpns.size()) {
904 result.set(RpcResultBuilder.<CreateL3VPNOutput> failed().withRpcErrors(errorList).build());
906 List<String> errorResponseList = new ArrayList<>();
907 if (!errorList.isEmpty()) {
908 for (RpcError rpcError : errorList) {
909 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
910 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
911 errorResponseList.add(errorResponse);
914 errorResponseList.add("Operation successful with no errors");
916 opBuilder.setResponse(errorResponseList);
917 result.set(RpcResultBuilder.<CreateL3VPNOutput> success().withResult(opBuilder.build()).build());
923 * It handles the invocations to the neutronvpn:getL3VPN RPC method
925 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getL3VPN
926 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput)
929 public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
931 GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
932 SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
933 Uuid inputVpnId = input.getId();
934 List<VpnInstance> vpns = new ArrayList<>();
937 if (inputVpnId == null) {
939 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
941 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker,
942 LogicalDatastoreType.CONFIGURATION,
944 if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
945 for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
946 // eliminating internal VPNs from getL3VPN output
947 if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
953 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL, "", "No VPN " +
954 "is present").build());
958 String name = inputVpnId.getValue();
959 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
960 .child(VpnInstance.class,
961 new VpnInstanceKey(name))
963 // read VpnInstance Info
964 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
966 if (optionalVpn.isPresent()) {
967 vpns.add(optionalVpn.get());
969 String message = String.format("GetL3VPN failed because VPN %s is not present", name);
971 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
972 "invalid-value", message).build());
975 List<L3vpnInstances> l3vpnList = new ArrayList<>();
976 for (VpnInstance vpnInstance : vpns) {
977 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
979 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
980 .class, new VpnMapKey(vpnId)).build();
981 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
983 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
984 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
986 List<String> ertList = new ArrayList<>();
987 List<String> irtList = new ArrayList<>();
989 for (VpnTarget vpnTarget : vpnTargetList) {
990 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
991 ertList.add(vpnTarget.getVrfRTValue());
993 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
994 irtList.add(vpnTarget.getVrfRTValue());
996 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
997 ertList.add(vpnTarget.getVrfRTValue());
998 irtList.add(vpnTarget.getVrfRTValue());
1002 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1003 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1005 if (optionalVpnMap.isPresent()) {
1006 VpnMap vpnMap = optionalVpnMap.get();
1007 l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1008 .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1010 l3vpnList.add(l3vpn.build());
1013 opBuilder.setL3vpnInstances(l3vpnList);
1014 result.set(RpcResultBuilder.<GetL3VPNOutput> success().withResult(opBuilder.build()).build());
1016 } catch (Exception ex) {
1017 String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
1018 LOG.error(message, ex);
1019 result.set(RpcResultBuilder.<GetL3VPNOutput> failed().withError(ErrorType.APPLICATION, message).build());
1025 * It handles the invocations to the neutronvpn:deleteL3VPN RPC method
1027 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#deleteL3VPN
1028 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput)
1031 public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1033 DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1034 SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1035 List<RpcError> errorList = new ArrayList<>();
1037 int failurecount = 0;
1038 int warningcount = 0;
1039 List<Uuid> vpns = input.getId();
1040 for (Uuid vpn : vpns) {
1044 InstanceIdentifier<VpnInstance> vpnIdentifier =
1045 InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey
1046 (vpn.getValue())).build();
1047 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1048 .CONFIGURATION, vpnIdentifier);
1049 if (optionalVpn.isPresent()) {
1052 msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1054 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1055 errorList.add(error);
1058 } catch (Exception ex) {
1059 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1061 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1062 errorList.add(error);
1066 // if at least one succeeds; result is success
1067 // if none succeeds; result is failure
1068 if (failurecount + warningcount == vpns.size()) {
1069 result.set(RpcResultBuilder.<DeleteL3VPNOutput> failed().withRpcErrors(errorList).build());
1071 List<String> errorResponseList = new ArrayList<>();
1072 if (!errorList.isEmpty()) {
1073 for (RpcError rpcError : errorList) {
1074 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1075 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1076 errorResponseList.add(errorResponse);
1079 errorResponseList.add("Operation successful with no errors");
1081 opBuilder.setResponse(errorResponseList);
1082 result.set(RpcResultBuilder.<DeleteL3VPNOutput> success().withResult(opBuilder.build()).build());
1087 protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
1088 LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1089 Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1090 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1091 // Check if there are ports on this subnet and add corresponding
1093 List<Uuid> portList = sn.getPortList();
1094 if (portList != null) {
1095 for (final Uuid portId : sn.getPortList()) {
1096 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1097 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1098 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), new
1099 Callable<List<ListenableFuture<Void>>>() {
1101 public List<ListenableFuture<Void>> call() throws Exception {
1102 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1103 List<ListenableFuture<Void>> futures = new ArrayList<>();
1104 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1106 futures.add(wrtConfigTxn.submit());
1114 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1115 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1116 // Read the subnet first to see if its already associated to a VPN
1117 Uuid oldVpnId = null;
1118 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class).
1119 child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1120 Subnetmap sn = null;
1121 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1122 if (optSn.isPresent()) {
1124 oldVpnId = sn.getVpnId();
1125 List<String> ips = sn.getRouterInterfaceFixedIps();
1126 for (String ipValue : ips) {
1127 // Update the association of router-interface to external vpn
1128 String PortName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, oldVpnId.getValue(), ipValue);
1129 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(PortName)),
1130 isBeingAssociated, true);
1133 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1134 // Check for ports on this subnet and update association of
1135 // corresponding vpn-interfaces to external vpn
1136 List<Uuid> portList = sn.getPortList();
1137 if (portList != null) {
1138 for (Uuid port : sn.getPortList()) {
1139 LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}", port.getValue(), isBeingAssociated);
1140 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port),
1141 isBeingAssociated, false);
1146 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1147 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1148 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1151 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1152 synchronized (routerId.getValue().intern()) {
1153 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1154 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1155 .CONFIGURATION, routerInterfacesId);
1156 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1157 (interfaceName).build();
1158 if (optRouterInterfaces.isPresent()) {
1159 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1160 .class, new InterfacesKey(interfaceName)), routerInterface);
1162 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1163 List<Interfaces> interfaces = new ArrayList<>();
1164 interfaces.add(routerInterface);
1165 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1166 .class, new InterfacesKey(interfaceName)), routerInterface);
1171 protected void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1172 synchronized (routerId.getValue().intern()) {
1173 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1174 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1175 .CONFIGURATION, routerInterfacesId);
1176 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1177 (interfaceName).build();
1178 if (optRouterInterfaces.isPresent()) {
1179 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1180 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1181 if (interfaces != null && interfaces.remove(routerInterface)) {
1182 if (interfaces.isEmpty()) {
1183 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1185 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1186 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1194 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1195 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1196 * route will be ignored.
1198 * @param vpnName the VPN identifier
1199 * @param interVpnLinkRoutes The list of static routes
1200 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1202 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1203 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1204 for ( Routes route : interVpnLinkRoutes ) {
1205 String nexthop = String.valueOf(route.getNexthop().getValue());
1206 String destination = String.valueOf(route.getDestination().getValue());
1207 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1208 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1209 AddStaticRouteInput rpcInput =
1210 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1211 .setVpnInstanceName(vpnName.getValue())
1213 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1214 RpcResult<AddStaticRouteOutput> rpcResult;
1216 rpcResult = labelOuputFtr.get();
1217 if ( rpcResult.isSuccessful() ) {
1218 LOG.debug("Label generated for destination {} is: {}",
1219 destination, rpcResult.getResult().getLabel());
1221 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1222 destination, nexthop, rpcResult.getErrors());
1224 } catch (InterruptedException | ExecutionException e) {
1225 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1228 // Any other case is a fault.
1229 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1230 String.valueOf(route.getDestination().getValue()), nexthop );
1237 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1238 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1240 * @param vpnName the VPN identifier
1241 * @param interVpnLinkRoutes The list of static routes
1242 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1244 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1245 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1246 for ( Routes route : interVpnLinkRoutes ) {
1247 String nexthop = String.valueOf(route.getNexthop().getValue());
1248 String destination = String.valueOf(route.getDestination().getValue());
1249 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1250 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1251 RemoveStaticRouteInput rpcInput =
1252 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1253 .setVpnInstanceName(vpnName.getValue())
1255 vpnRpcService.removeStaticRoute(rpcInput);
1257 // Any other case is a fault.
1258 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1259 String.valueOf(route.getDestination().getValue()), nexthop );
1266 * Returns true if the specified nexthop is the other endpoint in an
1267 * InterVpnLink, regarding one of the VPN's point of view.
1269 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1271 interVpnLink != null
1272 && ( (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1273 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1274 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1275 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1278 protected List<Adjacency> getAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList, String fixedIp) {
1279 List<Adjacency> adjList = new ArrayList<>();
1280 Map<String, List<String>> adjMap = new HashMap<>();
1281 for (Routes route : routeList) {
1282 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1283 LOG.error("Incorrect input received for extra route. {}", route);
1285 String nextHop = String.valueOf(route.getNexthop().getValue());
1286 String destination = String.valueOf(route.getDestination().getValue());
1287 if (!nextHop.equals(fixedIp)) {
1288 LOG.trace("FixedIP {} is not extra route nexthop for destination {}", fixedIp, destination);
1291 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} ", destination,
1292 vpnId.getValue(), nextHop);
1293 List<String> hops = adjMap.get(destination);
1295 hops = new ArrayList<>();
1296 adjMap.put(destination, hops);
1298 if (!hops.contains(nextHop)) {
1304 for (String destination : adjMap.keySet()) {
1305 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(adjMap.get
1306 (destination)).setKey(new AdjacencyKey(destination)).build();
1312 protected void updateVpnInterfaceWithExtraRouteAdjacency(Uuid vpnId, List<Routes> routeList) {
1313 for (Routes route : routeList) {
1314 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1315 LOG.error("Incorrect input received for extra route. {}", route);
1317 String nextHop = String.valueOf(route.getNexthop().getValue());
1318 String destination = String.valueOf(route.getDestination().getValue());
1319 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1321 if (infName != null) {
1322 LOG.trace("Updating extra route for destination {} onto vpn {} with nexthop {} and infName {}", destination,
1323 vpnId.getValue(), nextHop, infName);
1324 boolean isLockAcquired = false;
1326 InstanceIdentifier<VpnInterface> identifier = InstanceIdentifier.builder(VpnInterfaces.class)
1327 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1328 InstanceIdentifier<Adjacency> path = identifier.augmentation(Adjacencies.class).
1329 child(Adjacency.class, new AdjacencyKey(destination));
1330 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(Arrays.asList(nextHop)).
1331 setKey(new AdjacencyKey(destination)).build();
1332 isLockAcquired = NeutronvpnUtils.lock(infName);
1333 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, erAdj);
1334 } catch (Exception e) {
1335 LOG.error("exception in adding extra route with destination: {}, next hop: {}", destination, nextHop, e);
1337 if (isLockAcquired) {
1338 NeutronvpnUtils.unlock(infName);
1342 LOG.debug("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} " +
1343 "with nexthop {}", destination, vpnId.getValue(), nextHop);
1349 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1350 for (Routes route : routeList) {
1351 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1352 boolean isLockAcquired = false;
1353 String nextHop = String.valueOf(route.getNexthop().getValue());
1354 String destination = String.valueOf(route.getDestination().getValue());
1355 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1357 if (infName == null) {
1358 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} " +
1360 destination, vpnId.getValue(), nextHop);
1361 // Proceed to remove the next extra-route
1364 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1365 destination, vpnId.getValue(), nextHop, infName);
1367 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1368 InstanceIdentifier.builder(VpnInterfaces.class)
1369 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1370 .augmentation(Adjacencies.class)
1371 .child(Adjacency.class, new AdjacencyKey(destination))
1374 // Looking for existing prefix in MDSAL database
1375 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1376 adjacencyIdentifier);
1377 boolean updateNextHops = false;
1378 List<String> nextHopList = new ArrayList<>();
1379 if (adjacency.isPresent()) {
1380 List<String> nhListRead = adjacency.get().getNextHopIpList();
1381 if (nhListRead.size() > 1) { // ECMP case
1382 for (String nextHopRead : nhListRead) {
1383 if (nextHopRead.equals(nextHop)) {
1384 updateNextHops = true;
1386 nextHopList.add(nextHopRead);
1393 isLockAcquired = NeutronvpnUtils.lock(infName);
1394 if (updateNextHops) {
1395 // An update must be done, not including the current next hop
1396 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1397 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1398 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1399 .setNextHopIpList(nextHopList)
1400 .setKey(new AdjacencyKey(destination))
1402 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1403 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1404 .addAugmentation(Adjacencies.class, erAdjs).build();
1405 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1407 // Remove the whole route
1408 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1409 LOG.trace("extra route {} deleted successfully", route);
1411 } catch (Exception e) {
1412 LOG.error("exception in deleting extra route: {}" + e);
1414 if (isLockAcquired) {
1415 NeutronvpnUtils.unlock(infName);
1419 LOG.error("Incorrect input received for extra route. {}", route);
1424 protected void removeL3Vpn(Uuid id) {
1426 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1427 Uuid router = vpnMap.getRouterId();
1428 // dissociate router
1429 if (router != null) {
1430 dissociateRouterFromVpn(id, router);
1432 // dissociate networks
1433 if (!id.equals(router)) {
1434 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1436 // remove entire vpnMaps node
1437 deleteVpnMapsNode(id);
1439 // remove vpn-instance
1440 deleteVpnInstance(id);
1443 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1444 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1445 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1446 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1448 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1449 List<Uuid> portList = sn.getPortList();
1450 if (portList != null) {
1451 for (final Uuid portId : sn.getPortList()) {
1452 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1453 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1454 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1455 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1456 List<ListenableFuture<Void>> futures = new ArrayList<>();
1457 deleteVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1459 futures.add(wrtConfigTxn.submit());
1464 // update subnet-vpn association
1465 removeFromSubnetNode(subnet, null, null, vpnId, null);
1467 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1471 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1472 updateVpnMaps(vpnId, null, routerId, null, null);
1473 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1474 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1475 if (routerSubnets != null) {
1476 for (Uuid subnetId : routerSubnets) {
1477 updateVpnForSubnet(vpnId, subnetId, true);
1481 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1482 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1484 } catch (Exception e) {
1485 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1486 .getValue(), vpnId.getValue(), e);
1490 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1491 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1492 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1493 for (Uuid subnet : routerSubnets) {
1494 addSubnetToVpn(vpnId, subnet);
1498 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1500 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1501 if (routerSubnets != null) {
1502 for (Uuid subnetId : routerSubnets) {
1503 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1504 updateVpnForSubnet(routerId, subnetId, false);
1507 clearFromVpnMaps(vpnId, routerId, null);
1509 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1510 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1512 } catch (Exception e) {
1513 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1514 .getValue(), vpnId.getValue(), e);
1518 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1519 List<String> failedNwList = new ArrayList<>();
1520 List<Uuid> passedNwList = new ArrayList<>();
1521 if (!networks.isEmpty()) {
1522 // process corresponding subnets for VPN
1523 for (Uuid nw : networks) {
1524 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1525 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1526 if (network == null) {
1527 failedNwList.add(String.format("network %s not found", nw.getValue()));
1528 } else if (vpnId != null) {
1529 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1532 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1533 LOG.debug("Adding network subnets...{}", networkSubnets);
1534 if (networkSubnets != null) {
1535 for (Uuid subnet : networkSubnets) {
1536 // check if subnet added as router interface to some router
1537 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1538 if (subnetVpnId == null) {
1539 addSubnetToVpn(vpn, subnet);
1540 passedNwList.add(nw);
1542 failedNwList.add(String.format("subnet %s already added as router interface bound to " +
1543 "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
1547 if (NeutronvpnUtils.getIsExternal(network)) {
1548 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1552 updateVpnMaps(vpn, null, null, null, passedNwList);
1554 return failedNwList;
1557 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1558 List<String> failedNwList = new ArrayList<>();
1559 List<Uuid> passedNwList = new ArrayList<>();
1560 if (networks != null && !networks.isEmpty()) {
1561 // process corresponding subnets for VPN
1562 for (Uuid nw : networks) {
1563 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1564 if (network == null) {
1565 failedNwList.add(String.format("network %s not found", nw.getValue()));
1567 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1568 if (vpn.equals(vpnId)) {
1569 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1570 LOG.debug("Removing network subnets...");
1571 if (networkSubnets != null) {
1572 for (Uuid subnet : networkSubnets) {
1573 removeSubnetFromVpn(vpn, subnet);
1574 passedNwList.add(nw);
1578 if (vpnId == null) {
1579 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1582 failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
1583 "of the one given as input", nw.getValue(), vpnId.getValue()));
1586 if (NeutronvpnUtils.getIsExternal(network)) {
1587 nvpnNatManager.removeExternalNetworkFromVpn(network);
1591 clearFromVpnMaps(vpn, null, passedNwList);
1593 return failedNwList;
1597 * It handles the invocations to the neutronvpn:associateNetworks RPC method
1599 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateNetworks
1600 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput)
1603 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1605 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1606 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1607 LOG.debug("associateNetworks {}", input);
1608 StringBuilder returnMsg = new StringBuilder();
1609 Uuid vpnId = input.getVpnId();
1612 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1613 List<Uuid> netIds = input.getNetworkId();
1614 if (netIds != null && !netIds.isEmpty()) {
1615 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1616 if (!failed.isEmpty()) {
1617 returnMsg.append(failed);
1621 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1623 if (returnMsg.length() != 0) {
1624 String message = String.format("associate Networks to vpn %s failed due to %s",
1625 vpnId.getValue(), returnMsg);
1627 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1629 opBuilder.setResponse(errorResponse);
1630 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().withResult(opBuilder.build()).build());
1632 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().build());
1634 } catch (Exception ex) {
1635 String message = String.format("associate Networks to vpn %s failed due to %s",
1636 input.getVpnId().getValue(), ex.getMessage());
1637 LOG.error(message, ex);
1638 result.set(RpcResultBuilder.<AssociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1641 LOG.debug("associateNetworks returns..");
1646 * It handles the invocations to the neutronvpn:associateRouter RPC method
1648 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateRouter
1649 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput)
1652 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1654 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1655 LOG.debug("associateRouter {}", input);
1656 StringBuilder returnMsg = new StringBuilder();
1657 Uuid vpnId = input.getVpnId();
1658 Uuid routerId = input.getRouterId();
1660 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1661 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1662 if (vpnMap != null) {
1664 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1665 if (vpnMap.getRouterId() != null) {
1666 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1667 .append(vpnMap.getRouterId().getValue());
1668 } else if (extVpnId != null) {
1669 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
1670 "another VPN ").append(extVpnId.getValue());
1672 associateRouterToVpn(vpnId, routerId);
1675 returnMsg.append("router not found : ").append(routerId.getValue());
1678 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1680 if (returnMsg.length() != 0) {
1681 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1684 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1687 result.set(RpcResultBuilder.<Void> success().build());
1689 } catch (Exception ex) {
1690 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1691 vpnId.getValue(), ex.getMessage());
1692 LOG.error(message, ex);
1693 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1695 LOG.debug("associateRouter returns..");
1699 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method
1701 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getFixedIPsForNeutronPort
1702 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput)
1705 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput input) {
1706 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1707 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1708 Uuid portId = input.getPortId();
1709 StringBuilder returnMsg = new StringBuilder();
1711 List<String> fixedIPList = new ArrayList<>();
1712 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1714 List<FixedIps> fixedIPs = port.getFixedIps();
1715 for (FixedIps ip : fixedIPs) {
1716 fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
1719 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1721 if (returnMsg.length() != 0) {
1722 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1724 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1725 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1727 opBuilder.setFixedIPs(fixedIPList);
1728 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().withResult(opBuilder.build())
1730 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().build());
1732 } catch (Exception ex) {
1733 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1734 portId.getValue(), ex.getMessage());
1735 LOG.error(message, ex);
1736 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1737 .withError(ErrorType.APPLICATION, message).build());
1743 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method
1745 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1746 * .rev150602.NeutronvpnService#dissociateNetworks(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1747 * .neutronvpn.rev150602.DissociateNetworksInput)
1750 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1752 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1753 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1755 LOG.debug("dissociateNetworks {}", input);
1756 StringBuilder returnMsg = new StringBuilder();
1757 Uuid vpnId = input.getVpnId();
1760 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1761 List<Uuid> netIds = input.getNetworkId();
1762 if (netIds != null && !netIds.isEmpty()) {
1763 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1764 if (!failed.isEmpty()) {
1765 returnMsg.append(failed);
1769 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1771 if (returnMsg.length() != 0) {
1772 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1775 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1777 opBuilder.setResponse(errorResponse);
1778 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().withResult(opBuilder.build()).build());
1780 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().build());
1782 } catch (Exception ex) {
1783 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1784 input.getVpnId().getValue(), ex.getMessage());
1785 LOG.error(message, ex);
1786 result.set(RpcResultBuilder.<DissociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1789 LOG.debug("dissociateNetworks returns..");
1794 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1796 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1797 * .rev150602.NeutronvpnService#dissociateRouter(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1798 * .rev150602.DissociateRouterInput)
1801 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1803 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1805 LOG.debug("dissociateRouter {}", input);
1806 StringBuilder returnMsg = new StringBuilder();
1807 Uuid vpnId = input.getVpnId();
1808 Uuid routerId = input.getRouterId();
1810 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1811 if (routerId != null) {
1812 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1814 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1815 if (vpnId.equals(routerVpnId)) {
1816 dissociateRouterFromVpn(vpnId, routerId);
1818 if (routerVpnId == null) {
1819 returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
1822 returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
1823 "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
1828 returnMsg.append("router not found : ").append(routerId.getValue());
1832 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1834 if (returnMsg.length() != 0) {
1835 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1836 vpnId.getValue(), returnMsg);
1838 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1840 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1843 result.set(RpcResultBuilder.<Void> success().build());
1845 } catch (Exception ex) {
1846 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1847 vpnId.getValue(), ex.getMessage());
1848 LOG.error(message, ex);
1849 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1851 LOG.debug("dissociateRouter returns..");
1856 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1857 // check if the router is associated to some VPN
1858 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1859 if (vpnId != null) {
1860 // remove existing external vpn interfaces
1861 for (Uuid subnetId : routerSubnetIds) {
1862 removeSubnetFromVpn(vpnId, subnetId);
1864 clearFromVpnMaps(vpnId, routerId, null);
1866 // remove existing internal vpn interfaces
1867 for (Uuid subnetId : routerSubnetIds) {
1868 removeSubnetFromVpn(routerId, subnetId);
1871 // delete entire vpnMaps node for internal VPN
1872 deleteVpnMapsNode(routerId);
1874 // delete vpn-instance for internal VPN
1875 deleteVpnInstance(routerId);
1878 protected Subnet getNeutronSubnet(Uuid subnetId){
1879 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1882 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1883 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1885 return sn.getGatewayIp();
1891 protected Network getNeutronNetwork(Uuid networkId) {
1892 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1895 protected Port getNeutronPort(String name) {
1896 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1899 protected Port getNeutronPort(Uuid portId) {
1900 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1903 protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1904 List<Uuid> subnets = new ArrayList<>();
1906 InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1907 Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1909 if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1910 List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1911 for (Subnetmap subnetMap : subnetMapList) {
1912 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1913 subnets.add(subnetMap.getId());
1921 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command
1923 * @return a List of String to be printed on screen
1925 public List<String> showNeutronPortsCLI() {
1926 List<String> result = new ArrayList<>();
1927 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
1929 result.add("-------------------------------------------------------------------------------------------");
1930 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
1932 Optional<Ports> ports = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
1933 if (ports.isPresent() && ports.get().getPort() != null) {
1934 for (Port port : ports.get().getPort()) {
1935 List<FixedIps> fixedIPs = port.getFixedIps();
1937 if (fixedIPs != null && !fixedIPs.isEmpty()) {
1938 List<String> ipList = new ArrayList<>();
1939 for (FixedIps fixedIp : fixedIPs) {
1940 IpAddress ipAddress = fixedIp.getIpAddress();
1941 if (ipAddress.getIpv4Address() != null) {
1942 ipList.add(ipAddress.getIpv4Address().getValue());
1944 ipList.add((ipAddress.getIpv6Address().getValue()));
1947 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
1948 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
1949 ipList.toString()));
1951 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
1952 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
1954 } catch (Exception e) {
1955 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
1957 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
1958 .getValue() + ": " + e.getMessage());
1962 } catch (Exception e) {
1963 LOG.error("Failed to retrieve neutronPorts info : ", e);
1964 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
1970 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command
1972 * @param vpnuuid Uuid of the VPN whose config must be shown
1973 * @return formatted output list
1975 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
1976 List<String> result = new ArrayList<>();
1977 if (vpnuuid == null) {
1978 System.out.println("");
1979 System.out.println("Displaying VPN config for all VPNs");
1980 System.out.println("To display VPN config for a particular VPN, use the following syntax");
1981 System.out.println(getshowVpnConfigCLIHelp());
1984 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
1985 if (rpcResult.isSuccessful()) {
1987 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
1989 result.add(String.format(" %-80s ", "Import-RTs"));
1991 result.add(String.format(" %-80s ", "Export-RTs"));
1993 result.add(String.format(" %-76s ", "Subnet IDs"));
1995 result.add("------------------------------------------------------------------------------------");
1997 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
1998 for (L3vpnInstance Vpn : VpnList) {
1999 String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue()
2001 result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId,
2002 Vpn.getRouteDistinguisher()));
2004 result.add(String.format(" %-80s ", Vpn.getImportRT()));
2006 result.add(String.format(" %-80s ", Vpn.getExportRT()));
2009 Uuid vpnid = Vpn.getId();
2010 List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2011 if (!subnetList.isEmpty()) {
2012 for (Uuid subnetuuid : subnetList) {
2013 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2016 result.add(String.format(" %-76s ", "\" \""));
2019 result.add("----------------------------------------");
2023 String errortag = rpcResult.getErrors().iterator().next().getTag();
2024 if (errortag == "") {
2025 System.out.println("");
2026 System.out.println("No VPN has been configured yet");
2027 } else if (errortag == "invalid-value") {
2028 System.out.println("");
2029 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2031 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2032 System.out.println(getshowVpnConfigCLIHelp());
2035 } catch (InterruptedException | ExecutionException e) {
2036 LOG.error("error getting VPN info : ", e);
2037 System.out.println("error getting VPN info : " + e.getMessage());
2042 protected void createExternalVpnInterfaces(Uuid extNetId) {
2043 if (extNetId == null) {
2044 LOG.trace("external network is null");
2048 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2049 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2050 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2054 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2055 for (String elanInterface : extElanInterfaces) {
2056 createExternalVpnInterface(extNetId, elanInterface, wrtConfigTxn);
2058 wrtConfigTxn.submit();
2061 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2062 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2063 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2064 LOG.trace("No external ports attached for external network {}", extNetId);
2069 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2070 for (String elanInterface : extElanInterfaces) {
2071 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2072 .buildVpnInterfaceIdentifier(elanInterface);
2073 LOG.info("Removing vpn interface {}", elanInterface);
2074 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2076 wrtConfigTxn.submit();
2078 } catch (Exception ex) {
2079 LOG.error("Removal of vpninterfaces {} failed due to {}", extElanInterfaces, ex);
2083 private void createExternalVpnInterface(Uuid vpnId, String infName, WriteTransaction wrtConfigTxn) {
2084 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, wrtConfigTxn);
2087 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2088 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2089 if (vpnId == null || infName == null) {
2090 LOG.debug("vpn id or interface is null");
2094 Boolean wrtConfigTxnPresent = true;
2095 if (wrtConfigTxn == null) {
2096 wrtConfigTxnPresent = false;
2097 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2100 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2101 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2103 .setVpnInstanceName(vpnId.getValue())
2104 .setIsRouterInterface(isRouterInterface);
2105 if (adjacencies != null) {
2106 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2108 VpnInterface vpnIf = vpnb.build();
2110 LOG.info("Creating vpn interface {}", vpnIf);
2111 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2112 } catch (Exception ex) {
2113 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2116 if (!wrtConfigTxnPresent) {
2117 wrtConfigTxn.submit();
2121 private String getshowVpnConfigCLIHelp() {
2122 StringBuilder help = new StringBuilder("Usage:");
2123 help.append("display vpn-config [-vid/--vpnid <id>]");
2124 return help.toString();
2127 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2128 InterruptedException {
2129 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2130 .setVpnId(vpnId).build();
2131 LOG.info("publishing notification upon association of router to VPN");
2132 notificationPublishService.putNotification(routerAssociatedToVpn);
2135 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2136 InterruptedException {
2137 RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
2138 (routerId).setVpnId(vpnId).build();
2139 LOG.info("publishing notification upon disassociation of router from VPN");
2140 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2143 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2144 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);