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 List<String> existingRDs = NeutronvpnUtils.getExistingRDs(dataBroker);
830 RpcError error = null;
832 if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
833 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
834 vpn.getId().getValue());
836 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
837 errorList.add(error);
841 if (vpn.getRouteDistinguisher().size() > 1) {
842 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
843 vpn.getId().getValue(), vpn.getRouteDistinguisher());
845 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
846 errorList.add(error);
850 if (existingRDs.contains(vpn.getRouteDistinguisher().get(0))) {
851 msg = String.format("Creation of L3VPN failed for VPN %s as another VPN with the same RD %s is already configured",
852 vpn.getId().getValue(), vpn.getRouteDistinguisher().get(0));
854 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
855 errorList.add(error);
859 if (vpn.getRouterId() != null) {
860 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
861 msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
862 vpn.getId().getValue(), vpn.getRouterId().getValue());
864 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
865 errorList.add(error);
869 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
871 msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
872 + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
875 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
876 errorList.add(error);
881 if (vpn.getNetworkIds() != null) {
882 for (Uuid nw : vpn.getNetworkIds()) {
883 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
884 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
885 if (network == null) {
886 msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
887 vpn.getId().getValue(), nw.getValue());
889 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
890 errorList.add(error);
892 } else if (vpnId != null) {
893 msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
894 + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
897 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
898 errorList.add(error);
907 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
908 vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
909 } catch (Exception ex) {
910 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
912 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
913 errorList.add(error);
917 // if at least one succeeds; result is success
918 // if none succeeds; result is failure
919 if (failurecount + warningcount == vpns.size()) {
920 result.set(RpcResultBuilder.<CreateL3VPNOutput> failed().withRpcErrors(errorList).build());
922 List<String> errorResponseList = new ArrayList<>();
923 if (!errorList.isEmpty()) {
924 for (RpcError rpcError : errorList) {
925 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
926 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
927 errorResponseList.add(errorResponse);
930 errorResponseList.add("Operation successful with no errors");
932 opBuilder.setResponse(errorResponseList);
933 result.set(RpcResultBuilder.<CreateL3VPNOutput> success().withResult(opBuilder.build()).build());
939 * It handles the invocations to the neutronvpn:getL3VPN RPC method
941 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getL3VPN
942 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput)
945 public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
947 GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
948 SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
949 Uuid inputVpnId = input.getId();
950 List<VpnInstance> vpns = new ArrayList<>();
953 if (inputVpnId == null) {
955 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
957 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker,
958 LogicalDatastoreType.CONFIGURATION,
960 if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
961 for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
962 // eliminating internal VPNs from getL3VPN output
963 if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
969 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL, "", "No VPN " +
970 "is present").build());
974 String name = inputVpnId.getValue();
975 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
976 .child(VpnInstance.class,
977 new VpnInstanceKey(name))
979 // read VpnInstance Info
980 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
982 if (optionalVpn.isPresent()) {
983 vpns.add(optionalVpn.get());
985 String message = String.format("GetL3VPN failed because VPN %s is not present", name);
987 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
988 "invalid-value", message).build());
991 List<L3vpnInstances> l3vpnList = new ArrayList<>();
992 for (VpnInstance vpnInstance : vpns) {
993 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
995 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
996 .class, new VpnMapKey(vpnId)).build();
997 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
999 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
1000 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
1002 List<String> ertList = new ArrayList<>();
1003 List<String> irtList = new ArrayList<>();
1005 for (VpnTarget vpnTarget : vpnTargetList) {
1006 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
1007 ertList.add(vpnTarget.getVrfRTValue());
1009 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
1010 irtList.add(vpnTarget.getVrfRTValue());
1012 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
1013 ertList.add(vpnTarget.getVrfRTValue());
1014 irtList.add(vpnTarget.getVrfRTValue());
1018 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1019 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1021 if (optionalVpnMap.isPresent()) {
1022 VpnMap vpnMap = optionalVpnMap.get();
1023 l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1024 .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1026 l3vpnList.add(l3vpn.build());
1029 opBuilder.setL3vpnInstances(l3vpnList);
1030 result.set(RpcResultBuilder.<GetL3VPNOutput> success().withResult(opBuilder.build()).build());
1032 } catch (Exception ex) {
1033 String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
1034 LOG.error(message, ex);
1035 result.set(RpcResultBuilder.<GetL3VPNOutput> failed().withError(ErrorType.APPLICATION, message).build());
1041 * It handles the invocations to the neutronvpn:deleteL3VPN RPC method
1043 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#deleteL3VPN
1044 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput)
1047 public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1049 DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1050 SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1051 List<RpcError> errorList = new ArrayList<>();
1053 int failurecount = 0;
1054 int warningcount = 0;
1055 List<Uuid> vpns = input.getId();
1056 for (Uuid vpn : vpns) {
1060 InstanceIdentifier<VpnInstance> vpnIdentifier =
1061 InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey
1062 (vpn.getValue())).build();
1063 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1064 .CONFIGURATION, vpnIdentifier);
1065 if (optionalVpn.isPresent()) {
1068 msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1070 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1071 errorList.add(error);
1074 } catch (Exception ex) {
1075 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1077 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1078 errorList.add(error);
1082 // if at least one succeeds; result is success
1083 // if none succeeds; result is failure
1084 if (failurecount + warningcount == vpns.size()) {
1085 result.set(RpcResultBuilder.<DeleteL3VPNOutput> failed().withRpcErrors(errorList).build());
1087 List<String> errorResponseList = new ArrayList<>();
1088 if (!errorList.isEmpty()) {
1089 for (RpcError rpcError : errorList) {
1090 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1091 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1092 errorResponseList.add(errorResponse);
1095 errorResponseList.add("Operation successful with no errors");
1097 opBuilder.setResponse(errorResponseList);
1098 result.set(RpcResultBuilder.<DeleteL3VPNOutput> success().withResult(opBuilder.build()).build());
1103 protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
1104 LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1105 Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1106 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1107 // send subnet added to vpn notification
1108 isExternalVpn = vpnId.equals(routerId) ? false : true;
1109 String elanInstanceName = sn.getNetworkId().getValue();
1110 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1111 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1113 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1114 .CONFIGURATION, elanIdentifierId);
1115 if (elanInstance.isPresent()) {
1116 long elanTag = elanInstance.get().getElanTag();
1117 checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn,
1119 LOG.debug("Subnet added to VPN notification sent for subnet {} on VPN {}", subnet.getValue(),
1122 LOG.error("Subnet added to VPN notification failed for subnet {} on VPN {} because of failure in " +
1123 "reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1125 } catch (Exception e) {
1126 LOG.error("Subnet added to VPN notification failed for subnet {} on VPN {}", subnet.getValue(), vpnId
1129 // Check if there are ports on this subnet and add corresponding
1131 List<Uuid> portList = sn.getPortList();
1132 if (portList != null) {
1133 for (final Uuid portId : sn.getPortList()) {
1134 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1135 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1136 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), new
1137 Callable<List<ListenableFuture<Void>>>() {
1139 public List<ListenableFuture<Void>> call() throws Exception {
1140 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1141 List<ListenableFuture<Void>> futures = new ArrayList<>();
1142 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1144 futures.add(wrtConfigTxn.submit());
1152 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1153 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1154 // Read the subnet first to see if its already associated to a VPN
1155 Uuid oldVpnId = null;
1156 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class).
1157 child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1158 Subnetmap sn = null;
1159 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1160 if (optSn.isPresent()) {
1162 oldVpnId = sn.getVpnId();
1163 List<String> ips = sn.getRouterInterfaceFixedIps();
1164 for (String ipValue : ips) {
1165 // Update the association of router-interface to external vpn
1166 String PortName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, oldVpnId.getValue(), ipValue);
1167 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(PortName)),
1168 isBeingAssociated, true);
1171 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1172 // send vpn updated for subnet notification
1173 String elanInstanceName = sn.getNetworkId().getValue();
1174 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1175 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1177 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1178 .CONFIGURATION, elanIdentifierId);
1179 if (elanInstance.isPresent()) {
1180 long elanTag = elanInstance.get().getElanTag();
1181 checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
1183 LOG.debug("VPN updated for subnet notification sent for subnet {} on VPN {}", subnet.getValue(),
1186 LOG.error("VPN updated for subnet notification failed for subnet {} on VPN {} because of failure " +
1187 "in reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1189 } catch (Exception e) {
1190 LOG.error("VPN updated for subnet notification failed for subnet {} on VPN {}", subnet.getValue(),
1191 vpnId.getValue(), e);
1193 // Check for ports on this subnet and update association of
1194 // corresponding vpn-interfaces to external vpn
1195 List<Uuid> portList = sn.getPortList();
1196 if (portList != null) {
1197 for (Uuid port : sn.getPortList()) {
1198 LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}", port.getValue(), isBeingAssociated);
1199 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port),
1200 isBeingAssociated, false);
1205 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1206 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1207 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1210 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1211 synchronized (routerId.getValue().intern()) {
1212 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1213 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1214 .CONFIGURATION, routerInterfacesId);
1215 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1216 (interfaceName).build();
1217 if (optRouterInterfaces.isPresent()) {
1218 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1219 .class, new InterfacesKey(interfaceName)), routerInterface);
1221 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1222 List<Interfaces> interfaces = new ArrayList<>();
1223 interfaces.add(routerInterface);
1224 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1225 .class, new InterfacesKey(interfaceName)), routerInterface);
1230 protected void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1231 synchronized (routerId.getValue().intern()) {
1232 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1233 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1234 .CONFIGURATION, routerInterfacesId);
1235 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1236 (interfaceName).build();
1237 if (optRouterInterfaces.isPresent()) {
1238 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1239 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1240 if (interfaces != null && interfaces.remove(routerInterface)) {
1241 if (interfaces.isEmpty()) {
1242 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1244 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1245 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1253 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1254 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1255 * route will be ignored.
1257 * @param vpnName the VPN identifier
1258 * @param interVpnLinkRoutes The list of static routes
1259 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1261 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1262 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1263 for ( Routes route : interVpnLinkRoutes ) {
1264 String nexthop = String.valueOf(route.getNexthop().getValue());
1265 String destination = String.valueOf(route.getDestination().getValue());
1266 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1267 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1268 AddStaticRouteInput rpcInput =
1269 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1270 .setVpnInstanceName(vpnName.getValue())
1272 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1273 RpcResult<AddStaticRouteOutput> rpcResult;
1275 rpcResult = labelOuputFtr.get();
1276 if ( rpcResult.isSuccessful() ) {
1277 LOG.debug("Label generated for destination {} is: {}",
1278 destination, rpcResult.getResult().getLabel());
1280 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1281 destination, nexthop, rpcResult.getErrors());
1283 } catch (InterruptedException | ExecutionException e) {
1284 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1287 // Any other case is a fault.
1288 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1289 String.valueOf(route.getDestination().getValue()), nexthop );
1296 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1297 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1299 * @param vpnName the VPN identifier
1300 * @param interVpnLinkRoutes The list of static routes
1301 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1303 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1304 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1305 for ( Routes route : interVpnLinkRoutes ) {
1306 String nexthop = String.valueOf(route.getNexthop().getValue());
1307 String destination = String.valueOf(route.getDestination().getValue());
1308 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1309 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1310 RemoveStaticRouteInput rpcInput =
1311 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1312 .setVpnInstanceName(vpnName.getValue())
1314 vpnRpcService.removeStaticRoute(rpcInput);
1316 // Any other case is a fault.
1317 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1318 String.valueOf(route.getDestination().getValue()), nexthop );
1325 * Returns true if the specified nexthop is the other endpoint in an
1326 * InterVpnLink, regarding one of the VPN's point of view.
1328 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1330 interVpnLink != null
1331 && ( (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1332 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1333 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1334 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1337 protected List<Adjacency> getAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList, String fixedIp) {
1338 List<Adjacency> adjList = new ArrayList<>();
1339 Map<String, List<String>> adjMap = new HashMap<>();
1340 for (Routes route : routeList) {
1341 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1342 LOG.error("Incorrect input received for extra route. {}", route);
1344 String nextHop = String.valueOf(route.getNexthop().getValue());
1345 String destination = String.valueOf(route.getDestination().getValue());
1346 if (!nextHop.equals(fixedIp)) {
1347 LOG.trace("FixedIP {} is not extra route nexthop for destination {}", fixedIp, destination);
1350 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} ", destination,
1351 vpnId.getValue(), nextHop);
1352 List<String> hops = adjMap.get(destination);
1354 hops = new ArrayList<>();
1355 adjMap.put(destination, hops);
1357 if (!hops.contains(nextHop)) {
1363 for (String destination : adjMap.keySet()) {
1364 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(adjMap.get
1365 (destination)).setKey(new AdjacencyKey(destination)).build();
1371 protected void updateVpnInterfaceWithExtraRouteAdjacency(Uuid vpnId, List<Routes> routeList) {
1372 for (Routes route : routeList) {
1373 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1374 LOG.error("Incorrect input received for extra route. {}", route);
1376 String nextHop = String.valueOf(route.getNexthop().getValue());
1377 String destination = String.valueOf(route.getDestination().getValue());
1378 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1380 if (infName != null) {
1381 LOG.trace("Updating extra route for destination {} onto vpn {} with nexthop {} and infName {}", destination,
1382 vpnId.getValue(), nextHop, infName);
1383 boolean isLockAcquired = false;
1385 InstanceIdentifier<VpnInterface> identifier = InstanceIdentifier.builder(VpnInterfaces.class)
1386 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1387 InstanceIdentifier<Adjacency> path = identifier.augmentation(Adjacencies.class).
1388 child(Adjacency.class, new AdjacencyKey(destination));
1389 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(Arrays.asList(nextHop)).
1390 setKey(new AdjacencyKey(destination)).build();
1391 isLockAcquired = NeutronvpnUtils.lock(infName);
1392 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, erAdj);
1393 } catch (Exception e) {
1394 LOG.error("exception in adding extra route with destination: {}, next hop: {}", destination, nextHop, e);
1396 if (isLockAcquired) {
1397 NeutronvpnUtils.unlock(infName);
1401 LOG.debug("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} " +
1402 "with nexthop {}", destination, vpnId.getValue(), nextHop);
1408 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1409 for (Routes route : routeList) {
1410 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1411 boolean isLockAcquired = false;
1412 String nextHop = String.valueOf(route.getNexthop().getValue());
1413 String destination = String.valueOf(route.getDestination().getValue());
1414 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1416 if (infName == null) {
1417 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} " +
1419 destination, vpnId.getValue(), nextHop);
1420 // Proceed to remove the next extra-route
1423 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1424 destination, vpnId.getValue(), nextHop, infName);
1426 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1427 InstanceIdentifier.builder(VpnInterfaces.class)
1428 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1429 .augmentation(Adjacencies.class)
1430 .child(Adjacency.class, new AdjacencyKey(destination))
1433 // Looking for existing prefix in MDSAL database
1434 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1435 adjacencyIdentifier);
1436 boolean updateNextHops = false;
1437 List<String> nextHopList = new ArrayList<>();
1438 if (adjacency.isPresent()) {
1439 List<String> nhListRead = adjacency.get().getNextHopIpList();
1440 if (nhListRead.size() > 1) { // ECMP case
1441 for (String nextHopRead : nhListRead) {
1442 if (nextHopRead.equals(nextHop)) {
1443 updateNextHops = true;
1445 nextHopList.add(nextHopRead);
1452 isLockAcquired = NeutronvpnUtils.lock(infName);
1453 if (updateNextHops) {
1454 // An update must be done, not including the current next hop
1455 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1456 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1457 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1458 .setNextHopIpList(nextHopList)
1459 .setKey(new AdjacencyKey(destination))
1461 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1462 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1463 .addAugmentation(Adjacencies.class, erAdjs).build();
1464 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1466 // Remove the whole route
1467 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1468 LOG.trace("extra route {} deleted successfully", route);
1470 } catch (Exception e) {
1471 LOG.error("exception in deleting extra route: {}" + e);
1473 if (isLockAcquired) {
1474 NeutronvpnUtils.unlock(infName);
1478 LOG.error("Incorrect input received for extra route. {}", route);
1483 protected void removeL3Vpn(Uuid id) {
1485 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1486 Uuid router = vpnMap.getRouterId();
1487 // dissociate router
1488 if (router != null) {
1489 dissociateRouterFromVpn(id, router);
1491 // dissociate networks
1492 if (!id.equals(router)) {
1493 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1495 // remove entire vpnMaps node
1496 deleteVpnMapsNode(id);
1498 // remove vpn-instance
1499 deleteVpnInstance(id);
1502 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1503 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1504 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1505 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1506 // send subnet removed from vpn notification
1507 isExternalVpn = vpnId.equals(routerId) ? false : true;
1508 String elanInstanceName = sn.getNetworkId().getValue();
1509 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1510 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1512 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1513 .CONFIGURATION, elanIdentifierId);
1514 if (elanInstance.isPresent()) {
1515 long elanTag = elanInstance.get().getElanTag();
1516 checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn,
1518 LOG.debug("Subnet removed from VPN notification sent for subnet {} on VPN {}", subnet.getValue(),
1521 LOG.error("Subnet removed from VPN notification failed for subnet {} on VPN {} because of failure " +
1522 "in reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1524 } catch (Exception e) {
1525 LOG.error("Subnet removed from VPN notification failed for subnet {} on VPN {}", subnet.getValue(),
1526 vpnId.getValue(), e);
1529 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1530 List<Uuid> portList = sn.getPortList();
1531 if (portList != null) {
1532 for (final Uuid portId : sn.getPortList()) {
1533 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1534 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1535 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1536 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1537 List<ListenableFuture<Void>> futures = new ArrayList<>();
1538 deleteVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1540 futures.add(wrtConfigTxn.submit());
1545 // update subnet-vpn association
1546 removeFromSubnetNode(subnet, null, null, vpnId, null);
1548 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1552 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1553 updateVpnMaps(vpnId, null, routerId, null, null);
1554 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1555 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1556 if (routerSubnets != null) {
1557 for (Uuid subnetId : routerSubnets) {
1558 updateVpnForSubnet(vpnId, subnetId, true);
1562 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1563 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1565 } catch (Exception e) {
1566 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1567 .getValue(), vpnId.getValue(), e);
1571 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1572 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1573 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1574 for (Uuid subnet : routerSubnets) {
1575 addSubnetToVpn(vpnId, subnet);
1579 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1581 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1582 if (routerSubnets != null) {
1583 for (Uuid subnetId : routerSubnets) {
1584 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1585 updateVpnForSubnet(routerId, subnetId, false);
1588 clearFromVpnMaps(vpnId, routerId, null);
1590 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1591 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1593 } catch (Exception e) {
1594 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1595 .getValue(), vpnId.getValue(), e);
1599 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1600 List<String> failedNwList = new ArrayList<>();
1601 List<Uuid> passedNwList = new ArrayList<>();
1602 if (!networks.isEmpty()) {
1603 // process corresponding subnets for VPN
1604 for (Uuid nw : networks) {
1605 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1606 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1607 if (network == null) {
1608 failedNwList.add(String.format("network %s not found", nw.getValue()));
1609 } else if (vpnId != null) {
1610 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1613 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1614 LOG.debug("Adding network subnets...{}", networkSubnets);
1615 if (networkSubnets != null) {
1616 for (Uuid subnet : networkSubnets) {
1617 // check if subnet added as router interface to some router
1618 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1619 if (subnetVpnId == null) {
1620 addSubnetToVpn(vpn, subnet);
1621 passedNwList.add(nw);
1623 failedNwList.add(String.format("subnet %s already added as router interface bound to " +
1624 "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
1628 if (NeutronvpnUtils.getIsExternal(network)) {
1629 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1633 updateVpnMaps(vpn, null, null, null, passedNwList);
1635 return failedNwList;
1638 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1639 List<String> failedNwList = new ArrayList<>();
1640 List<Uuid> passedNwList = new ArrayList<>();
1641 if (networks != null && !networks.isEmpty()) {
1642 // process corresponding subnets for VPN
1643 for (Uuid nw : networks) {
1644 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1645 if (network == null) {
1646 failedNwList.add(String.format("network %s not found", nw.getValue()));
1648 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1649 if (vpn.equals(vpnId)) {
1650 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1651 LOG.debug("Removing network subnets...");
1652 if (networkSubnets != null) {
1653 for (Uuid subnet : networkSubnets) {
1654 removeSubnetFromVpn(vpn, subnet);
1655 passedNwList.add(nw);
1659 if (vpnId == null) {
1660 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1663 failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
1664 "of the one given as input", nw.getValue(), vpnId.getValue()));
1667 if (NeutronvpnUtils.getIsExternal(network)) {
1668 nvpnNatManager.removeExternalNetworkFromVpn(network);
1672 clearFromVpnMaps(vpn, null, passedNwList);
1674 return failedNwList;
1678 * It handles the invocations to the neutronvpn:associateNetworks RPC method
1680 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateNetworks
1681 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput)
1684 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1686 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1687 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1688 LOG.debug("associateNetworks {}", input);
1689 StringBuilder returnMsg = new StringBuilder();
1690 Uuid vpnId = input.getVpnId();
1693 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1694 List<Uuid> netIds = input.getNetworkId();
1695 if (netIds != null && !netIds.isEmpty()) {
1696 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1697 if (!failed.isEmpty()) {
1698 returnMsg.append(failed);
1702 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1704 if (returnMsg.length() != 0) {
1705 String message = String.format("associate Networks to vpn %s failed due to %s",
1706 vpnId.getValue(), returnMsg);
1708 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1710 opBuilder.setResponse(errorResponse);
1711 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().withResult(opBuilder.build()).build());
1713 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().build());
1715 } catch (Exception ex) {
1716 String message = String.format("associate Networks to vpn %s failed due to %s",
1717 input.getVpnId().getValue(), ex.getMessage());
1718 LOG.error(message, ex);
1719 result.set(RpcResultBuilder.<AssociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1722 LOG.debug("associateNetworks returns..");
1727 * It handles the invocations to the neutronvpn:associateRouter RPC method
1729 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateRouter
1730 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput)
1733 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1735 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1736 LOG.debug("associateRouter {}", input);
1737 StringBuilder returnMsg = new StringBuilder();
1738 Uuid vpnId = input.getVpnId();
1739 Uuid routerId = input.getRouterId();
1741 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1742 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1743 if (vpnMap != null) {
1745 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1746 if (vpnMap.getRouterId() != null) {
1747 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1748 .append(vpnMap.getRouterId().getValue());
1749 } else if (extVpnId != null) {
1750 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
1751 "another VPN ").append(extVpnId.getValue());
1753 associateRouterToVpn(vpnId, routerId);
1756 returnMsg.append("router not found : ").append(routerId.getValue());
1759 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1761 if (returnMsg.length() != 0) {
1762 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1765 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1768 result.set(RpcResultBuilder.<Void> success().build());
1770 } catch (Exception ex) {
1771 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1772 vpnId.getValue(), ex.getMessage());
1773 LOG.error(message, ex);
1774 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1776 LOG.debug("associateRouter returns..");
1780 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method
1782 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getFixedIPsForNeutronPort
1783 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput)
1786 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput input) {
1787 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1788 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1789 Uuid portId = input.getPortId();
1790 StringBuilder returnMsg = new StringBuilder();
1792 List<String> fixedIPList = new ArrayList<>();
1793 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1795 List<FixedIps> fixedIPs = port.getFixedIps();
1796 for (FixedIps ip : fixedIPs) {
1797 fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
1800 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1802 if (returnMsg.length() != 0) {
1803 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1805 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1806 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1808 opBuilder.setFixedIPs(fixedIPList);
1809 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().withResult(opBuilder.build())
1811 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().build());
1813 } catch (Exception ex) {
1814 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1815 portId.getValue(), ex.getMessage());
1816 LOG.error(message, ex);
1817 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1818 .withError(ErrorType.APPLICATION, message).build());
1824 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method
1826 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1827 * .rev150602.NeutronvpnService#dissociateNetworks(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1828 * .neutronvpn.rev150602.DissociateNetworksInput)
1831 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1833 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1834 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1836 LOG.debug("dissociateNetworks {}", input);
1837 StringBuilder returnMsg = new StringBuilder();
1838 Uuid vpnId = input.getVpnId();
1841 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1842 List<Uuid> netIds = input.getNetworkId();
1843 if (netIds != null && !netIds.isEmpty()) {
1844 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1845 if (!failed.isEmpty()) {
1846 returnMsg.append(failed);
1850 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1852 if (returnMsg.length() != 0) {
1853 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1856 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1858 opBuilder.setResponse(errorResponse);
1859 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().withResult(opBuilder.build()).build());
1861 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().build());
1863 } catch (Exception ex) {
1864 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1865 input.getVpnId().getValue(), ex.getMessage());
1866 LOG.error(message, ex);
1867 result.set(RpcResultBuilder.<DissociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1870 LOG.debug("dissociateNetworks returns..");
1875 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1877 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1878 * .rev150602.NeutronvpnService#dissociateRouter(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1879 * .rev150602.DissociateRouterInput)
1882 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1884 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1886 LOG.debug("dissociateRouter {}", input);
1887 StringBuilder returnMsg = new StringBuilder();
1888 Uuid vpnId = input.getVpnId();
1889 Uuid routerId = input.getRouterId();
1891 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1892 if (routerId != null) {
1893 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1895 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1896 if (vpnId.equals(routerVpnId)) {
1897 dissociateRouterFromVpn(vpnId, routerId);
1899 if (routerVpnId == null) {
1900 returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
1903 returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
1904 "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
1909 returnMsg.append("router not found : ").append(routerId.getValue());
1913 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1915 if (returnMsg.length() != 0) {
1916 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1917 vpnId.getValue(), returnMsg);
1919 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1921 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1924 result.set(RpcResultBuilder.<Void> success().build());
1926 } catch (Exception ex) {
1927 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1928 vpnId.getValue(), ex.getMessage());
1929 LOG.error(message, ex);
1930 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1932 LOG.debug("dissociateRouter returns..");
1937 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1938 // check if the router is associated to some VPN
1939 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1940 if (vpnId != null) {
1941 // remove existing external vpn interfaces
1942 for (Uuid subnetId : routerSubnetIds) {
1943 removeSubnetFromVpn(vpnId, subnetId);
1945 clearFromVpnMaps(vpnId, routerId, null);
1947 // remove existing internal vpn interfaces
1948 for (Uuid subnetId : routerSubnetIds) {
1949 removeSubnetFromVpn(routerId, subnetId);
1952 // delete entire vpnMaps node for internal VPN
1953 deleteVpnMapsNode(routerId);
1955 // delete vpn-instance for internal VPN
1956 deleteVpnInstance(routerId);
1959 protected Subnet getNeutronSubnet(Uuid subnetId){
1960 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1963 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1964 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1966 return sn.getGatewayIp();
1972 protected Network getNeutronNetwork(Uuid networkId) {
1973 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1976 protected Port getNeutronPort(String name) {
1977 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1980 protected Port getNeutronPort(Uuid portId) {
1981 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1984 protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1985 List<Uuid> subnets = new ArrayList<>();
1987 InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1988 Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1990 if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1991 List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1992 for (Subnetmap subnetMap : subnetMapList) {
1993 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1994 subnets.add(subnetMap.getId());
2002 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command
2004 * @return a List of String to be printed on screen
2006 public List<String> showNeutronPortsCLI() {
2007 List<String> result = new ArrayList<>();
2008 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
2010 result.add("-------------------------------------------------------------------------------------------");
2011 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
2013 Optional<Ports> ports = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
2014 if (ports.isPresent() && ports.get().getPort() != null) {
2015 for (Port port : ports.get().getPort()) {
2016 List<FixedIps> fixedIPs = port.getFixedIps();
2018 if (fixedIPs != null && !fixedIPs.isEmpty()) {
2019 List<String> ipList = new ArrayList<>();
2020 for (FixedIps fixedIp : fixedIPs) {
2021 IpAddress ipAddress = fixedIp.getIpAddress();
2022 if (ipAddress.getIpv4Address() != null) {
2023 ipList.add(ipAddress.getIpv4Address().getValue());
2025 ipList.add((ipAddress.getIpv6Address().getValue()));
2028 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2029 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
2030 ipList.toString()));
2032 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2033 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
2035 } catch (Exception e) {
2036 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
2038 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
2039 .getValue() + ": " + e.getMessage());
2043 } catch (Exception e) {
2044 LOG.error("Failed to retrieve neutronPorts info : ", e);
2045 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2051 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command
2053 * @param vpnuuid Uuid of the VPN whose config must be shown
2054 * @return formatted output list
2056 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2057 List<String> result = new ArrayList<>();
2058 if (vpnuuid == null) {
2059 System.out.println("");
2060 System.out.println("Displaying VPN config for all VPNs");
2061 System.out.println("To display VPN config for a particular VPN, use the following syntax");
2062 System.out.println(getshowVpnConfigCLIHelp());
2065 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2066 if (rpcResult.isSuccessful()) {
2068 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2070 result.add(String.format(" %-80s ", "Import-RTs"));
2072 result.add(String.format(" %-80s ", "Export-RTs"));
2074 result.add(String.format(" %-76s ", "Subnet IDs"));
2076 result.add("------------------------------------------------------------------------------------");
2078 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
2079 for (L3vpnInstance Vpn : VpnList) {
2080 String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue()
2082 result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId,
2083 Vpn.getRouteDistinguisher()));
2085 result.add(String.format(" %-80s ", Vpn.getImportRT()));
2087 result.add(String.format(" %-80s ", Vpn.getExportRT()));
2090 Uuid vpnid = Vpn.getId();
2091 List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2092 if (!subnetList.isEmpty()) {
2093 for (Uuid subnetuuid : subnetList) {
2094 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2097 result.add(String.format(" %-76s ", "\" \""));
2100 result.add("----------------------------------------");
2104 String errortag = rpcResult.getErrors().iterator().next().getTag();
2105 if (errortag == "") {
2106 System.out.println("");
2107 System.out.println("No VPN has been configured yet");
2108 } else if (errortag == "invalid-value") {
2109 System.out.println("");
2110 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2112 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2113 System.out.println(getshowVpnConfigCLIHelp());
2116 } catch (InterruptedException | ExecutionException e) {
2117 LOG.error("error getting VPN info : ", e);
2118 System.out.println("error getting VPN info : " + e.getMessage());
2123 protected void createExternalVpnInterfaces(Uuid extNetId) {
2124 if (extNetId == null) {
2125 LOG.trace("external network is null");
2129 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2130 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2131 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2135 for (String elanInterface : extElanInterfaces) {
2136 createExternalVpnInterface(extNetId, elanInterface);
2140 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2141 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2142 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2143 LOG.trace("No external ports attached for external network {}", extNetId);
2147 for (String elanInterface : extElanInterfaces) {
2148 boolean isLockAcquired = false;
2149 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2150 .buildVpnInterfaceIdentifier(elanInterface);
2152 isLockAcquired = NeutronvpnUtils.lock(elanInterface);
2153 LOG.debug("removing vpn interface {}, vpnIfIdentifier", elanInterface, vpnIfIdentifier);
2154 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2155 } catch (Exception ex) {
2156 LOG.error("Removal of vpninterface {} failed due to {}", elanInterface, ex);
2158 if (isLockAcquired) {
2159 NeutronvpnUtils.unlock(elanInterface);
2165 private void createExternalVpnInterface(Uuid vpnId, String infName) {
2166 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, null);
2169 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2170 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2171 if (vpnId == null || infName == null) {
2172 LOG.debug("vpn id or interface is null");
2176 Boolean wrtConfigTxnPresent = true;
2177 if (wrtConfigTxn == null) {
2178 wrtConfigTxnPresent = false;
2179 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2182 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2183 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2185 .setVpnInstanceName(vpnId.getValue())
2186 .setIsRouterInterface(isRouterInterface);
2187 if (adjacencies != null) {
2188 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2190 VpnInterface vpnIf = vpnb.build();
2192 LOG.info("Creating vpn interface {}", vpnIf);
2193 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2194 } catch (Exception ex) {
2195 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2198 if (!wrtConfigTxnPresent) {
2199 wrtConfigTxn.submit();
2203 private String getshowVpnConfigCLIHelp() {
2204 StringBuilder help = new StringBuilder("Usage:");
2205 help.append("display vpn-config [-vid/--vpnid <id>]");
2206 return help.toString();
2209 private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
2210 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2211 SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
2213 LOG.info("publish notification called");
2215 builder.setSubnetId(subnetId);
2216 builder.setSubnetIp(subnetIp);
2217 builder.setVpnName(vpnName);
2218 builder.setExternalVpn(isExternalvpn);
2219 builder.setElanTag(elanTag);
2221 notificationPublishService.putNotification(builder.build());
2224 private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
2225 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2226 SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
2228 LOG.info("publish notification called");
2230 builder.setSubnetId(subnetId);
2231 builder.setSubnetIp(subnetIp);
2232 builder.setVpnName(vpnName);
2233 builder.setExternalVpn(isExternalvpn);
2234 builder.setElanTag(elanTag);
2236 notificationPublishService.putNotification(builder.build());
2239 private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
2240 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2241 SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
2243 LOG.info("publish notification called");
2245 builder.setSubnetId(subnetId);
2246 builder.setSubnetIp(subnetIp);
2247 builder.setVpnName(vpnName);
2248 builder.setExternalVpn(isExternalvpn);
2249 builder.setElanTag(elanTag);
2251 notificationPublishService.putNotification(builder.build());
2254 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2255 InterruptedException {
2256 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2257 .setVpnId(vpnId).build();
2258 LOG.info("publishing notification upon association of router to VPN");
2259 notificationPublishService.putNotification(routerAssociatedToVpn);
2262 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2263 InterruptedException {
2264 RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
2265 (routerId).setVpnId(vpnId).build();
2266 LOG.info("publishing notification upon disassociation of router from VPN");
2267 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2270 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2271 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);