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.elan.rev150602.ElanInstances;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.config.rev160806.NeutronvpnConfig;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksOutputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNOutputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNOutputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateNetworksOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DissociateRouterInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.L3vpnInstance;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpn;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterAssociatedToVpnBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpn;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterDisassociatedFromVpnBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetAddedToVpnBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetDeletedFromVpnBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.SubnetUpdatedInVpnBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInputBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteOutput;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInput;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInputBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
120 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
121 import org.opendaylight.yangtools.yang.common.RpcError;
122 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
123 import org.opendaylight.yangtools.yang.common.RpcResult;
124 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
125 import org.slf4j.Logger;
126 import org.slf4j.LoggerFactory;
128 import com.google.common.base.Optional;
129 import com.google.common.util.concurrent.ListenableFuture;
130 import com.google.common.util.concurrent.SettableFuture;
132 public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, EventListener {
133 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnManager.class);
134 private final DataBroker dataBroker;
135 private final NeutronvpnNatManager nvpnNatManager;
136 private final NotificationPublishService notificationPublishService;
137 private final VpnRpcService vpnRpcService;
138 private final NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
139 private final NeutronvpnConfig neutronvpnConfig;
140 private final IMdsalApiManager mdsalUtil;
141 private final IElanService elanService;
142 Boolean isExternalVpn;
145 * @param dataBroker DataBroker reference
146 * @param mdsalManager MDSAL Util API access
147 * @param notiPublishService notificationPublishService
148 * @param vpnNatMgr VPN NAT manager service
149 * @param vpnRpcSrv VPN RPC service
150 * @param elanService ELAN service
151 * @param neutronFloatingToFixedIpMappingChangeListener FIP to FixedIP listener
152 * @param neutronvpnConfig Neutronvpn configuration service
154 public NeutronvpnManager(
155 final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
156 final NotificationPublishService notiPublishService, final NeutronvpnNatManager vpnNatMgr,
157 final VpnRpcService vpnRpcSrv, final IElanService elanService,
158 final NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener,
159 final NeutronvpnConfig neutronvpnConfig) {
160 this.dataBroker = dataBroker;
161 mdsalUtil = mdsalManager;
162 nvpnNatManager = vpnNatMgr;
163 notificationPublishService = notiPublishService;
164 vpnRpcService = vpnRpcSrv;
165 this.elanService = elanService;
166 floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
167 LOG.info("neutronvpnConfig: {}", neutronvpnConfig);
168 this.neutronvpnConfig = neutronvpnConfig;
172 public void close() throws Exception {
173 LOG.info("{} close", getClass().getSimpleName());
176 public NeutronvpnConfig getNeutronvpnConfig() {
177 return neutronvpnConfig;
180 protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
181 Uuid routerInterfaceName, String fixedIp,
182 String routerIntfMacAddress) {
183 Subnetmap subnetmap = null;
184 SubnetmapBuilder builder = null;
185 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).
186 child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
188 synchronized (subnetId.getValue().intern()) {
189 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
190 if (sn.isPresent()) {
191 builder = new SubnetmapBuilder(sn.get());
192 LOG.debug("WithRouterFixedIPs: Updating existing subnetmap node for subnet ID {}", subnetId.getValue());
194 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
195 LOG.debug("WithRouterFixedIPs: creating new subnetmap node for subnet ID {}", subnetId.getValue());
197 if (routerId != null) {
198 builder.setRouterId(routerId);
200 builder.setRouterId(null);
202 if (routerInterfaceName != null) {
203 builder.setRouterInterfaceName(routerInterfaceName);
205 builder.setRouterInterfaceName(null);
207 if (routerIntfMacAddress != null) {
208 builder.setRouterIntfMacAddress(routerIntfMacAddress);
210 builder.setRouterIntfMacAddress(null);
212 if (fixedIp != null) {
213 List<String> fixedIps = builder.getRouterInterfaceFixedIps();
214 if (fixedIps == null) {
215 fixedIps = new ArrayList<>();
217 fixedIps.add(fixedIp);
218 builder.setRouterInterfaceFixedIps(fixedIps);
220 builder.setRouterInterfaceFixedIps(null);
222 subnetmap = builder.build();
223 LOG.debug("WithRouterFixedIPs Creating/Updating subnetMap node for Router FixedIps: {} ", subnetId.getValue());
224 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
226 } catch (Exception e) {
227 LOG.error("WithRouterFixedIPs: Updation of subnetMap for Router FixedIps failed for node: {}", subnetId.getValue());
231 protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
233 Subnetmap subnetmap = null;
234 SubnetmapBuilder builder = null;
235 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
236 .child(Subnetmap.class, new SubnetmapKey(subnetId))
239 synchronized (subnetId.getValue().intern()) {
240 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
241 if (sn.isPresent()) {
242 builder = new SubnetmapBuilder(sn.get());
243 LOG.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
245 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
246 LOG.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
249 if (subnetIp != null) {
250 builder.setSubnetIp(subnetIp);
252 if (routerId != null) {
253 builder.setRouterId(routerId);
255 if (networkId != null) {
256 builder.setNetworkId(networkId);
259 builder.setVpnId(vpnId);
261 if (tenantId != null) {
262 builder.setTenantId(tenantId);
265 subnetmap = builder.build();
266 LOG.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
267 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
269 } catch (Exception e) {
270 LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
275 protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
276 Subnetmap subnetmap = null;
277 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
278 .child(Subnetmap.class, new SubnetmapKey(subnetId))
281 synchronized (subnetId.getValue().intern()) {
282 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
283 if (sn.isPresent()) {
284 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
285 if (routerId != null) {
286 builder.setRouterId(null);
288 if (networkId != null) {
289 builder.setNetworkId(null);
292 builder.setVpnId(null);
294 if (portId != null && builder.getPortList() != null) {
295 List<Uuid> portList = builder.getPortList();
296 portList.remove(portId);
297 builder.setPortList(portList);
300 subnetmap = builder.build();
301 LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
302 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
304 LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
307 } catch (Exception e) {
308 LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
313 protected Subnetmap updateSubnetmapNodeWithPorts(Uuid subnetId, Uuid portId, Uuid directPortId) {
314 Subnetmap subnetmap = null;
315 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
316 new SubnetmapKey(subnetId)).build();
318 synchronized (subnetId.getValue().intern()) {
319 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
320 if (sn.isPresent()) {
321 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
322 if (null != portId) {
323 List<Uuid> portList = builder.getPortList();
324 if (null == portList) {
325 portList = new ArrayList<Uuid>();
327 portList.add(portId);
328 builder.setPortList(portList);
329 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
332 if (null != directPortId) {
333 List<Uuid> directPortList = builder.getDirectPortList();
334 if (null == directPortList) {
335 directPortList = new ArrayList<Uuid>();
337 directPortList.add(directPortId);
338 builder.setDirectPortList(directPortList);
339 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
340 directPortId.getValue());
342 subnetmap = builder.build();
343 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
345 LOG.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
348 } catch (Exception e) {
349 LOG.error("Updating port list of a given subnetMap failed for node: {} with exception{}",
350 subnetId.getValue(), e);
355 protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
356 Subnetmap subnetmap = null;
357 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
358 new SubnetmapKey(subnetId)).build();
360 synchronized (subnetId.getValue().intern()) {
361 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
362 if (sn.isPresent()) {
363 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
364 if (null != portId && null != builder.getPortList()) {
365 List<Uuid> portList = builder.getPortList();
366 portList.remove(portId);
367 builder.setPortList(portList);
368 LOG.debug("Removing port {} from existing subnetmap node: {} ", portId.getValue(),
369 subnetId.getValue());
371 if (null != directPortId && null != builder.getDirectPortList()) {
372 List<Uuid> directPortList = builder.getDirectPortList();
373 directPortList.remove(directPortId);
374 builder.setDirectPortList(directPortList);
375 LOG.debug("Removing direct port {} from existing subnetmap node: {} ", directPortId
376 .getValue(), subnetId.getValue());
378 subnetmap = builder.build();
379 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
381 LOG.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
384 } catch (Exception e) {
385 LOG.error("Removing a port from port list of a subnetmap failed for node: {} with expection {}",
386 subnetId.getValue(), e);
391 protected void deleteSubnetMapNode(Uuid subnetId) {
392 InstanceIdentifier<Subnetmap> subnetMapIdentifier =
393 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,new SubnetmapKey(subnetId)).build();
394 LOG.debug("removing subnetMap node: {} ", subnetId.getValue());
396 synchronized (subnetId.getValue().intern()) {
397 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
399 } catch (Exception e) {
400 LOG.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
404 private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
406 VpnInstanceBuilder builder = null;
407 List<VpnTarget> vpnTargetList = new ArrayList<>();
408 boolean isLockAcquired = false;
409 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class).child
410 (VpnInstance.class, new VpnInstanceKey(vpnName)).build();
412 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
414 LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
415 if (optionalVpn.isPresent()) {
416 builder = new VpnInstanceBuilder(optionalVpn.get());
417 LOG.debug("updating existing vpninstance node");
419 builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName);
421 if (irt != null && !irt.isEmpty()) {
422 if (ert != null && !ert.isEmpty()) {
423 List<String> commonRT = new ArrayList<>(irt);
424 commonRT.retainAll(ert);
426 for (String common : commonRT) {
429 VpnTarget vpnTarget =
430 new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue(common)
431 .setVrfRTType(VpnTarget.VrfRTType.Both).build();
432 vpnTargetList.add(vpnTarget);
435 for (String importRT : irt) {
436 VpnTarget vpnTarget =
437 new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue(importRT)
438 .setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
439 vpnTargetList.add(vpnTarget);
443 if (ert != null && !ert.isEmpty()) {
444 for (String exportRT : ert) {
445 VpnTarget vpnTarget =
446 new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue(exportRT)
447 .setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
448 vpnTargetList.add(vpnTarget);
452 VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
454 Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
456 if (rd != null && !rd.isEmpty()) {
457 ipv4vpnBuilder.setRouteDistinguisher(rd.get(0));
460 VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
461 isLockAcquired = NeutronvpnUtils.lock(vpnName);
462 LOG.debug("Creating/Updating vpn-instance for {} ", vpnName);
463 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
464 } catch (Exception e) {
465 LOG.error("Update VPN Instance node failed for node: {} {} {} {}", vpnName, rd, irt, ert);
467 if (isLockAcquired) {
468 NeutronvpnUtils.unlock(vpnName);
473 private void deleteVpnMapsNode(Uuid vpnid) {
474 boolean isLockAcquired = false;
475 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
476 .child(VpnMap.class, new VpnMapKey(vpnid))
478 LOG.debug("removing vpnMaps node: {} ", vpnid.getValue());
480 isLockAcquired = NeutronvpnUtils.lock(vpnid.getValue());
481 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
482 } catch (Exception e) {
483 LOG.error("Delete vpnMaps node failed for vpn : {} ", vpnid.getValue());
485 if (isLockAcquired) {
486 NeutronvpnUtils.unlock(vpnid.getValue());
491 private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
492 VpnMapBuilder builder;
493 boolean isLockAcquired = false;
494 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
495 .child(VpnMap.class, new VpnMapKey(vpnId))
498 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
500 if (optionalVpnMap.isPresent()) {
501 builder = new VpnMapBuilder(optionalVpnMap.get());
503 builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
507 builder.setName(name);
509 if (tenantId != null) {
510 builder.setTenantId(tenantId);
512 if (router != null) {
513 builder.setRouterId(router);
515 if (networks != null) {
516 List<Uuid> nwList = builder.getNetworkIds();
517 if (nwList == null) {
518 nwList = new ArrayList<>();
520 nwList.addAll(networks);
521 builder.setNetworkIds(nwList);
524 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
525 LOG.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
526 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
527 LOG.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
528 } catch (Exception e) {
529 LOG.error("UpdateVpnMaps failed for node: {} ", vpnId.getValue());
531 if (isLockAcquired) {
532 NeutronvpnUtils.unlock(vpnId.getValue());
537 private void clearFromVpnMaps(Uuid vpnId, Uuid routerId, List<Uuid> networkIds) {
538 boolean isLockAcquired = false;
539 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
540 .child(VpnMap.class, new VpnMapKey(vpnId))
542 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
544 if (optionalVpnMap.isPresent()) {
545 VpnMap vpnMap = optionalVpnMap.get();
546 VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
547 if (routerId != null) {
548 if (vpnMap.getNetworkIds() == null && routerId.equals(vpnMap.getVpnId())) {
550 // remove entire node in case of internal VPN
551 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
552 LOG.debug("removing vpnMaps node: {} ", vpnId);
553 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
554 } catch (Exception e) {
555 LOG.error("Deletion of vpnMaps node failed for vpn {}", vpnId.getValue());
557 if (isLockAcquired) {
558 NeutronvpnUtils.unlock(vpnId.getValue());
563 vpnMapBuilder.setRouterId(null);
565 if (networkIds != null) {
566 List<Uuid> vpnNw = vpnMap.getNetworkIds();
567 for (Uuid nw : networkIds) {
570 if (vpnNw.isEmpty()) {
571 LOG.debug("setting networks null in vpnMaps node: {} ", vpnId.getValue());
572 vpnMapBuilder.setNetworkIds(null);
574 vpnMapBuilder.setNetworkIds(vpnNw);
579 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
580 LOG.debug("clearing from vpnMaps node: {} ", vpnId.getValue());
581 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier,
582 vpnMapBuilder.build());
583 } catch (Exception e) {
584 LOG.error("Clearing from vpnMaps node failed for vpn {}", vpnId.getValue());
586 if (isLockAcquired) {
587 NeutronvpnUtils.unlock(vpnId.getValue());
591 LOG.error("VPN : {} not found", vpnId.getValue());
593 LOG.debug("Clear from VPNMaps DS successful for VPN {} ", vpnId.getValue());
596 private void deleteVpnInstance(Uuid vpnId) {
597 boolean isLockAcquired = false;
598 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
599 .child(VpnInstance.class,
600 new VpnInstanceKey(vpnId.getValue()))
603 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
604 LOG.debug("Deleting vpnInstance {}", vpnId.getValue());
605 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
606 } catch (Exception e) {
607 LOG.error("Deletion of VPNInstance node failed for VPN {}", vpnId.getValue());
609 if (isLockAcquired) {
610 NeutronvpnUtils.unlock(vpnId.getValue());
615 protected void createVpnInterface(Uuid vpnId, Uuid routerId, Port port,
616 WriteTransaction wrtConfigTxn) {
617 String infName = port.getUuid().getValue();
618 List<Adjacency> adjList = new ArrayList<>();
619 List<FixedIps> ips = port.getFixedIps();
620 Boolean isRouterInterface = false;
621 if (port.getDeviceOwner() != null) {
622 isRouterInterface = port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF);
624 LOG.trace("createVpnInterface - isRouterInterface:{}", isRouterInterface);
626 if (routerId != null) {
627 rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
629 // create adjacency list
630 for (FixedIps ip : ips) {
631 // create vm adjacency
632 StringBuilder IpPrefixBuild = new StringBuilder(ip.getIpAddress().getIpv4Address().getValue());
633 String IpPrefix = IpPrefixBuild.append("/32").toString();
634 Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(IpPrefix)).setIpAddress(IpPrefix)
635 .setMacAddress(port.getMacAddress().getValue()).setPrimaryAdjacency(true).build();
637 // create extra route adjacency
638 if (rtr != null && rtr.getRoutes() != null) {
639 List<Routes> routeList = rtr.getRoutes();
640 List<Adjacency> erAdjList = addAdjacencyforExtraRoute(vpnId, routeList);
641 if (erAdjList != null && !erAdjList.isEmpty()) {
642 adjList.addAll(erAdjList);
645 String ipValue = ip.getIpAddress().getIpv4Address().getValue();
646 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
647 .getMacAddress().getValue(), isRouterInterface, true, false);
649 // create vpn-interface on this neutron port
650 Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
651 writeVpnInterfaceToDs(vpnId, infName, adjs, isRouterInterface, wrtConfigTxn);
652 if (routerId != null) {
653 addToNeutronRouterInterfacesMap(routerId, infName);
657 protected void deleteVpnInterface(Uuid vpnId, Uuid routerId, Port port, WriteTransaction wrtConfigTxn) {
658 Boolean wrtConfigTxnPresent = true;
659 if (wrtConfigTxn == null) {
660 wrtConfigTxnPresent = false;
661 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
663 String infName = port.getUuid().getValue();
664 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
666 LOG.debug("Deleting vpn interface {}", infName);
667 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
669 List<FixedIps> ips = port.getFixedIps();
670 for (FixedIps ip : ips) {
671 String ipValue = ip.getIpAddress().getIpv4Address().getValue();
672 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue);
674 } catch (Exception ex) {
675 LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
677 if (routerId != null) {
678 removeFromNeutronRouterInterfacesMap(routerId, infName);
680 if (!wrtConfigTxnPresent) {
681 wrtConfigTxn.submit();
685 protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean isBeingAssociated) {
686 if (vpnId == null || port == null) {
689 boolean isLockAcquired = false;
690 String infName = port.getUuid().getValue();
691 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
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 List<Adjacency> adjacencyList = vpnIfBuilder.getAugmentation(Adjacencies.class).getAdjacency();
702 Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
703 while (adjacencyIter.hasNext()) {
704 Adjacency adjacency = adjacencyIter.next();
705 String mipToQuery = adjacency.getIpAddress().split("/")[0];
706 InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier
707 (oldVpnId.getValue(), mipToQuery);
708 Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker,
711 if (optionalVpnPort.isPresent() && optionalVpnPort.get().isLearnt()) {
712 LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} " +
713 "from VPN " + "{}", infName, vpnId, oldVpnId);
714 adjacencyIter.remove();
715 NeutronvpnUtils.removeVpnPortFixedIpToPort(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 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
726 List<FixedIps> ips = port.getFixedIps();
727 for (FixedIps ip : ips) {
728 String ipValue = ip.getIpAddress().getIpv4Address().getValue();
729 if (oldVpnId != null) {
730 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
732 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
733 .getMacAddress().getValue(), false, true, false);
736 LOG.error("VPN Interface {} not found", infName);
738 } catch (Exception ex) {
739 LOG.error("Updation of vpninterface {} failed due to {}", infName, ex);
741 if (isLockAcquired) {
742 NeutronvpnUtils.unlock(infName);
747 public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt,
748 List<String> ert, Uuid router, List<Uuid> networks) {
750 // Update VPN Instance node
751 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
753 // Update local vpn-subnet DS
754 updateVpnMaps(vpn, name, router, tenant, networks);
756 if (router != null) {
757 Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(dataBroker, router, true);
758 if (existingVpn != null) {
759 // use case when a cluster is rebooted and router add DCN is received, triggering #createL3InternalVpn
761 // if before reboot, router was already associated to VPN, should not proceed associating router to
762 // internal VPN. Adding to RouterInterfacesMap is also not needed since it's a config DS and will be
763 // preserved upon reboot.
764 // For a non-reboot case #associateRouterToInternalVPN already takes care of adding to
765 // RouterInterfacesMap via #createVPNInterface call.
766 LOG.info("Associating router to Internal VPN skipped for VPN {} due to router {} already associated " +
767 "to external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
770 associateRouterToInternalVpn(vpn, router);
775 * Performs the creation of a Neutron L3VPN, associating the new VPN to the
776 * specified Neutron Networks and Routers
778 * @param vpn Uuid of the VPN tp be created
779 * @param name Representative name of the new VPN
780 * @param tenant Uuid of the Tenant under which the VPN is going to be created
781 * @param rd Route-distinguisher for the VPN
782 * @param irt A list of Import Route Targets
783 * @param ert A list of Export Route Targets
784 * @param router UUID of the neutron router the VPN may be associated to
785 * @param networks UUID of the neutron network the VPN may be associated to
786 * @throws Exception if association of L3VPN failed
788 public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
789 Uuid router, List<Uuid> networks) throws Exception {
791 // Update VPN Instance node
792 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
794 // Please note that router and networks will be filled into VPNMaps
795 // by subsequent calls here to associateRouterToVpn and
796 // associateNetworksToVpn
797 updateVpnMaps(vpn, name, null, tenant, null);
799 if (router != null) {
800 associateRouterToVpn(vpn, router);
802 if (networks != null) {
803 List<String> failStrings = associateNetworksToVpn(vpn, networks);
804 if (failStrings != null && !failStrings.isEmpty()) {
805 LOG.error("L3VPN {} association to networks failed with error message {}. ",
806 vpn.getValue(), failStrings.get(0));
807 throw new Exception(failStrings.get(0));
813 * It handles the invocations to the createL3VPN RPC method
815 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#createL3VPN
816 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput)
819 public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
821 CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
822 SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
823 List<RpcError> errorList = new ArrayList<>();
824 int failurecount = 0;
825 int warningcount = 0;
827 List<L3vpn> vpns = input.getL3vpn();
828 for (L3vpn vpn : vpns) {
829 RpcError error = null;
831 if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
832 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
833 vpn.getId().getValue());
835 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
836 errorList.add(error);
840 if (vpn.getRouteDistinguisher().size() > 1) {
841 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
842 vpn.getId().getValue(), vpn.getRouteDistinguisher());
844 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
845 errorList.add(error);
849 if (vpn.getRouterId() != null) {
850 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
851 msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
852 vpn.getId().getValue(), vpn.getRouterId().getValue());
854 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
855 errorList.add(error);
859 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
861 msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
862 + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
865 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
866 errorList.add(error);
871 if (vpn.getNetworkIds() != null) {
872 for (Uuid nw : vpn.getNetworkIds()) {
873 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
874 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
875 if (network == null) {
876 msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
877 vpn.getId().getValue(), nw.getValue());
879 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
880 errorList.add(error);
882 } else if (vpnId != null) {
883 msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
884 + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
887 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
888 errorList.add(error);
897 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
898 vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
899 } catch (Exception ex) {
900 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
902 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
903 errorList.add(error);
907 // if at least one succeeds; result is success
908 // if none succeeds; result is failure
909 if (failurecount + warningcount == vpns.size()) {
910 result.set(RpcResultBuilder.<CreateL3VPNOutput> failed().withRpcErrors(errorList).build());
912 List<String> errorResponseList = new ArrayList<>();
913 if (!errorList.isEmpty()) {
914 for (RpcError rpcError : errorList) {
915 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
916 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
917 errorResponseList.add(errorResponse);
920 errorResponseList.add("Operation successful with no errors");
922 opBuilder.setResponse(errorResponseList);
923 result.set(RpcResultBuilder.<CreateL3VPNOutput> success().withResult(opBuilder.build()).build());
929 * It handles the invocations to the neutronvpn:getL3VPN RPC method
931 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getL3VPN
932 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput)
935 public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
937 GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
938 SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
939 Uuid inputVpnId = input.getId();
940 List<VpnInstance> vpns = new ArrayList<>();
943 if (inputVpnId == null) {
945 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
947 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker,
948 LogicalDatastoreType.CONFIGURATION,
950 if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
951 for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
952 // eliminating internal VPNs from getL3VPN output
953 if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
959 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL, "", "No VPN " +
960 "is present").build());
964 String name = inputVpnId.getValue();
965 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
966 .child(VpnInstance.class,
967 new VpnInstanceKey(name))
969 // read VpnInstance Info
970 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
972 if (optionalVpn.isPresent()) {
973 vpns.add(optionalVpn.get());
975 String message = String.format("GetL3VPN failed because VPN %s is not present", name);
977 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
978 "invalid-value", message).build());
981 List<L3vpnInstances> l3vpnList = new ArrayList<>();
982 for (VpnInstance vpnInstance : vpns) {
983 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
985 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
986 .class, new VpnMapKey(vpnId)).build();
987 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
989 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
990 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
992 List<String> ertList = new ArrayList<>();
993 List<String> irtList = new ArrayList<>();
995 for (VpnTarget vpnTarget : vpnTargetList) {
996 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
997 ertList.add(vpnTarget.getVrfRTValue());
999 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
1000 irtList.add(vpnTarget.getVrfRTValue());
1002 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
1003 ertList.add(vpnTarget.getVrfRTValue());
1004 irtList.add(vpnTarget.getVrfRTValue());
1008 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1009 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1011 if (optionalVpnMap.isPresent()) {
1012 VpnMap vpnMap = optionalVpnMap.get();
1013 l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1014 .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1016 l3vpnList.add(l3vpn.build());
1019 opBuilder.setL3vpnInstances(l3vpnList);
1020 result.set(RpcResultBuilder.<GetL3VPNOutput> success().withResult(opBuilder.build()).build());
1022 } catch (Exception ex) {
1023 String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
1024 LOG.error(message, ex);
1025 result.set(RpcResultBuilder.<GetL3VPNOutput> failed().withError(ErrorType.APPLICATION, message).build());
1031 * It handles the invocations to the neutronvpn:deleteL3VPN RPC method
1033 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#deleteL3VPN
1034 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput)
1037 public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1039 DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1040 SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1041 List<RpcError> errorList = new ArrayList<>();
1043 int failurecount = 0;
1044 int warningcount = 0;
1045 List<Uuid> vpns = input.getId();
1046 for (Uuid vpn : vpns) {
1050 InstanceIdentifier<VpnInstance> vpnIdentifier =
1051 InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey
1052 (vpn.getValue())).build();
1053 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1054 .CONFIGURATION, vpnIdentifier);
1055 if (optionalVpn.isPresent()) {
1058 msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1060 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1061 errorList.add(error);
1064 } catch (Exception ex) {
1065 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1067 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1068 errorList.add(error);
1072 // if at least one succeeds; result is success
1073 // if none succeeds; result is failure
1074 if (failurecount + warningcount == vpns.size()) {
1075 result.set(RpcResultBuilder.<DeleteL3VPNOutput> failed().withRpcErrors(errorList).build());
1077 List<String> errorResponseList = new ArrayList<>();
1078 if (!errorList.isEmpty()) {
1079 for (RpcError rpcError : errorList) {
1080 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1081 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1082 errorResponseList.add(errorResponse);
1085 errorResponseList.add("Operation successful with no errors");
1087 opBuilder.setResponse(errorResponseList);
1088 result.set(RpcResultBuilder.<DeleteL3VPNOutput> success().withResult(opBuilder.build()).build());
1093 protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
1094 LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1095 Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1096 boolean isLockAcquired = false;
1097 String lockName = vpnId.getValue() + subnet.getValue();
1098 String elanInstanceName = sn.getNetworkId().getValue();
1099 InstanceIdentifier<ElanInstance> elanIdentifierId =
1100 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
1101 new ElanInstanceKey(elanInstanceName)).build();
1102 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1104 long elanTag = elanInstance.get().getElanTag();
1105 final Uuid routerId = (sn != null) ? sn.getRouterId() : null;
1106 isExternalVpn = vpnId.equals(routerId) ? false : true;
1108 isLockAcquired = NeutronvpnUtils.lock(lockName);
1109 checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
1110 LOG.debug("Subnet added to Vpn notification sent");
1111 } catch (Exception e) {
1112 LOG.error("Subnet added to Vpn notification failed", e);
1114 if (isLockAcquired) {
1115 NeutronvpnUtils.unlock(lockName);
1118 // Check if there are ports on this subnet and add corresponding
1120 List<Uuid> portList = sn.getPortList();
1121 if (portList != null) {
1122 for (final Uuid portId : sn.getPortList()) {
1123 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1124 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1125 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), new Callable<List<ListenableFuture<Void>>>() {
1127 public List<ListenableFuture<Void>> call() throws Exception {
1128 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1129 List<ListenableFuture<Void>> futures = new ArrayList<>();
1130 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1132 futures.add(wrtConfigTxn.submit());
1140 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1141 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1142 // Read the subnet first to see if its already associated to a VPN
1143 Uuid oldVpnId = null;
1144 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class).
1145 child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1146 Subnetmap sn = null;
1147 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1148 if (optSn.isPresent()) {
1150 oldVpnId = sn.getVpnId();
1151 List<String> ips = sn.getRouterInterfaceFixedIps();
1152 for (String ipValue : ips) {
1153 if (oldVpnId != null) {
1154 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
1156 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, sn
1157 .getRouterInterfaceName().getValue(), sn.getRouterIntfMacAddress(), true, true, false);
1160 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1161 boolean isLockAcquired = false;
1162 String lockName = vpnId.getValue() + subnet.getValue();
1163 String elanInstanceName = sn.getNetworkId().getValue();
1164 InstanceIdentifier<ElanInstance> elanIdentifierId =
1165 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
1166 new ElanInstanceKey(elanInstanceName)).build();
1167 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1169 long elanTag = elanInstance.get().getElanTag();
1171 isLockAcquired = NeutronvpnUtils.lock(lockName);
1172 checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
1174 LOG.debug("Subnet updated in Vpn notification sent");
1175 } catch (Exception e) {
1176 LOG.error("Subnet updated in Vpn notification failed", e);
1178 if (isLockAcquired) {
1179 NeutronvpnUtils.unlock(lockName);
1182 // Check for ports on this subnet and update association of
1183 // corresponding vpn-interfaces to external vpn
1184 List<Uuid> portList = sn.getPortList();
1185 if (portList != null) {
1186 for (Uuid port : sn.getPortList()) {
1187 LOG.debug("Updating vpn-interface for port {}", port.getValue());
1188 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port), isBeingAssociated);
1193 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1194 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1195 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1198 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1199 synchronized (routerId.getValue().intern()) {
1200 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1201 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1202 .CONFIGURATION, routerInterfacesId);
1203 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1204 (interfaceName).build();
1205 if (optRouterInterfaces.isPresent()) {
1206 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1207 .class, new InterfacesKey(interfaceName)), routerInterface);
1209 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1210 List<Interfaces> interfaces = new ArrayList<>();
1211 interfaces.add(routerInterface);
1212 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1213 .class, new InterfacesKey(interfaceName)), routerInterface);
1218 protected void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1219 synchronized (routerId.getValue().intern()) {
1220 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1221 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1222 .CONFIGURATION, routerInterfacesId);
1223 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1224 (interfaceName).build();
1225 if (optRouterInterfaces.isPresent()) {
1226 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1227 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1228 if (interfaces != null && interfaces.remove(routerInterface)) {
1229 if (interfaces.isEmpty()) {
1230 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1232 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1233 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1241 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1242 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1243 * route will be ignored.
1245 * @param vpnName the VPN identifier
1246 * @param interVpnLinkRoutes The list of static routes
1247 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1249 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1250 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1251 for ( Routes route : interVpnLinkRoutes ) {
1252 String nexthop = String.valueOf(route.getNexthop().getValue());
1253 String destination = String.valueOf(route.getDestination().getValue());
1254 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1255 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1256 AddStaticRouteInput rpcInput =
1257 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1258 .setVpnInstanceName(vpnName.getValue())
1260 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1261 RpcResult<AddStaticRouteOutput> rpcResult;
1263 rpcResult = labelOuputFtr.get();
1264 if ( rpcResult.isSuccessful() ) {
1265 LOG.debug("Label generated for destination {} is: {}",
1266 destination, rpcResult.getResult().getLabel());
1268 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1269 destination, nexthop, rpcResult.getErrors());
1271 } catch (InterruptedException | ExecutionException e) {
1272 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1275 // Any other case is a fault.
1276 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1277 String.valueOf(route.getDestination().getValue()), nexthop );
1284 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1285 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1287 * @param vpnName the VPN identifier
1288 * @param interVpnLinkRoutes The list of static routes
1289 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1291 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1292 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1293 for ( Routes route : interVpnLinkRoutes ) {
1294 String nexthop = String.valueOf(route.getNexthop().getValue());
1295 String destination = String.valueOf(route.getDestination().getValue());
1296 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1297 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1298 RemoveStaticRouteInput rpcInput =
1299 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1300 .setVpnInstanceName(vpnName.getValue())
1302 vpnRpcService.removeStaticRoute(rpcInput);
1304 // Any other case is a fault.
1305 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1306 String.valueOf(route.getDestination().getValue()), nexthop );
1313 * Returns true if the specified nexthop is the other endpoint in an
1314 * InterVpnLink, regarding one of the VPN's point of view.
1316 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1318 interVpnLink != null
1319 && ( (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1320 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1321 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1322 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1325 protected List<Adjacency> addAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1326 List<Adjacency> adjList = new ArrayList<>();
1327 Map<String, List<String>> adjMap = new HashMap<>();
1328 for (Routes route : routeList) {
1329 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1330 LOG.error("Incorrect input received for extra route. {}", route);
1332 String nextHop = String.valueOf(route.getNexthop().getValue());
1333 String destination = String.valueOf(route.getDestination().getValue());
1334 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1336 if (infName == null) {
1337 LOG.error("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} " +
1338 "with nexthop {}", destination, vpnId.getValue(), nextHop);
1339 // Proceed to process the next extra-route
1342 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} and infName {}", destination,
1343 vpnId.getValue(), nextHop, infName);
1344 List<String> hops = adjMap.get(destination);
1346 hops = new ArrayList<>();
1347 adjMap.put(destination, hops);
1349 if (! hops.contains(nextHop)) {
1355 for (String destination : adjMap.keySet()) {
1356 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(adjMap.get
1357 (destination)).setKey(new AdjacencyKey(destination)).build();
1361 for (Adjacency adj : adjList) {
1362 for(String nextHop : adj.getNextHopIpList()) {
1363 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1365 if (infName != null) {
1366 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
1367 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1368 boolean isLockAcquired = false;
1370 Optional<VpnInterface> optionalVpnInterface =
1371 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
1372 if (optionalVpnInterface.isPresent()) {
1373 Adjacency newAdj = new AdjacencyBuilder(adj).setNextHopIpList(Arrays.asList(nextHop))
1375 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1376 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1377 .addAugmentation(Adjacencies.class, erAdjs).build();
1378 isLockAcquired = NeutronvpnUtils.lock(infName);
1379 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1381 LOG.error("VM adjacency for interface {} not present; cannot add extra route adjacency",
1384 } catch (Exception e) {
1385 LOG.error("exception in adding extra route with destination: {}, next hop: {}", adj
1386 .getIpAddress(), nextHop, e);
1388 if (isLockAcquired) {
1389 NeutronvpnUtils.unlock(infName);
1393 LOG.warn("Could not find suitable Interface for {}", nextHop);
1401 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1402 for (Routes route : routeList) {
1403 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1404 boolean isLockAcquired = false;
1405 String nextHop = String.valueOf(route.getNexthop().getValue());
1406 String destination = String.valueOf(route.getDestination().getValue());
1407 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1409 if (infName == null) {
1410 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} " +
1412 destination, vpnId.getValue(), nextHop);
1413 // Proceed to remove the next extra-route
1416 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1417 destination, vpnId.getValue(), nextHop, infName);
1419 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1420 InstanceIdentifier.builder(VpnInterfaces.class)
1421 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1422 .augmentation(Adjacencies.class)
1423 .child(Adjacency.class, new AdjacencyKey(destination))
1426 // Looking for existing prefix in MDSAL database
1427 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1428 adjacencyIdentifier);
1429 boolean updateNextHops = false;
1430 List<String> nextHopList = new ArrayList<>();
1431 if (adjacency.isPresent()) {
1432 List<String> nhListRead = adjacency.get().getNextHopIpList();
1433 if (nhListRead.size() > 1) { // ECMP case
1434 for (String nextHopRead : nhListRead) {
1435 if (nextHopRead.equals(nextHop)) {
1436 updateNextHops = true;
1438 nextHopList.add(nextHopRead);
1445 isLockAcquired = NeutronvpnUtils.lock(infName);
1446 if (updateNextHops) {
1447 // An update must be done, not including the current next hop
1448 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1449 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1450 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1451 .setNextHopIpList(nextHopList)
1452 .setKey(new AdjacencyKey(destination))
1454 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1455 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1456 .addAugmentation(Adjacencies.class, erAdjs).build();
1457 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1459 // Remove the whole route
1460 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1461 LOG.trace("extra route {} deleted successfully", route);
1463 } catch (Exception e) {
1464 LOG.error("exception in deleting extra route: {}" + e);
1466 if (isLockAcquired) {
1467 NeutronvpnUtils.unlock(infName);
1471 LOG.error("Incorrect input received for extra route. {}", route);
1476 protected void removeL3Vpn(Uuid id) {
1478 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1479 Uuid router = vpnMap.getRouterId();
1480 // dissociate router
1481 if (router != null) {
1482 dissociateRouterFromVpn(id, router);
1484 // dissociate networks
1485 if (!id.equals(router)) {
1486 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1488 // remove entire vpnMaps node
1489 deleteVpnMapsNode(id);
1491 // remove vpn-instance
1492 deleteVpnInstance(id);
1495 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1496 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1497 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1498 boolean isLockAcquired = false;
1499 String lockName = vpnId.getValue() + subnet.getValue();
1500 String elanInstanceName = sn.getNetworkId().getValue();
1501 InstanceIdentifier<ElanInstance> elanIdentifierId =
1502 InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class,
1503 new ElanInstanceKey(elanInstanceName)).build();
1504 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1506 long elanTag = elanInstance.get().getElanTag();
1507 final Uuid routerId = (sn != null) ? sn.getRouterId() : null;
1508 isExternalVpn = vpnId.equals(routerId) ? false : true;
1510 isLockAcquired = NeutronvpnUtils.lock(lockName);
1511 checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn, elanTag);
1512 LOG.debug("Subnet removed from Vpn notification sent");
1513 } catch (Exception e) {
1514 LOG.error("Subnet removed from Vpn notification failed", e);
1516 if (isLockAcquired) {
1517 NeutronvpnUtils.unlock(lockName);
1521 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1522 List<Uuid> portList = sn.getPortList();
1523 if (portList != null) {
1524 for (final Uuid portId : sn.getPortList()) {
1525 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1526 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1527 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1528 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1529 List<ListenableFuture<Void>> futures = new ArrayList<>();
1530 deleteVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1532 futures.add(wrtConfigTxn.submit());
1537 // update subnet-vpn association
1538 removeFromSubnetNode(subnet, null, null, vpnId, null);
1540 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1544 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1545 updateVpnMaps(vpnId, null, routerId, null, null);
1546 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1547 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1548 if (routerSubnets != null) {
1549 for (Uuid subnetId : routerSubnets) {
1550 updateVpnForSubnet(vpnId, subnetId, true);
1554 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1555 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1557 } catch (Exception e) {
1558 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1559 .getValue(), vpnId.getValue(), e);
1563 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1564 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1565 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1566 for (Uuid subnet : routerSubnets) {
1567 addSubnetToVpn(vpnId, subnet);
1571 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1573 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1574 if (routerSubnets != null) {
1575 for (Uuid subnetId : routerSubnets) {
1576 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1577 updateVpnForSubnet(routerId, subnetId, false);
1580 clearFromVpnMaps(vpnId, routerId, null);
1582 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1583 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1585 } catch (Exception e) {
1586 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1587 .getValue(), vpnId.getValue(), e);
1591 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1592 List<String> failedNwList = new ArrayList<>();
1593 List<Uuid> passedNwList = new ArrayList<>();
1594 if (!networks.isEmpty()) {
1595 // process corresponding subnets for VPN
1596 for (Uuid nw : networks) {
1597 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1598 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1599 if (network == null) {
1600 failedNwList.add(String.format("network %s not found", nw.getValue()));
1601 } else if (vpnId != null) {
1602 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1605 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1606 LOG.debug("Adding network subnets...{}", networkSubnets);
1607 if (networkSubnets != null) {
1608 for (Uuid subnet : networkSubnets) {
1609 // check if subnet added as router interface to some router
1610 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1611 if (subnetVpnId == null) {
1612 addSubnetToVpn(vpn, subnet);
1613 passedNwList.add(nw);
1615 failedNwList.add(String.format("subnet %s already added as router interface bound to " +
1616 "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
1620 if (NeutronvpnUtils.getIsExternal(network)) {
1621 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1625 updateVpnMaps(vpn, null, null, null, passedNwList);
1627 return failedNwList;
1630 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1631 List<String> failedNwList = new ArrayList<>();
1632 List<Uuid> passedNwList = new ArrayList<>();
1633 if (networks != null && !networks.isEmpty()) {
1634 // process corresponding subnets for VPN
1635 for (Uuid nw : networks) {
1636 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1637 if (network == null) {
1638 failedNwList.add(String.format("network %s not found", nw.getValue()));
1640 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1641 if (vpn.equals(vpnId)) {
1642 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1643 LOG.debug("Removing network subnets...");
1644 if (networkSubnets != null) {
1645 for (Uuid subnet : networkSubnets) {
1646 removeSubnetFromVpn(vpn, subnet);
1647 passedNwList.add(nw);
1651 if (vpnId == null) {
1652 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1655 failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
1656 "of the one given as input", nw.getValue(), vpnId.getValue()));
1659 if (NeutronvpnUtils.getIsExternal(network)) {
1660 nvpnNatManager.removeExternalNetworkFromVpn(network);
1664 clearFromVpnMaps(vpn, null, passedNwList);
1666 return failedNwList;
1670 * It handles the invocations to the neutronvpn:associateNetworks RPC method
1672 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateNetworks
1673 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput)
1676 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1678 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1679 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1680 LOG.debug("associateNetworks {}", input);
1681 StringBuilder returnMsg = new StringBuilder();
1682 Uuid vpnId = input.getVpnId();
1685 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1686 List<Uuid> netIds = input.getNetworkId();
1687 if (netIds != null && !netIds.isEmpty()) {
1688 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1689 if (!failed.isEmpty()) {
1690 returnMsg.append(failed);
1694 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1696 if (returnMsg.length() != 0) {
1697 String message = String.format("associate Networks to vpn %s failed due to %s",
1698 vpnId.getValue(), returnMsg);
1700 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1702 opBuilder.setResponse(errorResponse);
1703 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().withResult(opBuilder.build()).build());
1705 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().build());
1707 } catch (Exception ex) {
1708 String message = String.format("associate Networks to vpn %s failed due to %s",
1709 input.getVpnId().getValue(), ex.getMessage());
1710 LOG.error(message, ex);
1711 result.set(RpcResultBuilder.<AssociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1714 LOG.debug("associateNetworks returns..");
1719 * It handles the invocations to the neutronvpn:associateRouter RPC method
1721 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateRouter
1722 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput)
1725 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1727 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1728 LOG.debug("associateRouter {}", input);
1729 StringBuilder returnMsg = new StringBuilder();
1730 Uuid vpnId = input.getVpnId();
1731 Uuid routerId = input.getRouterId();
1733 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1734 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1735 if (vpnMap != null) {
1737 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1738 if (vpnMap.getRouterId() != null) {
1739 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1740 .append(vpnMap.getRouterId().getValue());
1741 } else if (extVpnId != null) {
1742 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
1743 "another VPN ").append(extVpnId.getValue());
1745 associateRouterToVpn(vpnId, routerId);
1748 returnMsg.append("router not found : ").append(routerId.getValue());
1751 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1753 if (returnMsg.length() != 0) {
1754 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1757 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1760 result.set(RpcResultBuilder.<Void> success().build());
1762 } catch (Exception ex) {
1763 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1764 vpnId.getValue(), ex.getMessage());
1765 LOG.error(message, ex);
1766 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1768 LOG.debug("associateRouter returns..");
1772 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method
1774 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getFixedIPsForNeutronPort
1775 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput)
1778 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput input) {
1779 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1780 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1781 Uuid portId = input.getPortId();
1782 StringBuilder returnMsg = new StringBuilder();
1784 List<String> fixedIPList = new ArrayList<>();
1785 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1787 List<FixedIps> fixedIPs = port.getFixedIps();
1788 for (FixedIps ip : fixedIPs) {
1789 fixedIPList.add(ip.getIpAddress().getIpv4Address().getValue());
1792 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1794 if (returnMsg.length() != 0) {
1795 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1797 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1798 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1800 opBuilder.setFixedIPs(fixedIPList);
1801 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().withResult(opBuilder.build())
1803 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().build());
1805 } catch (Exception ex) {
1806 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1807 portId.getValue(), ex.getMessage());
1808 LOG.error(message, ex);
1809 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1810 .withError(ErrorType.APPLICATION, message).build());
1816 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method
1818 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1819 * .rev150602.NeutronvpnService#dissociateNetworks(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1820 * .neutronvpn.rev150602.DissociateNetworksInput)
1823 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1825 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1826 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1828 LOG.debug("dissociateNetworks {}", input);
1829 StringBuilder returnMsg = new StringBuilder();
1830 Uuid vpnId = input.getVpnId();
1833 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1834 List<Uuid> netIds = input.getNetworkId();
1835 if (netIds != null && !netIds.isEmpty()) {
1836 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1837 if (!failed.isEmpty()) {
1838 returnMsg.append(failed);
1842 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1844 if (returnMsg.length() != 0) {
1845 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1848 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1850 opBuilder.setResponse(errorResponse);
1851 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().withResult(opBuilder.build()).build());
1853 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().build());
1855 } catch (Exception ex) {
1856 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1857 input.getVpnId().getValue(), ex.getMessage());
1858 LOG.error(message, ex);
1859 result.set(RpcResultBuilder.<DissociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1862 LOG.debug("dissociateNetworks returns..");
1867 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1869 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1870 * .rev150602.NeutronvpnService#dissociateRouter(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1871 * .rev150602.DissociateRouterInput)
1874 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1876 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1878 LOG.debug("dissociateRouter {}", input);
1879 StringBuilder returnMsg = new StringBuilder();
1880 Uuid vpnId = input.getVpnId();
1881 Uuid routerId = input.getRouterId();
1883 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1884 if (routerId != null) {
1885 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1887 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1888 if (vpnId.equals(routerVpnId)) {
1889 dissociateRouterFromVpn(vpnId, routerId);
1891 if (routerVpnId == null) {
1892 returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
1895 returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
1896 "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
1901 returnMsg.append("router not found : ").append(routerId.getValue());
1905 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1907 if (returnMsg.length() != 0) {
1908 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1909 vpnId.getValue(), returnMsg);
1911 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1913 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1916 result.set(RpcResultBuilder.<Void> success().build());
1918 } catch (Exception ex) {
1919 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1920 vpnId.getValue(), ex.getMessage());
1921 LOG.error(message, ex);
1922 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1924 LOG.debug("dissociateRouter returns..");
1929 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1930 // check if the router is associated to some VPN
1931 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1932 if (vpnId != null) {
1933 // remove existing external vpn interfaces
1934 for (Uuid subnetId : routerSubnetIds) {
1935 removeSubnetFromVpn(vpnId, subnetId);
1937 clearFromVpnMaps(vpnId, routerId, null);
1939 // remove existing internal vpn interfaces
1940 for (Uuid subnetId : routerSubnetIds) {
1941 removeSubnetFromVpn(routerId, subnetId);
1944 // delete entire vpnMaps node for internal VPN
1945 deleteVpnMapsNode(routerId);
1947 // delete vpn-instance for internal VPN
1948 deleteVpnInstance(routerId);
1951 protected Subnet getNeutronSubnet(Uuid subnetId){
1952 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1955 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1956 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1958 return sn.getGatewayIp();
1964 protected Network getNeutronNetwork(Uuid networkId) {
1965 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1968 protected Port getNeutronPort(String name) {
1969 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1972 protected Port getNeutronPort(Uuid portId) {
1973 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1976 protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1977 List<Uuid> subnets = new ArrayList<>();
1979 InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1980 Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1982 if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1983 List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1984 for (Subnetmap subnetMap : subnetMapList) {
1985 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1986 subnets.add(subnetMap.getId());
1994 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command
1996 * @return a List of String to be printed on screen
1998 public List<String> showNeutronPortsCLI() {
1999 List<String> result = new ArrayList<>();
2000 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
2002 result.add("-------------------------------------------------------------------------------------------");
2003 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
2005 Optional<Ports> ports = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
2006 if (ports.isPresent() && ports.get().getPort() != null) {
2007 for (Port port : ports.get().getPort()) {
2008 List<FixedIps> fixedIPs = port.getFixedIps();
2010 if (fixedIPs != null && !fixedIPs.isEmpty()) {
2011 List<String> ipList = new ArrayList<>();
2012 for (FixedIps fixedIp : fixedIPs) {
2013 IpAddress ipAddress = fixedIp.getIpAddress();
2014 if (ipAddress.getIpv4Address() != null) {
2015 ipList.add(ipAddress.getIpv4Address().getValue());
2017 ipList.add((ipAddress.getIpv6Address().getValue()));
2020 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2021 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
2022 ipList.toString()));
2024 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2025 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
2027 } catch (Exception e) {
2028 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
2030 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
2031 .getValue() + ": " + e.getMessage());
2035 } catch (Exception e) {
2036 LOG.error("Failed to retrieve neutronPorts info : ", e);
2037 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2043 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command
2045 * @param vpnuuid Uuid of the VPN whose config must be shown
2046 * @return formatted output list
2048 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2049 List<String> result = new ArrayList<>();
2050 if (vpnuuid == null) {
2051 System.out.println("");
2052 System.out.println("Displaying VPN config for all VPNs");
2053 System.out.println("To display VPN config for a particular VPN, use the following syntax");
2054 System.out.println(getshowVpnConfigCLIHelp());
2057 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2058 if (rpcResult.isSuccessful()) {
2060 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2062 result.add(String.format(" %-80s ", "Import-RTs"));
2064 result.add(String.format(" %-80s ", "Export-RTs"));
2066 result.add(String.format(" %-76s ", "Subnet IDs"));
2068 result.add("------------------------------------------------------------------------------------");
2070 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
2071 for (L3vpnInstance Vpn : VpnList) {
2072 String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue()
2074 result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId,
2075 Vpn.getRouteDistinguisher()));
2077 result.add(String.format(" %-80s ", Vpn.getImportRT()));
2079 result.add(String.format(" %-80s ", Vpn.getExportRT()));
2082 Uuid vpnid = Vpn.getId();
2083 List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2084 if (!subnetList.isEmpty()) {
2085 for (Uuid subnetuuid : subnetList) {
2086 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2089 result.add(String.format(" %-76s ", "\" \""));
2092 result.add("----------------------------------------");
2096 String errortag = rpcResult.getErrors().iterator().next().getTag();
2097 if (errortag == "") {
2098 System.out.println("");
2099 System.out.println("No VPN has been configured yet");
2100 } else if (errortag == "invalid-value") {
2101 System.out.println("");
2102 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2104 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2105 System.out.println(getshowVpnConfigCLIHelp());
2108 } catch (InterruptedException | ExecutionException e) {
2109 LOG.error("error getting VPN info : ", e);
2110 System.out.println("error getting VPN info : " + e.getMessage());
2115 protected void createExternalVpnInterfaces(Uuid extNetId) {
2116 if (extNetId == null) {
2117 LOG.trace("external network is null");
2121 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2122 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2123 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2127 for (String elanInterface : extElanInterfaces) {
2128 createExternalVpnInterface(extNetId, elanInterface);
2132 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2133 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2134 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2135 LOG.trace("No external ports attached for external network {}", extNetId);
2139 for (String elanInterface : extElanInterfaces) {
2140 boolean isLockAcquired = false;
2141 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2142 .buildVpnInterfaceIdentifier(elanInterface);
2144 isLockAcquired = NeutronvpnUtils.lock(elanInterface);
2145 LOG.debug("removing vpn interface {}, vpnIfIdentifier", elanInterface, vpnIfIdentifier);
2146 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2147 } catch (Exception ex) {
2148 LOG.error("Removal of vpninterface {} failed due to {}", elanInterface, ex);
2150 if (isLockAcquired) {
2151 NeutronvpnUtils.unlock(elanInterface);
2157 private void createExternalVpnInterface(Uuid vpnId, String infName) {
2158 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, null);
2161 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2162 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2163 if (vpnId == null || infName == null) {
2164 LOG.debug("vpn id or interface is null");
2168 Boolean wrtConfigTxnPresent = true;
2169 if (wrtConfigTxn == null) {
2170 wrtConfigTxnPresent = false;
2171 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2174 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2175 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2177 .setVpnInstanceName(vpnId.getValue())
2178 .setIsRouterInterface(isRouterInterface);
2179 if (adjacencies != null) {
2180 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2182 VpnInterface vpnIf = vpnb.build();
2184 LOG.info("Creating vpn interface {}", vpnIf);
2185 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2186 } catch (Exception ex) {
2187 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2190 if (!wrtConfigTxnPresent) {
2191 wrtConfigTxn.submit();
2195 private String getshowVpnConfigCLIHelp() {
2196 StringBuilder help = new StringBuilder("Usage:");
2197 help.append("display vpn-config [-vid/--vpnid <id>]");
2198 return help.toString();
2201 private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
2202 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2203 SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
2205 LOG.info("publish notification called");
2207 builder.setSubnetId(subnetId);
2208 builder.setSubnetIp(subnetIp);
2209 builder.setVpnName(vpnName);
2210 builder.setExternalVpn(isExternalvpn);
2211 builder.setElanTag(elanTag);
2213 notificationPublishService.putNotification(builder.build());
2216 private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
2217 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2218 SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
2220 LOG.info("publish notification called");
2222 builder.setSubnetId(subnetId);
2223 builder.setSubnetIp(subnetIp);
2224 builder.setVpnName(vpnName);
2225 builder.setExternalVpn(isExternalvpn);
2226 builder.setElanTag(elanTag);
2228 notificationPublishService.putNotification(builder.build());
2231 private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
2232 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2233 SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
2235 LOG.info("publish notification called");
2237 builder.setSubnetId(subnetId);
2238 builder.setSubnetIp(subnetIp);
2239 builder.setVpnName(vpnName);
2240 builder.setExternalVpn(isExternalvpn);
2241 builder.setElanTag(elanTag);
2243 notificationPublishService.putNotification(builder.build());
2246 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2247 InterruptedException {
2248 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2249 .setVpnId(vpnId).build();
2250 LOG.info("publishing notification upon association of router to VPN");
2251 notificationPublishService.putNotification(routerAssociatedToVpn);
2254 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2255 InterruptedException {
2256 RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
2257 (routerId).setVpnId(vpnId).build();
2258 LOG.info("publishing notification upon disassociation of router from VPN");
2259 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2262 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2263 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);