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 String ipValue = String.valueOf(ip.getIpAddress().getValue());
633 String ipPrefix = (ip.getIpAddress().getIpv4Address() != null) ? ipValue + "/32" : ipValue + "/128";
634 Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
635 .setMacAddress(port.getMacAddress().getValue()).setPrimaryAdjacency(true)
636 .setSubnetId(ip.getSubnetId()).build();
638 // create extra route adjacency
639 if (rtr != null && rtr.getRoutes() != null) {
640 List<Routes> routeList = rtr.getRoutes();
641 List<Adjacency> erAdjList = getAdjacencyforExtraRoute(vpnId, routeList, ipValue);
642 if (erAdjList != null && !erAdjList.isEmpty()) {
643 adjList.addAll(erAdjList);
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 = String.valueOf(ip.getIpAddress().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, boolean isSubnetIp) {
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 Adjacencies adjs = vpnIfBuilder.getAugmentation(Adjacencies.class);
702 List<Adjacency> adjacencyList = (adjs != null) ? adjs.getAdjacency() : new ArrayList<Adjacency>();
703 Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
704 while (adjacencyIter.hasNext()) {
705 Adjacency adjacency = adjacencyIter.next();
706 String mipToQuery = adjacency.getIpAddress().split("/")[0];
707 InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier
708 (oldVpnId.getValue(), mipToQuery);
709 Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker,
712 if (!optionalVpnPort.isPresent() || optionalVpnPort.get().isLearnt()) {
713 LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} " +
714 "from VPN " + "{}", infName, vpnId, oldVpnId);
715 adjacencyIter.remove();
716 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), mipToQuery);
717 LOG.trace("Entry for fixedIP {} for port {} on VPN removed from " +
718 "VpnPortFixedIPToPortData", mipToQuery, infName, vpnId.getValue());
721 Adjacencies adjacencies = new AdjacenciesBuilder().setAdjacency(adjacencyList).build();
722 vpnIfBuilder.addAugmentation(Adjacencies.class, adjacencies);
724 List<FixedIps> ips = port.getFixedIps();
725 for (FixedIps ip : ips) {
726 String ipValue = String.valueOf(ip.getIpAddress().getValue());
727 if (oldVpnId != null) {
728 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
730 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
731 .getMacAddress().getValue(), isSubnetIp, true, false);
733 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
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 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1097 // send subnet added to vpn notification
1098 isExternalVpn = vpnId.equals(routerId) ? false : true;
1099 String elanInstanceName = sn.getNetworkId().getValue();
1100 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1101 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1103 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1104 .CONFIGURATION, elanIdentifierId);
1105 if (elanInstance.isPresent()) {
1106 long elanTag = elanInstance.get().getElanTag();
1107 checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn,
1109 LOG.debug("Subnet added to VPN notification sent for subnet {} on VPN {}", subnet.getValue(),
1112 LOG.error("Subnet added to VPN notification failed for subnet {} on VPN {} because of failure in " +
1113 "reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1115 } catch (Exception e) {
1116 LOG.error("Subnet added to VPN notification failed for subnet {} on VPN {}", subnet.getValue(), vpnId
1119 // Check if there are ports on this subnet and add corresponding
1121 List<Uuid> portList = sn.getPortList();
1122 if (portList != null) {
1123 for (final Uuid portId : sn.getPortList()) {
1124 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1125 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1126 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), new
1127 Callable<List<ListenableFuture<Void>>>() {
1129 public List<ListenableFuture<Void>> call() throws Exception {
1130 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1131 List<ListenableFuture<Void>> futures = new ArrayList<>();
1132 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1134 futures.add(wrtConfigTxn.submit());
1142 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1143 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1144 // Read the subnet first to see if its already associated to a VPN
1145 Uuid oldVpnId = null;
1146 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class).
1147 child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1148 Subnetmap sn = null;
1149 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1150 if (optSn.isPresent()) {
1152 oldVpnId = sn.getVpnId();
1153 List<String> ips = sn.getRouterInterfaceFixedIps();
1154 for (String ipValue : ips) {
1155 // Update the association of router-interface to external vpn
1156 String PortName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, oldVpnId.getValue(), ipValue);
1157 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(PortName)),
1158 isBeingAssociated, true);
1161 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1162 // send vpn updated for subnet notification
1163 String elanInstanceName = sn.getNetworkId().getValue();
1164 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1165 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1167 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1168 .CONFIGURATION, elanIdentifierId);
1169 if (elanInstance.isPresent()) {
1170 long elanTag = elanInstance.get().getElanTag();
1171 checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
1173 LOG.debug("VPN updated for subnet notification sent for subnet {} on VPN {}", subnet.getValue(),
1176 LOG.error("VPN updated for subnet notification failed for subnet {} on VPN {} because of failure " +
1177 "in reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1179 } catch (Exception e) {
1180 LOG.error("VPN updated for subnet notification failed for subnet {} on VPN {}", subnet.getValue(),
1181 vpnId.getValue(), e);
1183 // Check for ports on this subnet and update association of
1184 // corresponding vpn-interfaces to external vpn
1185 List<Uuid> portList = sn.getPortList();
1186 if (portList != null) {
1187 for (Uuid port : sn.getPortList()) {
1188 LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}", port.getValue(), isBeingAssociated);
1189 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port),
1190 isBeingAssociated, false);
1195 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1196 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1197 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1200 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1201 synchronized (routerId.getValue().intern()) {
1202 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1203 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1204 .CONFIGURATION, routerInterfacesId);
1205 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1206 (interfaceName).build();
1207 if (optRouterInterfaces.isPresent()) {
1208 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1209 .class, new InterfacesKey(interfaceName)), routerInterface);
1211 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1212 List<Interfaces> interfaces = new ArrayList<>();
1213 interfaces.add(routerInterface);
1214 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1215 .class, new InterfacesKey(interfaceName)), routerInterface);
1220 protected void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1221 synchronized (routerId.getValue().intern()) {
1222 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1223 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1224 .CONFIGURATION, routerInterfacesId);
1225 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1226 (interfaceName).build();
1227 if (optRouterInterfaces.isPresent()) {
1228 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1229 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1230 if (interfaces != null && interfaces.remove(routerInterface)) {
1231 if (interfaces.isEmpty()) {
1232 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1234 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1235 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1243 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1244 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1245 * route will be ignored.
1247 * @param vpnName the VPN identifier
1248 * @param interVpnLinkRoutes The list of static routes
1249 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1251 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1252 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1253 for ( Routes route : interVpnLinkRoutes ) {
1254 String nexthop = String.valueOf(route.getNexthop().getValue());
1255 String destination = String.valueOf(route.getDestination().getValue());
1256 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1257 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1258 AddStaticRouteInput rpcInput =
1259 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1260 .setVpnInstanceName(vpnName.getValue())
1262 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1263 RpcResult<AddStaticRouteOutput> rpcResult;
1265 rpcResult = labelOuputFtr.get();
1266 if ( rpcResult.isSuccessful() ) {
1267 LOG.debug("Label generated for destination {} is: {}",
1268 destination, rpcResult.getResult().getLabel());
1270 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1271 destination, nexthop, rpcResult.getErrors());
1273 } catch (InterruptedException | ExecutionException e) {
1274 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1277 // Any other case is a fault.
1278 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1279 String.valueOf(route.getDestination().getValue()), nexthop );
1286 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1287 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1289 * @param vpnName the VPN identifier
1290 * @param interVpnLinkRoutes The list of static routes
1291 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1293 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1294 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1295 for ( Routes route : interVpnLinkRoutes ) {
1296 String nexthop = String.valueOf(route.getNexthop().getValue());
1297 String destination = String.valueOf(route.getDestination().getValue());
1298 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1299 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1300 RemoveStaticRouteInput rpcInput =
1301 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1302 .setVpnInstanceName(vpnName.getValue())
1304 vpnRpcService.removeStaticRoute(rpcInput);
1306 // Any other case is a fault.
1307 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1308 String.valueOf(route.getDestination().getValue()), nexthop );
1315 * Returns true if the specified nexthop is the other endpoint in an
1316 * InterVpnLink, regarding one of the VPN's point of view.
1318 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1320 interVpnLink != null
1321 && ( (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1322 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1323 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1324 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1327 protected List<Adjacency> getAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList, String fixedIp) {
1328 List<Adjacency> adjList = new ArrayList<>();
1329 Map<String, List<String>> adjMap = new HashMap<>();
1330 for (Routes route : routeList) {
1331 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1332 LOG.error("Incorrect input received for extra route. {}", route);
1334 String nextHop = String.valueOf(route.getNexthop().getValue());
1335 String destination = String.valueOf(route.getDestination().getValue());
1336 if (!nextHop.equals(fixedIp)) {
1337 LOG.trace("FixedIP {} is not extra route nexthop for destination {}", fixedIp, destination);
1340 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} ", destination,
1341 vpnId.getValue(), nextHop);
1342 List<String> hops = adjMap.get(destination);
1344 hops = new ArrayList<>();
1345 adjMap.put(destination, hops);
1347 if (!hops.contains(nextHop)) {
1353 for (String destination : adjMap.keySet()) {
1354 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(adjMap.get
1355 (destination)).setKey(new AdjacencyKey(destination)).build();
1361 protected void updateVpnInterfaceWithExtraRouteAdjacency(Uuid vpnId, List<Routes> routeList) {
1362 for (Routes route : routeList) {
1363 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1364 LOG.error("Incorrect input received for extra route. {}", route);
1366 String nextHop = String.valueOf(route.getNexthop().getValue());
1367 String destination = String.valueOf(route.getDestination().getValue());
1368 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1370 if (infName != null) {
1371 LOG.trace("Updating extra route for destination {} onto vpn {} with nexthop {} and infName {}", destination,
1372 vpnId.getValue(), nextHop, infName);
1373 boolean isLockAcquired = false;
1375 InstanceIdentifier<VpnInterface> identifier = InstanceIdentifier.builder(VpnInterfaces.class)
1376 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1377 InstanceIdentifier<Adjacency> path = identifier.augmentation(Adjacencies.class).
1378 child(Adjacency.class, new AdjacencyKey(destination));
1379 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(Arrays.asList(nextHop)).
1380 setKey(new AdjacencyKey(destination)).build();
1381 isLockAcquired = NeutronvpnUtils.lock(infName);
1382 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, erAdj);
1383 } catch (Exception e) {
1384 LOG.error("exception in adding extra route with destination: {}, next hop: {}", destination, nextHop, e);
1386 if (isLockAcquired) {
1387 NeutronvpnUtils.unlock(infName);
1391 LOG.debug("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} " +
1392 "with nexthop {}", destination, vpnId.getValue(), nextHop);
1398 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1399 for (Routes route : routeList) {
1400 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1401 boolean isLockAcquired = false;
1402 String nextHop = String.valueOf(route.getNexthop().getValue());
1403 String destination = String.valueOf(route.getDestination().getValue());
1404 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1406 if (infName == null) {
1407 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} " +
1409 destination, vpnId.getValue(), nextHop);
1410 // Proceed to remove the next extra-route
1413 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1414 destination, vpnId.getValue(), nextHop, infName);
1416 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1417 InstanceIdentifier.builder(VpnInterfaces.class)
1418 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1419 .augmentation(Adjacencies.class)
1420 .child(Adjacency.class, new AdjacencyKey(destination))
1423 // Looking for existing prefix in MDSAL database
1424 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1425 adjacencyIdentifier);
1426 boolean updateNextHops = false;
1427 List<String> nextHopList = new ArrayList<>();
1428 if (adjacency.isPresent()) {
1429 List<String> nhListRead = adjacency.get().getNextHopIpList();
1430 if (nhListRead.size() > 1) { // ECMP case
1431 for (String nextHopRead : nhListRead) {
1432 if (nextHopRead.equals(nextHop)) {
1433 updateNextHops = true;
1435 nextHopList.add(nextHopRead);
1442 isLockAcquired = NeutronvpnUtils.lock(infName);
1443 if (updateNextHops) {
1444 // An update must be done, not including the current next hop
1445 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1446 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1447 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1448 .setNextHopIpList(nextHopList)
1449 .setKey(new AdjacencyKey(destination))
1451 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1452 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1453 .addAugmentation(Adjacencies.class, erAdjs).build();
1454 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1456 // Remove the whole route
1457 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1458 LOG.trace("extra route {} deleted successfully", route);
1460 } catch (Exception e) {
1461 LOG.error("exception in deleting extra route: {}" + e);
1463 if (isLockAcquired) {
1464 NeutronvpnUtils.unlock(infName);
1468 LOG.error("Incorrect input received for extra route. {}", route);
1473 protected void removeL3Vpn(Uuid id) {
1475 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1476 Uuid router = vpnMap.getRouterId();
1477 // dissociate router
1478 if (router != null) {
1479 dissociateRouterFromVpn(id, router);
1481 // dissociate networks
1482 if (!id.equals(router)) {
1483 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1485 // remove entire vpnMaps node
1486 deleteVpnMapsNode(id);
1488 // remove vpn-instance
1489 deleteVpnInstance(id);
1492 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1493 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1494 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1495 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1496 // send subnet removed from vpn notification
1497 isExternalVpn = vpnId.equals(routerId) ? false : true;
1498 String elanInstanceName = sn.getNetworkId().getValue();
1499 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1500 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1502 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1503 .CONFIGURATION, elanIdentifierId);
1504 if (elanInstance.isPresent()) {
1505 long elanTag = elanInstance.get().getElanTag();
1506 checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn,
1508 LOG.debug("Subnet removed from VPN notification sent for subnet {} on VPN {}", subnet.getValue(),
1511 LOG.error("Subnet removed from VPN notification failed for subnet {} on VPN {} because of failure " +
1512 "in reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1514 } catch (Exception e) {
1515 LOG.error("Subnet removed from VPN notification failed for subnet {} on VPN {}", subnet.getValue(),
1516 vpnId.getValue(), e);
1519 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1520 List<Uuid> portList = sn.getPortList();
1521 if (portList != null) {
1522 for (final Uuid portId : sn.getPortList()) {
1523 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1524 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1525 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1526 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1527 List<ListenableFuture<Void>> futures = new ArrayList<>();
1528 deleteVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1530 futures.add(wrtConfigTxn.submit());
1535 // update subnet-vpn association
1536 removeFromSubnetNode(subnet, null, null, vpnId, null);
1538 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1542 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1543 updateVpnMaps(vpnId, null, routerId, null, null);
1544 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1545 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1546 if (routerSubnets != null) {
1547 for (Uuid subnetId : routerSubnets) {
1548 updateVpnForSubnet(vpnId, subnetId, true);
1552 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1553 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1555 } catch (Exception e) {
1556 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1557 .getValue(), vpnId.getValue(), e);
1561 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1562 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1563 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1564 for (Uuid subnet : routerSubnets) {
1565 addSubnetToVpn(vpnId, subnet);
1569 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1571 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1572 if (routerSubnets != null) {
1573 for (Uuid subnetId : routerSubnets) {
1574 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1575 updateVpnForSubnet(routerId, subnetId, false);
1578 clearFromVpnMaps(vpnId, routerId, null);
1580 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1581 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1583 } catch (Exception e) {
1584 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1585 .getValue(), vpnId.getValue(), e);
1589 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1590 List<String> failedNwList = new ArrayList<>();
1591 List<Uuid> passedNwList = new ArrayList<>();
1592 if (!networks.isEmpty()) {
1593 // process corresponding subnets for VPN
1594 for (Uuid nw : networks) {
1595 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1596 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1597 if (network == null) {
1598 failedNwList.add(String.format("network %s not found", nw.getValue()));
1599 } else if (vpnId != null) {
1600 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1603 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1604 LOG.debug("Adding network subnets...{}", networkSubnets);
1605 if (networkSubnets != null) {
1606 for (Uuid subnet : networkSubnets) {
1607 // check if subnet added as router interface to some router
1608 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1609 if (subnetVpnId == null) {
1610 addSubnetToVpn(vpn, subnet);
1611 passedNwList.add(nw);
1613 failedNwList.add(String.format("subnet %s already added as router interface bound to " +
1614 "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
1618 if (NeutronvpnUtils.getIsExternal(network)) {
1619 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1623 updateVpnMaps(vpn, null, null, null, passedNwList);
1625 return failedNwList;
1628 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1629 List<String> failedNwList = new ArrayList<>();
1630 List<Uuid> passedNwList = new ArrayList<>();
1631 if (networks != null && !networks.isEmpty()) {
1632 // process corresponding subnets for VPN
1633 for (Uuid nw : networks) {
1634 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1635 if (network == null) {
1636 failedNwList.add(String.format("network %s not found", nw.getValue()));
1638 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1639 if (vpn.equals(vpnId)) {
1640 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1641 LOG.debug("Removing network subnets...");
1642 if (networkSubnets != null) {
1643 for (Uuid subnet : networkSubnets) {
1644 removeSubnetFromVpn(vpn, subnet);
1645 passedNwList.add(nw);
1649 if (vpnId == null) {
1650 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1653 failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
1654 "of the one given as input", nw.getValue(), vpnId.getValue()));
1657 if (NeutronvpnUtils.getIsExternal(network)) {
1658 nvpnNatManager.removeExternalNetworkFromVpn(network);
1662 clearFromVpnMaps(vpn, null, passedNwList);
1664 return failedNwList;
1668 * It handles the invocations to the neutronvpn:associateNetworks RPC method
1670 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateNetworks
1671 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput)
1674 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1676 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1677 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1678 LOG.debug("associateNetworks {}", input);
1679 StringBuilder returnMsg = new StringBuilder();
1680 Uuid vpnId = input.getVpnId();
1683 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1684 List<Uuid> netIds = input.getNetworkId();
1685 if (netIds != null && !netIds.isEmpty()) {
1686 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1687 if (!failed.isEmpty()) {
1688 returnMsg.append(failed);
1692 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1694 if (returnMsg.length() != 0) {
1695 String message = String.format("associate Networks to vpn %s failed due to %s",
1696 vpnId.getValue(), returnMsg);
1698 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1700 opBuilder.setResponse(errorResponse);
1701 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().withResult(opBuilder.build()).build());
1703 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().build());
1705 } catch (Exception ex) {
1706 String message = String.format("associate Networks to vpn %s failed due to %s",
1707 input.getVpnId().getValue(), ex.getMessage());
1708 LOG.error(message, ex);
1709 result.set(RpcResultBuilder.<AssociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1712 LOG.debug("associateNetworks returns..");
1717 * It handles the invocations to the neutronvpn:associateRouter RPC method
1719 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateRouter
1720 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput)
1723 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1725 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1726 LOG.debug("associateRouter {}", input);
1727 StringBuilder returnMsg = new StringBuilder();
1728 Uuid vpnId = input.getVpnId();
1729 Uuid routerId = input.getRouterId();
1731 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1732 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1733 if (vpnMap != null) {
1735 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1736 if (vpnMap.getRouterId() != null) {
1737 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1738 .append(vpnMap.getRouterId().getValue());
1739 } else if (extVpnId != null) {
1740 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
1741 "another VPN ").append(extVpnId.getValue());
1743 associateRouterToVpn(vpnId, routerId);
1746 returnMsg.append("router not found : ").append(routerId.getValue());
1749 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1751 if (returnMsg.length() != 0) {
1752 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1755 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1758 result.set(RpcResultBuilder.<Void> success().build());
1760 } catch (Exception ex) {
1761 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1762 vpnId.getValue(), ex.getMessage());
1763 LOG.error(message, ex);
1764 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1766 LOG.debug("associateRouter returns..");
1770 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method
1772 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getFixedIPsForNeutronPort
1773 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput)
1776 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput input) {
1777 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1778 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1779 Uuid portId = input.getPortId();
1780 StringBuilder returnMsg = new StringBuilder();
1782 List<String> fixedIPList = new ArrayList<>();
1783 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1785 List<FixedIps> fixedIPs = port.getFixedIps();
1786 for (FixedIps ip : fixedIPs) {
1787 fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
1790 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1792 if (returnMsg.length() != 0) {
1793 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1795 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1796 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1798 opBuilder.setFixedIPs(fixedIPList);
1799 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().withResult(opBuilder.build())
1801 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().build());
1803 } catch (Exception ex) {
1804 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1805 portId.getValue(), ex.getMessage());
1806 LOG.error(message, ex);
1807 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1808 .withError(ErrorType.APPLICATION, message).build());
1814 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method
1816 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1817 * .rev150602.NeutronvpnService#dissociateNetworks(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1818 * .neutronvpn.rev150602.DissociateNetworksInput)
1821 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1823 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1824 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1826 LOG.debug("dissociateNetworks {}", input);
1827 StringBuilder returnMsg = new StringBuilder();
1828 Uuid vpnId = input.getVpnId();
1831 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1832 List<Uuid> netIds = input.getNetworkId();
1833 if (netIds != null && !netIds.isEmpty()) {
1834 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1835 if (!failed.isEmpty()) {
1836 returnMsg.append(failed);
1840 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1842 if (returnMsg.length() != 0) {
1843 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1846 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1848 opBuilder.setResponse(errorResponse);
1849 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().withResult(opBuilder.build()).build());
1851 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().build());
1853 } catch (Exception ex) {
1854 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1855 input.getVpnId().getValue(), ex.getMessage());
1856 LOG.error(message, ex);
1857 result.set(RpcResultBuilder.<DissociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1860 LOG.debug("dissociateNetworks returns..");
1865 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1867 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1868 * .rev150602.NeutronvpnService#dissociateRouter(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1869 * .rev150602.DissociateRouterInput)
1872 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1874 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1876 LOG.debug("dissociateRouter {}", input);
1877 StringBuilder returnMsg = new StringBuilder();
1878 Uuid vpnId = input.getVpnId();
1879 Uuid routerId = input.getRouterId();
1881 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1882 if (routerId != null) {
1883 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1885 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1886 if (vpnId.equals(routerVpnId)) {
1887 dissociateRouterFromVpn(vpnId, routerId);
1889 if (routerVpnId == null) {
1890 returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
1893 returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
1894 "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
1899 returnMsg.append("router not found : ").append(routerId.getValue());
1903 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1905 if (returnMsg.length() != 0) {
1906 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1907 vpnId.getValue(), returnMsg);
1909 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1911 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1914 result.set(RpcResultBuilder.<Void> success().build());
1916 } catch (Exception ex) {
1917 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1918 vpnId.getValue(), ex.getMessage());
1919 LOG.error(message, ex);
1920 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1922 LOG.debug("dissociateRouter returns..");
1927 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1928 // check if the router is associated to some VPN
1929 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1930 if (vpnId != null) {
1931 // remove existing external vpn interfaces
1932 for (Uuid subnetId : routerSubnetIds) {
1933 removeSubnetFromVpn(vpnId, subnetId);
1935 clearFromVpnMaps(vpnId, routerId, null);
1937 // remove existing internal vpn interfaces
1938 for (Uuid subnetId : routerSubnetIds) {
1939 removeSubnetFromVpn(routerId, subnetId);
1942 // delete entire vpnMaps node for internal VPN
1943 deleteVpnMapsNode(routerId);
1945 // delete vpn-instance for internal VPN
1946 deleteVpnInstance(routerId);
1949 protected Subnet getNeutronSubnet(Uuid subnetId){
1950 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1953 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1954 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1956 return sn.getGatewayIp();
1962 protected Network getNeutronNetwork(Uuid networkId) {
1963 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1966 protected Port getNeutronPort(String name) {
1967 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1970 protected Port getNeutronPort(Uuid portId) {
1971 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1974 protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1975 List<Uuid> subnets = new ArrayList<>();
1977 InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1978 Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1980 if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1981 List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1982 for (Subnetmap subnetMap : subnetMapList) {
1983 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1984 subnets.add(subnetMap.getId());
1992 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command
1994 * @return a List of String to be printed on screen
1996 public List<String> showNeutronPortsCLI() {
1997 List<String> result = new ArrayList<>();
1998 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
2000 result.add("-------------------------------------------------------------------------------------------");
2001 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
2003 Optional<Ports> ports = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
2004 if (ports.isPresent() && ports.get().getPort() != null) {
2005 for (Port port : ports.get().getPort()) {
2006 List<FixedIps> fixedIPs = port.getFixedIps();
2008 if (fixedIPs != null && !fixedIPs.isEmpty()) {
2009 List<String> ipList = new ArrayList<>();
2010 for (FixedIps fixedIp : fixedIPs) {
2011 IpAddress ipAddress = fixedIp.getIpAddress();
2012 if (ipAddress.getIpv4Address() != null) {
2013 ipList.add(ipAddress.getIpv4Address().getValue());
2015 ipList.add((ipAddress.getIpv6Address().getValue()));
2018 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2019 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
2020 ipList.toString()));
2022 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2023 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
2025 } catch (Exception e) {
2026 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
2028 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
2029 .getValue() + ": " + e.getMessage());
2033 } catch (Exception e) {
2034 LOG.error("Failed to retrieve neutronPorts info : ", e);
2035 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2041 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command
2043 * @param vpnuuid Uuid of the VPN whose config must be shown
2044 * @return formatted output list
2046 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2047 List<String> result = new ArrayList<>();
2048 if (vpnuuid == null) {
2049 System.out.println("");
2050 System.out.println("Displaying VPN config for all VPNs");
2051 System.out.println("To display VPN config for a particular VPN, use the following syntax");
2052 System.out.println(getshowVpnConfigCLIHelp());
2055 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2056 if (rpcResult.isSuccessful()) {
2058 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2060 result.add(String.format(" %-80s ", "Import-RTs"));
2062 result.add(String.format(" %-80s ", "Export-RTs"));
2064 result.add(String.format(" %-76s ", "Subnet IDs"));
2066 result.add("------------------------------------------------------------------------------------");
2068 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
2069 for (L3vpnInstance Vpn : VpnList) {
2070 String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue()
2072 result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId,
2073 Vpn.getRouteDistinguisher()));
2075 result.add(String.format(" %-80s ", Vpn.getImportRT()));
2077 result.add(String.format(" %-80s ", Vpn.getExportRT()));
2080 Uuid vpnid = Vpn.getId();
2081 List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2082 if (!subnetList.isEmpty()) {
2083 for (Uuid subnetuuid : subnetList) {
2084 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2087 result.add(String.format(" %-76s ", "\" \""));
2090 result.add("----------------------------------------");
2094 String errortag = rpcResult.getErrors().iterator().next().getTag();
2095 if (errortag == "") {
2096 System.out.println("");
2097 System.out.println("No VPN has been configured yet");
2098 } else if (errortag == "invalid-value") {
2099 System.out.println("");
2100 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2102 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2103 System.out.println(getshowVpnConfigCLIHelp());
2106 } catch (InterruptedException | ExecutionException e) {
2107 LOG.error("error getting VPN info : ", e);
2108 System.out.println("error getting VPN info : " + e.getMessage());
2113 protected void createExternalVpnInterfaces(Uuid extNetId) {
2114 if (extNetId == null) {
2115 LOG.trace("external network is null");
2119 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2120 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2121 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2125 for (String elanInterface : extElanInterfaces) {
2126 createExternalVpnInterface(extNetId, elanInterface);
2130 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2131 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2132 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2133 LOG.trace("No external ports attached for external network {}", extNetId);
2137 for (String elanInterface : extElanInterfaces) {
2138 boolean isLockAcquired = false;
2139 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2140 .buildVpnInterfaceIdentifier(elanInterface);
2142 isLockAcquired = NeutronvpnUtils.lock(elanInterface);
2143 LOG.debug("removing vpn interface {}, vpnIfIdentifier", elanInterface, vpnIfIdentifier);
2144 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2145 } catch (Exception ex) {
2146 LOG.error("Removal of vpninterface {} failed due to {}", elanInterface, ex);
2148 if (isLockAcquired) {
2149 NeutronvpnUtils.unlock(elanInterface);
2155 private void createExternalVpnInterface(Uuid vpnId, String infName) {
2156 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, null);
2159 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2160 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2161 if (vpnId == null || infName == null) {
2162 LOG.debug("vpn id or interface is null");
2166 Boolean wrtConfigTxnPresent = true;
2167 if (wrtConfigTxn == null) {
2168 wrtConfigTxnPresent = false;
2169 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2172 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2173 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2175 .setVpnInstanceName(vpnId.getValue())
2176 .setIsRouterInterface(isRouterInterface);
2177 if (adjacencies != null) {
2178 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2180 VpnInterface vpnIf = vpnb.build();
2182 LOG.info("Creating vpn interface {}", vpnIf);
2183 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2184 } catch (Exception ex) {
2185 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2188 if (!wrtConfigTxnPresent) {
2189 wrtConfigTxn.submit();
2193 private String getshowVpnConfigCLIHelp() {
2194 StringBuilder help = new StringBuilder("Usage:");
2195 help.append("display vpn-config [-vid/--vpnid <id>]");
2196 return help.toString();
2199 private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
2200 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2201 SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
2203 LOG.info("publish notification called");
2205 builder.setSubnetId(subnetId);
2206 builder.setSubnetIp(subnetIp);
2207 builder.setVpnName(vpnName);
2208 builder.setExternalVpn(isExternalvpn);
2209 builder.setElanTag(elanTag);
2211 notificationPublishService.putNotification(builder.build());
2214 private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
2215 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2216 SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
2218 LOG.info("publish notification called");
2220 builder.setSubnetId(subnetId);
2221 builder.setSubnetIp(subnetIp);
2222 builder.setVpnName(vpnName);
2223 builder.setExternalVpn(isExternalvpn);
2224 builder.setElanTag(elanTag);
2226 notificationPublishService.putNotification(builder.build());
2229 private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
2230 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2231 SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
2233 LOG.info("publish notification called");
2235 builder.setSubnetId(subnetId);
2236 builder.setSubnetIp(subnetIp);
2237 builder.setVpnName(vpnName);
2238 builder.setExternalVpn(isExternalvpn);
2239 builder.setElanTag(elanTag);
2241 notificationPublishService.putNotification(builder.build());
2244 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2245 InterruptedException {
2246 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2247 .setVpnId(vpnId).build();
2248 LOG.info("publishing notification upon association of router to VPN");
2249 notificationPublishService.putNotification(routerAssociatedToVpn);
2252 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2253 InterruptedException {
2254 RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
2255 (routerId).setVpnId(vpnId).build();
2256 LOG.info("publishing notification upon disassociation of router from VPN");
2257 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2260 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2261 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);