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).build();
637 // create extra route adjacency
638 if (rtr != null && rtr.getRoutes() != null) {
639 List<Routes> routeList = rtr.getRoutes();
640 List<Adjacency> erAdjList = addAdjacencyforExtraRoute(vpnId, routeList);
641 if (erAdjList != null && !erAdjList.isEmpty()) {
642 adjList.addAll(erAdjList);
645 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
646 .getMacAddress().getValue(), isRouterInterface, true, false);
648 // create vpn-interface on this neutron port
649 Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
650 writeVpnInterfaceToDs(vpnId, infName, adjs, isRouterInterface, wrtConfigTxn);
651 if (routerId != null) {
652 addToNeutronRouterInterfacesMap(routerId, infName);
656 protected void deleteVpnInterface(Uuid vpnId, Uuid routerId, Port port, WriteTransaction wrtConfigTxn) {
657 Boolean wrtConfigTxnPresent = true;
658 if (wrtConfigTxn == null) {
659 wrtConfigTxnPresent = false;
660 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
662 String infName = port.getUuid().getValue();
663 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
665 LOG.debug("Deleting vpn interface {}", infName);
666 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
668 List<FixedIps> ips = port.getFixedIps();
669 for (FixedIps ip : ips) {
670 String ipValue = String.valueOf(ip.getIpAddress().getValue());
671 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue);
673 } catch (Exception ex) {
674 LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
676 if (routerId != null) {
677 removeFromNeutronRouterInterfacesMap(routerId, infName);
679 if (!wrtConfigTxnPresent) {
680 wrtConfigTxn.submit();
684 protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean isBeingAssociated) {
685 if (vpnId == null || port == null) {
688 boolean isLockAcquired = false;
689 String infName = port.getUuid().getValue();
690 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
692 isLockAcquired = NeutronvpnUtils.lock(infName);
693 Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
694 .CONFIGURATION, vpnIfIdentifier);
695 if (optionalVpnInterface.isPresent()) {
696 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get())
697 .setVpnInstanceName(vpnId.getValue());
698 LOG.debug("Updating vpn interface {}", infName);
699 if (!isBeingAssociated) {
700 List<Adjacency> adjacencyList = vpnIfBuilder.getAugmentation(Adjacencies.class).getAdjacency();
701 Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
702 while (adjacencyIter.hasNext()) {
703 Adjacency adjacency = adjacencyIter.next();
704 String mipToQuery = adjacency.getIpAddress().split("/")[0];
705 InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier
706 (oldVpnId.getValue(), mipToQuery);
707 Optional<VpnPortipToPort> optionalVpnPort = NeutronvpnUtils.read(dataBroker,
710 if (!optionalVpnPort.isPresent() || optionalVpnPort.get().isLearnt()) {
711 LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} " +
712 "from VPN " + "{}", infName, vpnId, oldVpnId);
713 adjacencyIter.remove();
714 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), mipToQuery);
715 LOG.trace("Entry for fixedIP {} for port {} on VPN removed from " +
716 "VpnPortFixedIPToPortData", mipToQuery, infName, vpnId.getValue());
719 Adjacencies adjacencies = new AdjacenciesBuilder().setAdjacency(adjacencyList).build();
720 vpnIfBuilder.addAugmentation(Adjacencies.class, adjacencies);
722 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
725 List<FixedIps> ips = port.getFixedIps();
726 for (FixedIps ip : ips) {
727 String ipValue = String.valueOf(ip.getIpAddress().getValue());
728 if (oldVpnId != null) {
729 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
731 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
732 .getMacAddress().getValue(), false, true, false);
735 LOG.error("VPN Interface {} not found", infName);
737 } catch (Exception ex) {
738 LOG.error("Updation of vpninterface {} failed due to {}", infName, ex);
740 if (isLockAcquired) {
741 NeutronvpnUtils.unlock(infName);
746 public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt,
747 List<String> ert, Uuid router, List<Uuid> networks) {
749 // Update VPN Instance node
750 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
752 // Update local vpn-subnet DS
753 updateVpnMaps(vpn, name, router, tenant, networks);
755 if (router != null) {
756 Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(dataBroker, router, true);
757 if (existingVpn != null) {
758 // use case when a cluster is rebooted and router add DCN is received, triggering #createL3InternalVpn
760 // if before reboot, router was already associated to VPN, should not proceed associating router to
761 // internal VPN. Adding to RouterInterfacesMap is also not needed since it's a config DS and will be
762 // preserved upon reboot.
763 // For a non-reboot case #associateRouterToInternalVPN already takes care of adding to
764 // RouterInterfacesMap via #createVPNInterface call.
765 LOG.info("Associating router to Internal VPN skipped for VPN {} due to router {} already associated " +
766 "to external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
769 associateRouterToInternalVpn(vpn, router);
774 * Performs the creation of a Neutron L3VPN, associating the new VPN to the
775 * specified Neutron Networks and Routers
777 * @param vpn Uuid of the VPN tp be created
778 * @param name Representative name of the new VPN
779 * @param tenant Uuid of the Tenant under which the VPN is going to be created
780 * @param rd Route-distinguisher for the VPN
781 * @param irt A list of Import Route Targets
782 * @param ert A list of Export Route Targets
783 * @param router UUID of the neutron router the VPN may be associated to
784 * @param networks UUID of the neutron network the VPN may be associated to
785 * @throws Exception if association of L3VPN failed
787 public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
788 Uuid router, List<Uuid> networks) throws Exception {
790 // Update VPN Instance node
791 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
793 // Please note that router and networks will be filled into VPNMaps
794 // by subsequent calls here to associateRouterToVpn and
795 // associateNetworksToVpn
796 updateVpnMaps(vpn, name, null, tenant, null);
798 if (router != null) {
799 associateRouterToVpn(vpn, router);
801 if (networks != null) {
802 List<String> failStrings = associateNetworksToVpn(vpn, networks);
803 if (failStrings != null && !failStrings.isEmpty()) {
804 LOG.error("L3VPN {} association to networks failed with error message {}. ",
805 vpn.getValue(), failStrings.get(0));
806 throw new Exception(failStrings.get(0));
812 * It handles the invocations to the createL3VPN RPC method
814 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#createL3VPN
815 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateL3VPNInput)
818 public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
820 CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
821 SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
822 List<RpcError> errorList = new ArrayList<>();
823 int failurecount = 0;
824 int warningcount = 0;
826 List<L3vpn> vpns = input.getL3vpn();
827 for (L3vpn vpn : vpns) {
828 RpcError error = null;
830 if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
831 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
832 vpn.getId().getValue());
834 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
835 errorList.add(error);
839 if (vpn.getRouteDistinguisher().size() > 1) {
840 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
841 vpn.getId().getValue(), vpn.getRouteDistinguisher());
843 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
844 errorList.add(error);
848 if (vpn.getRouterId() != null) {
849 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
850 msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
851 vpn.getId().getValue(), vpn.getRouterId().getValue());
853 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
854 errorList.add(error);
858 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
860 msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
861 + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
864 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
865 errorList.add(error);
870 if (vpn.getNetworkIds() != null) {
871 for (Uuid nw : vpn.getNetworkIds()) {
872 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
873 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
874 if (network == null) {
875 msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
876 vpn.getId().getValue(), nw.getValue());
878 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
879 errorList.add(error);
881 } else if (vpnId != null) {
882 msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
883 + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
886 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
887 errorList.add(error);
896 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
897 vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
898 } catch (Exception ex) {
899 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
901 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
902 errorList.add(error);
906 // if at least one succeeds; result is success
907 // if none succeeds; result is failure
908 if (failurecount + warningcount == vpns.size()) {
909 result.set(RpcResultBuilder.<CreateL3VPNOutput> failed().withRpcErrors(errorList).build());
911 List<String> errorResponseList = new ArrayList<>();
912 if (!errorList.isEmpty()) {
913 for (RpcError rpcError : errorList) {
914 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
915 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
916 errorResponseList.add(errorResponse);
919 errorResponseList.add("Operation successful with no errors");
921 opBuilder.setResponse(errorResponseList);
922 result.set(RpcResultBuilder.<CreateL3VPNOutput> success().withResult(opBuilder.build()).build());
928 * It handles the invocations to the neutronvpn:getL3VPN RPC method
930 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getL3VPN
931 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetL3VPNInput)
934 public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
936 GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
937 SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
938 Uuid inputVpnId = input.getId();
939 List<VpnInstance> vpns = new ArrayList<>();
942 if (inputVpnId == null) {
944 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
946 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker,
947 LogicalDatastoreType.CONFIGURATION,
949 if (optionalVpns.isPresent() && optionalVpns.get().getVpnInstance() != null) {
950 for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
951 // eliminating internal VPNs from getL3VPN output
952 if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
958 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL, "", "No VPN " +
959 "is present").build());
963 String name = inputVpnId.getValue();
964 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
965 .child(VpnInstance.class,
966 new VpnInstanceKey(name))
968 // read VpnInstance Info
969 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
971 if (optionalVpn.isPresent()) {
972 vpns.add(optionalVpn.get());
974 String message = String.format("GetL3VPN failed because VPN %s is not present", name);
976 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
977 "invalid-value", message).build());
980 List<L3vpnInstances> l3vpnList = new ArrayList<>();
981 for (VpnInstance vpnInstance : vpns) {
982 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
984 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
985 .class, new VpnMapKey(vpnId)).build();
986 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
988 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
989 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
991 List<String> ertList = new ArrayList<>();
992 List<String> irtList = new ArrayList<>();
994 for (VpnTarget vpnTarget : vpnTargetList) {
995 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
996 ertList.add(vpnTarget.getVrfRTValue());
998 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
999 irtList.add(vpnTarget.getVrfRTValue());
1001 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
1002 ertList.add(vpnTarget.getVrfRTValue());
1003 irtList.add(vpnTarget.getVrfRTValue());
1007 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1008 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1010 if (optionalVpnMap.isPresent()) {
1011 VpnMap vpnMap = optionalVpnMap.get();
1012 l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1013 .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1015 l3vpnList.add(l3vpn.build());
1018 opBuilder.setL3vpnInstances(l3vpnList);
1019 result.set(RpcResultBuilder.<GetL3VPNOutput> success().withResult(opBuilder.build()).build());
1021 } catch (Exception ex) {
1022 String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
1023 LOG.error(message, ex);
1024 result.set(RpcResultBuilder.<GetL3VPNOutput> failed().withError(ErrorType.APPLICATION, message).build());
1030 * It handles the invocations to the neutronvpn:deleteL3VPN RPC method
1032 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#deleteL3VPN
1033 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteL3VPNInput)
1036 public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1038 DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1039 SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1040 List<RpcError> errorList = new ArrayList<>();
1042 int failurecount = 0;
1043 int warningcount = 0;
1044 List<Uuid> vpns = input.getId();
1045 for (Uuid vpn : vpns) {
1049 InstanceIdentifier<VpnInstance> vpnIdentifier =
1050 InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class, new VpnInstanceKey
1051 (vpn.getValue())).build();
1052 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1053 .CONFIGURATION, vpnIdentifier);
1054 if (optionalVpn.isPresent()) {
1057 msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1059 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1060 errorList.add(error);
1063 } catch (Exception ex) {
1064 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1066 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1067 errorList.add(error);
1071 // if at least one succeeds; result is success
1072 // if none succeeds; result is failure
1073 if (failurecount + warningcount == vpns.size()) {
1074 result.set(RpcResultBuilder.<DeleteL3VPNOutput> failed().withRpcErrors(errorList).build());
1076 List<String> errorResponseList = new ArrayList<>();
1077 if (!errorList.isEmpty()) {
1078 for (RpcError rpcError : errorList) {
1079 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1080 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1081 errorResponseList.add(errorResponse);
1084 errorResponseList.add("Operation successful with no errors");
1086 opBuilder.setResponse(errorResponseList);
1087 result.set(RpcResultBuilder.<DeleteL3VPNOutput> success().withResult(opBuilder.build()).build());
1092 protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
1093 LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1094 Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1095 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1096 // send subnet added to vpn notification
1097 isExternalVpn = vpnId.equals(routerId) ? false : true;
1098 String elanInstanceName = sn.getNetworkId().getValue();
1099 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1100 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1102 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1103 .CONFIGURATION, elanIdentifierId);
1104 if (elanInstance.isPresent()) {
1105 long elanTag = elanInstance.get().getElanTag();
1106 checkAndPublishSubnetAddNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn,
1108 LOG.debug("Subnet added to VPN notification sent for subnet {} on VPN {}", subnet.getValue(),
1111 LOG.error("Subnet added to VPN notification failed for subnet {} on VPN {} because of failure in " +
1112 "reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1114 } catch (Exception e) {
1115 LOG.error("Subnet added to VPN notification failed for subnet {} on VPN {}", subnet.getValue(), vpnId
1118 // Check if there are ports on this subnet and add corresponding
1120 List<Uuid> portList = sn.getPortList();
1121 if (portList != null) {
1122 for (final Uuid portId : sn.getPortList()) {
1123 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1124 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1125 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), new
1126 Callable<List<ListenableFuture<Void>>>() {
1128 public List<ListenableFuture<Void>> call() throws Exception {
1129 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1130 List<ListenableFuture<Void>> futures = new ArrayList<>();
1131 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1133 futures.add(wrtConfigTxn.submit());
1141 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1142 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1143 // Read the subnet first to see if its already associated to a VPN
1144 Uuid oldVpnId = null;
1145 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class).
1146 child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1147 Subnetmap sn = null;
1148 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1149 if (optSn.isPresent()) {
1151 oldVpnId = sn.getVpnId();
1152 List<String> ips = sn.getRouterInterfaceFixedIps();
1153 for (String ipValue : ips) {
1154 if (oldVpnId != null) {
1155 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(), ipValue);
1157 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, sn
1158 .getRouterInterfaceName().getValue(), sn.getRouterIntfMacAddress(), true, true, false);
1161 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1162 // send vpn updated for subnet notification
1163 String elanInstanceName = sn.getNetworkId().getValue();
1164 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1165 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1167 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1168 .CONFIGURATION, elanIdentifierId);
1169 if (elanInstance.isPresent()) {
1170 long elanTag = elanInstance.get().getElanTag();
1171 checkAndPublishSubnetUpdNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isBeingAssociated,
1173 LOG.debug("VPN updated for subnet notification sent for subnet {} on VPN {}", subnet.getValue(),
1176 LOG.error("VPN updated for subnet notification failed for subnet {} on VPN {} because of failure " +
1177 "in reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1179 } catch (Exception e) {
1180 LOG.error("VPN updated for subnet notification failed for subnet {} on VPN {}", subnet.getValue(),
1181 vpnId.getValue(), e);
1183 // Check for ports on this subnet and update association of
1184 // corresponding vpn-interfaces to external vpn
1185 List<Uuid> portList = sn.getPortList();
1186 if (portList != null) {
1187 for (Uuid port : sn.getPortList()) {
1188 LOG.debug("Updating vpn-interface for port {}", port.getValue());
1189 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port),
1195 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1196 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1197 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1200 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1201 synchronized (routerId.getValue().intern()) {
1202 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1203 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1204 .CONFIGURATION, routerInterfacesId);
1205 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1206 (interfaceName).build();
1207 if (optRouterInterfaces.isPresent()) {
1208 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1209 .class, new InterfacesKey(interfaceName)), routerInterface);
1211 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1212 List<Interfaces> interfaces = new ArrayList<>();
1213 interfaces.add(routerInterface);
1214 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1215 .class, new InterfacesKey(interfaceName)), routerInterface);
1220 protected void removeFromNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1221 synchronized (routerId.getValue().intern()) {
1222 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1223 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1224 .CONFIGURATION, routerInterfacesId);
1225 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName)).setInterfaceId
1226 (interfaceName).build();
1227 if (optRouterInterfaces.isPresent()) {
1228 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1229 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1230 if (interfaces != null && interfaces.remove(routerInterface)) {
1231 if (interfaces.isEmpty()) {
1232 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1234 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1235 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1243 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1244 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1245 * route will be ignored.
1247 * @param vpnName the VPN identifier
1248 * @param interVpnLinkRoutes The list of static routes
1249 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1251 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1252 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1253 for ( Routes route : interVpnLinkRoutes ) {
1254 String nexthop = String.valueOf(route.getNexthop().getValue());
1255 String destination = String.valueOf(route.getDestination().getValue());
1256 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1257 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1258 AddStaticRouteInput rpcInput =
1259 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1260 .setVpnInstanceName(vpnName.getValue())
1262 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1263 RpcResult<AddStaticRouteOutput> rpcResult;
1265 rpcResult = labelOuputFtr.get();
1266 if ( rpcResult.isSuccessful() ) {
1267 LOG.debug("Label generated for destination {} is: {}",
1268 destination, rpcResult.getResult().getLabel());
1270 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1271 destination, nexthop, rpcResult.getErrors());
1273 } catch (InterruptedException | ExecutionException e) {
1274 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1277 // Any other case is a fault.
1278 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1279 String.valueOf(route.getDestination().getValue()), nexthop );
1286 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1287 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1289 * @param vpnName the VPN identifier
1290 * @param interVpnLinkRoutes The list of static routes
1291 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1293 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1294 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1295 for ( Routes route : interVpnLinkRoutes ) {
1296 String nexthop = String.valueOf(route.getNexthop().getValue());
1297 String destination = String.valueOf(route.getDestination().getValue());
1298 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1299 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1300 RemoveStaticRouteInput rpcInput =
1301 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1302 .setVpnInstanceName(vpnName.getValue())
1304 vpnRpcService.removeStaticRoute(rpcInput);
1306 // Any other case is a fault.
1307 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1308 String.valueOf(route.getDestination().getValue()), nexthop );
1315 * Returns true if the specified nexthop is the other endpoint in an
1316 * InterVpnLink, regarding one of the VPN's point of view.
1318 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1320 interVpnLink != null
1321 && ( (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1322 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1323 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1324 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1327 protected List<Adjacency> addAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1328 List<Adjacency> adjList = new ArrayList<>();
1329 Map<String, List<String>> adjMap = new HashMap<>();
1330 for (Routes route : routeList) {
1331 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1332 LOG.error("Incorrect input received for extra route. {}", route);
1334 String nextHop = String.valueOf(route.getNexthop().getValue());
1335 String destination = String.valueOf(route.getDestination().getValue());
1336 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1338 if (infName == null) {
1339 LOG.error("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} " +
1340 "with nexthop {}", destination, vpnId.getValue(), nextHop);
1341 // Proceed to process the next extra-route
1344 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} and infName {}", destination,
1345 vpnId.getValue(), nextHop, infName);
1346 List<String> hops = adjMap.get(destination);
1348 hops = new ArrayList<>();
1349 adjMap.put(destination, hops);
1351 if (! hops.contains(nextHop)) {
1357 for (String destination : adjMap.keySet()) {
1358 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination).setNextHopIpList(adjMap.get
1359 (destination)).setKey(new AdjacencyKey(destination)).build();
1363 for (Adjacency adj : adjList) {
1364 for(String nextHop : adj.getNextHopIpList()) {
1365 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1367 if (infName != null) {
1368 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(VpnInterfaces.class)
1369 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1370 boolean isLockAcquired = false;
1372 Optional<VpnInterface> optionalVpnInterface =
1373 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
1374 if (optionalVpnInterface.isPresent()) {
1375 Adjacency newAdj = new AdjacencyBuilder(adj).setNextHopIpList(Arrays.asList(nextHop))
1377 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1378 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1379 .addAugmentation(Adjacencies.class, erAdjs).build();
1380 isLockAcquired = NeutronvpnUtils.lock(infName);
1381 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1383 LOG.error("VM adjacency for interface {} not present; cannot add extra route adjacency",
1386 } catch (Exception e) {
1387 LOG.error("exception in adding extra route with destination: {}, next hop: {}", adj
1388 .getIpAddress(), nextHop, e);
1390 if (isLockAcquired) {
1391 NeutronvpnUtils.unlock(infName);
1395 LOG.warn("Could not find suitable Interface for {}", nextHop);
1402 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1403 for (Routes route : routeList) {
1404 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1405 boolean isLockAcquired = false;
1406 String nextHop = String.valueOf(route.getNexthop().getValue());
1407 String destination = String.valueOf(route.getDestination().getValue());
1408 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1410 if (infName == null) {
1411 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} " +
1413 destination, vpnId.getValue(), nextHop);
1414 // Proceed to remove the next extra-route
1417 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1418 destination, vpnId.getValue(), nextHop, infName);
1420 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1421 InstanceIdentifier.builder(VpnInterfaces.class)
1422 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1423 .augmentation(Adjacencies.class)
1424 .child(Adjacency.class, new AdjacencyKey(destination))
1427 // Looking for existing prefix in MDSAL database
1428 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1429 adjacencyIdentifier);
1430 boolean updateNextHops = false;
1431 List<String> nextHopList = new ArrayList<>();
1432 if (adjacency.isPresent()) {
1433 List<String> nhListRead = adjacency.get().getNextHopIpList();
1434 if (nhListRead.size() > 1) { // ECMP case
1435 for (String nextHopRead : nhListRead) {
1436 if (nextHopRead.equals(nextHop)) {
1437 updateNextHops = true;
1439 nextHopList.add(nextHopRead);
1446 isLockAcquired = NeutronvpnUtils.lock(infName);
1447 if (updateNextHops) {
1448 // An update must be done, not including the current next hop
1449 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1450 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1451 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1452 .setNextHopIpList(nextHopList)
1453 .setKey(new AdjacencyKey(destination))
1455 Adjacencies erAdjs = new AdjacenciesBuilder().setAdjacency(Arrays.asList(newAdj)).build();
1456 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1457 .addAugmentation(Adjacencies.class, erAdjs).build();
1458 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1460 // Remove the whole route
1461 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1462 LOG.trace("extra route {} deleted successfully", route);
1464 } catch (Exception e) {
1465 LOG.error("exception in deleting extra route: {}" + e);
1467 if (isLockAcquired) {
1468 NeutronvpnUtils.unlock(infName);
1472 LOG.error("Incorrect input received for extra route. {}", route);
1477 protected void removeL3Vpn(Uuid id) {
1479 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1480 Uuid router = vpnMap.getRouterId();
1481 // dissociate router
1482 if (router != null) {
1483 dissociateRouterFromVpn(id, router);
1485 // dissociate networks
1486 if (!id.equals(router)) {
1487 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1489 // remove entire vpnMaps node
1490 deleteVpnMapsNode(id);
1492 // remove vpn-instance
1493 deleteVpnInstance(id);
1496 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1497 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1498 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1499 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1500 // send subnet removed from vpn notification
1501 isExternalVpn = vpnId.equals(routerId) ? false : true;
1502 String elanInstanceName = sn.getNetworkId().getValue();
1503 InstanceIdentifier<ElanInstance> elanIdentifierId = InstanceIdentifier.builder(ElanInstances.class)
1504 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1506 Optional<ElanInstance> elanInstance = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1507 .CONFIGURATION, elanIdentifierId);
1508 if (elanInstance.isPresent()) {
1509 long elanTag = elanInstance.get().getElanTag();
1510 checkAndPublishSubnetDelNotification(subnet, sn.getSubnetIp(), vpnId.getValue(), isExternalVpn,
1512 LOG.debug("Subnet removed from VPN notification sent for subnet {} on VPN {}", subnet.getValue(),
1515 LOG.error("Subnet removed from VPN notification failed for subnet {} on VPN {} because of failure " +
1516 "in reading ELANInstance {}", subnet.getValue(), vpnId.getValue(), elanInstanceName);
1518 } catch (Exception e) {
1519 LOG.error("Subnet removed from VPN notification failed for subnet {} on VPN {}", subnet.getValue(),
1520 vpnId.getValue(), e);
1523 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1524 List<Uuid> portList = sn.getPortList();
1525 if (portList != null) {
1526 for (final Uuid portId : sn.getPortList()) {
1527 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1528 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1529 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1530 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1531 List<ListenableFuture<Void>> futures = new ArrayList<>();
1532 deleteVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1534 futures.add(wrtConfigTxn.submit());
1539 // update subnet-vpn association
1540 removeFromSubnetNode(subnet, null, null, vpnId, null);
1542 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1546 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1547 updateVpnMaps(vpnId, null, routerId, null, null);
1548 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1549 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1550 if (routerSubnets != null) {
1551 for (Uuid subnetId : routerSubnets) {
1552 updateVpnForSubnet(vpnId, subnetId, true);
1556 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1557 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1559 } catch (Exception e) {
1560 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1561 .getValue(), vpnId.getValue(), e);
1565 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1566 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1567 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1568 for (Uuid subnet : routerSubnets) {
1569 addSubnetToVpn(vpnId, subnet);
1573 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1575 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1576 if (routerSubnets != null) {
1577 for (Uuid subnetId : routerSubnets) {
1578 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1579 updateVpnForSubnet(routerId, subnetId, false);
1582 clearFromVpnMaps(vpnId, routerId, null);
1584 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1585 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1587 } catch (Exception e) {
1588 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1589 .getValue(), vpnId.getValue(), e);
1593 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1594 List<String> failedNwList = new ArrayList<>();
1595 List<Uuid> passedNwList = new ArrayList<>();
1596 if (!networks.isEmpty()) {
1597 // process corresponding subnets for VPN
1598 for (Uuid nw : networks) {
1599 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1600 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1601 if (network == null) {
1602 failedNwList.add(String.format("network %s not found", nw.getValue()));
1603 } else if (vpnId != null) {
1604 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1607 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1608 LOG.debug("Adding network subnets...{}", networkSubnets);
1609 if (networkSubnets != null) {
1610 for (Uuid subnet : networkSubnets) {
1611 // check if subnet added as router interface to some router
1612 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1613 if (subnetVpnId == null) {
1614 addSubnetToVpn(vpn, subnet);
1615 passedNwList.add(nw);
1617 failedNwList.add(String.format("subnet %s already added as router interface bound to " +
1618 "internal/external VPN %s", subnet.getValue (), subnetVpnId.getValue()));
1622 if (NeutronvpnUtils.getIsExternal(network)) {
1623 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1627 updateVpnMaps(vpn, null, null, null, passedNwList);
1629 return failedNwList;
1632 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1633 List<String> failedNwList = new ArrayList<>();
1634 List<Uuid> passedNwList = new ArrayList<>();
1635 if (networks != null && !networks.isEmpty()) {
1636 // process corresponding subnets for VPN
1637 for (Uuid nw : networks) {
1638 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1639 if (network == null) {
1640 failedNwList.add(String.format("network %s not found", nw.getValue()));
1642 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1643 if (vpn.equals(vpnId)) {
1644 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1645 LOG.debug("Removing network subnets...");
1646 if (networkSubnets != null) {
1647 for (Uuid subnet : networkSubnets) {
1648 removeSubnetFromVpn(vpn, subnet);
1649 passedNwList.add(nw);
1653 if (vpnId == null) {
1654 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1657 failedNwList.add(String.format("input network %s associated to a another vpn %s instead " +
1658 "of the one given as input", nw.getValue(), vpnId.getValue()));
1661 if (NeutronvpnUtils.getIsExternal(network)) {
1662 nvpnNatManager.removeExternalNetworkFromVpn(network);
1666 clearFromVpnMaps(vpn, null, passedNwList);
1668 return failedNwList;
1672 * It handles the invocations to the neutronvpn:associateNetworks RPC method
1674 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateNetworks
1675 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateNetworksInput)
1678 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1680 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1681 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1682 LOG.debug("associateNetworks {}", input);
1683 StringBuilder returnMsg = new StringBuilder();
1684 Uuid vpnId = input.getVpnId();
1687 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1688 List<Uuid> netIds = input.getNetworkId();
1689 if (netIds != null && !netIds.isEmpty()) {
1690 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1691 if (!failed.isEmpty()) {
1692 returnMsg.append(failed);
1696 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1698 if (returnMsg.length() != 0) {
1699 String message = String.format("associate Networks to vpn %s failed due to %s",
1700 vpnId.getValue(), returnMsg);
1702 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1704 opBuilder.setResponse(errorResponse);
1705 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().withResult(opBuilder.build()).build());
1707 result.set(RpcResultBuilder.<AssociateNetworksOutput> success().build());
1709 } catch (Exception ex) {
1710 String message = String.format("associate Networks to vpn %s failed due to %s",
1711 input.getVpnId().getValue(), ex.getMessage());
1712 LOG.error(message, ex);
1713 result.set(RpcResultBuilder.<AssociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1716 LOG.debug("associateNetworks returns..");
1721 * It handles the invocations to the neutronvpn:associateRouter RPC method
1723 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#associateRouter
1724 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.AssociateRouterInput)
1727 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1729 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1730 LOG.debug("associateRouter {}", input);
1731 StringBuilder returnMsg = new StringBuilder();
1732 Uuid vpnId = input.getVpnId();
1733 Uuid routerId = input.getRouterId();
1735 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1736 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1737 if (vpnMap != null) {
1739 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1740 if (vpnMap.getRouterId() != null) {
1741 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1742 .append(vpnMap.getRouterId().getValue());
1743 } else if (extVpnId != null) {
1744 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to " +
1745 "another VPN ").append(extVpnId.getValue());
1747 associateRouterToVpn(vpnId, routerId);
1750 returnMsg.append("router not found : ").append(routerId.getValue());
1753 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1755 if (returnMsg.length() != 0) {
1756 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1759 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1762 result.set(RpcResultBuilder.<Void> success().build());
1764 } catch (Exception ex) {
1765 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1766 vpnId.getValue(), ex.getMessage());
1767 LOG.error(message, ex);
1768 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1770 LOG.debug("associateRouter returns..");
1774 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method
1776 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService#getFixedIPsForNeutronPort
1777 * (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInput)
1780 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(GetFixedIPsForNeutronPortInput input) {
1781 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1782 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1783 Uuid portId = input.getPortId();
1784 StringBuilder returnMsg = new StringBuilder();
1786 List<String> fixedIPList = new ArrayList<>();
1787 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1789 List<FixedIps> fixedIPs = port.getFixedIps();
1790 for (FixedIps ip : fixedIPs) {
1791 fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
1794 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1796 if (returnMsg.length() != 0) {
1797 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1799 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1800 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1802 opBuilder.setFixedIPs(fixedIPList);
1803 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().withResult(opBuilder.build())
1805 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> success().build());
1807 } catch (Exception ex) {
1808 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1809 portId.getValue(), ex.getMessage());
1810 LOG.error(message, ex);
1811 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput> failed()
1812 .withError(ErrorType.APPLICATION, message).build());
1818 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method
1820 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1821 * .rev150602.NeutronvpnService#dissociateNetworks(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1822 * .neutronvpn.rev150602.DissociateNetworksInput)
1825 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1827 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1828 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1830 LOG.debug("dissociateNetworks {}", input);
1831 StringBuilder returnMsg = new StringBuilder();
1832 Uuid vpnId = input.getVpnId();
1835 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1836 List<Uuid> netIds = input.getNetworkId();
1837 if (netIds != null && !netIds.isEmpty()) {
1838 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1839 if (!failed.isEmpty()) {
1840 returnMsg.append(failed);
1844 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1846 if (returnMsg.length() != 0) {
1847 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1850 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1852 opBuilder.setResponse(errorResponse);
1853 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().withResult(opBuilder.build()).build());
1855 result.set(RpcResultBuilder.<DissociateNetworksOutput> success().build());
1857 } catch (Exception ex) {
1858 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1859 input.getVpnId().getValue(), ex.getMessage());
1860 LOG.error(message, ex);
1861 result.set(RpcResultBuilder.<DissociateNetworksOutput> failed().withError(ErrorType.APPLICATION, message)
1864 LOG.debug("dissociateNetworks returns..");
1869 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1871 * @see org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1872 * .rev150602.NeutronvpnService#dissociateRouter(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1873 * .rev150602.DissociateRouterInput)
1876 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1878 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1880 LOG.debug("dissociateRouter {}", input);
1881 StringBuilder returnMsg = new StringBuilder();
1882 Uuid vpnId = input.getVpnId();
1883 Uuid routerId = input.getRouterId();
1885 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1886 if (routerId != null) {
1887 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1889 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1890 if (vpnId.equals(routerVpnId)) {
1891 dissociateRouterFromVpn(vpnId, routerId);
1893 if (routerVpnId == null) {
1894 returnMsg.append("input router ").append(routerId.getValue()).append(" not associated" +
1897 returnMsg.append("input router ").append(routerId.getValue()).append(" associated to " +
1898 "vpn ").append(routerVpnId.getValue()).append("instead of the vpn given as " +
1903 returnMsg.append("router not found : ").append(routerId.getValue());
1907 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1909 if (returnMsg.length() != 0) {
1910 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1911 vpnId.getValue(), returnMsg);
1913 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1915 result.set(RpcResultBuilder.<Void> failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1918 result.set(RpcResultBuilder.<Void> success().build());
1920 } catch (Exception ex) {
1921 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1922 vpnId.getValue(), ex.getMessage());
1923 LOG.error(message, ex);
1924 result.set(RpcResultBuilder.<Void> failed().withError(ErrorType.APPLICATION, message).build());
1926 LOG.debug("dissociateRouter returns..");
1931 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1932 // check if the router is associated to some VPN
1933 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1934 if (vpnId != null) {
1935 // remove existing external vpn interfaces
1936 for (Uuid subnetId : routerSubnetIds) {
1937 removeSubnetFromVpn(vpnId, subnetId);
1939 clearFromVpnMaps(vpnId, routerId, null);
1941 // remove existing internal vpn interfaces
1942 for (Uuid subnetId : routerSubnetIds) {
1943 removeSubnetFromVpn(routerId, subnetId);
1946 // delete entire vpnMaps node for internal VPN
1947 deleteVpnMapsNode(routerId);
1949 // delete vpn-instance for internal VPN
1950 deleteVpnInstance(routerId);
1953 protected Subnet getNeutronSubnet(Uuid subnetId){
1954 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1957 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1958 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1960 return sn.getGatewayIp();
1966 protected Network getNeutronNetwork(Uuid networkId) {
1967 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1970 protected Port getNeutronPort(String name) {
1971 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1974 protected Port getNeutronPort(Uuid portId) {
1975 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1978 protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1979 List<Uuid> subnets = new ArrayList<>();
1981 InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1982 Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1984 if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1985 List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1986 for (Subnetmap subnetMap : subnetMapList) {
1987 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1988 subnets.add(subnetMap.getId());
1996 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command
1998 * @return a List of String to be printed on screen
2000 public List<String> showNeutronPortsCLI() {
2001 List<String> result = new ArrayList<>();
2002 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length", "IP " +
2004 result.add("-------------------------------------------------------------------------------------------");
2005 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
2007 Optional<Ports> ports = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
2008 if (ports.isPresent() && ports.get().getPort() != null) {
2009 for (Port port : ports.get().getPort()) {
2010 List<FixedIps> fixedIPs = port.getFixedIps();
2012 if (fixedIPs != null && !fixedIPs.isEmpty()) {
2013 List<String> ipList = new ArrayList<>();
2014 for (FixedIps fixedIp : fixedIPs) {
2015 IpAddress ipAddress = fixedIp.getIpAddress();
2016 if (ipAddress.getIpv4Address() != null) {
2017 ipList.add(ipAddress.getIpv4Address().getValue());
2019 ipList.add((ipAddress.getIpv6Address().getValue()));
2022 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2023 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
2024 ipList.toString()));
2026 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
2027 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
2029 } catch (Exception e) {
2030 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
2032 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
2033 .getValue() + ": " + e.getMessage());
2037 } catch (Exception e) {
2038 LOG.error("Failed to retrieve neutronPorts info : ", e);
2039 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2045 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command
2047 * @param vpnuuid Uuid of the VPN whose config must be shown
2048 * @return formatted output list
2050 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2051 List<String> result = new ArrayList<>();
2052 if (vpnuuid == null) {
2053 System.out.println("");
2054 System.out.println("Displaying VPN config for all VPNs");
2055 System.out.println("To display VPN config for a particular VPN, use the following syntax");
2056 System.out.println(getshowVpnConfigCLIHelp());
2059 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2060 if (rpcResult.isSuccessful()) {
2062 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2064 result.add(String.format(" %-80s ", "Import-RTs"));
2066 result.add(String.format(" %-80s ", "Export-RTs"));
2068 result.add(String.format(" %-76s ", "Subnet IDs"));
2070 result.add("------------------------------------------------------------------------------------");
2072 List<L3vpnInstances> VpnList = rpcResult.getResult().getL3vpnInstances();
2073 for (L3vpnInstance Vpn : VpnList) {
2074 String tenantId = Vpn.getTenantId() != null ? Vpn.getTenantId().getValue()
2076 result.add(String.format(" %-37s %-37s %-7s ", Vpn.getId().getValue(), tenantId,
2077 Vpn.getRouteDistinguisher()));
2079 result.add(String.format(" %-80s ", Vpn.getImportRT()));
2081 result.add(String.format(" %-80s ", Vpn.getExportRT()));
2084 Uuid vpnid = Vpn.getId();
2085 List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2086 if (!subnetList.isEmpty()) {
2087 for (Uuid subnetuuid : subnetList) {
2088 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2091 result.add(String.format(" %-76s ", "\" \""));
2094 result.add("----------------------------------------");
2098 String errortag = rpcResult.getErrors().iterator().next().getTag();
2099 if (errortag == "") {
2100 System.out.println("");
2101 System.out.println("No VPN has been configured yet");
2102 } else if (errortag == "invalid-value") {
2103 System.out.println("");
2104 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2106 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2107 System.out.println(getshowVpnConfigCLIHelp());
2110 } catch (InterruptedException | ExecutionException e) {
2111 LOG.error("error getting VPN info : ", e);
2112 System.out.println("error getting VPN info : " + e.getMessage());
2117 protected void createExternalVpnInterfaces(Uuid extNetId) {
2118 if (extNetId == null) {
2119 LOG.trace("external network is null");
2123 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2124 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2125 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2129 for (String elanInterface : extElanInterfaces) {
2130 createExternalVpnInterface(extNetId, elanInterface);
2134 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2135 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2136 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2137 LOG.trace("No external ports attached for external network {}", extNetId);
2141 for (String elanInterface : extElanInterfaces) {
2142 boolean isLockAcquired = false;
2143 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2144 .buildVpnInterfaceIdentifier(elanInterface);
2146 isLockAcquired = NeutronvpnUtils.lock(elanInterface);
2147 LOG.debug("removing vpn interface {}, vpnIfIdentifier", elanInterface, vpnIfIdentifier);
2148 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2149 } catch (Exception ex) {
2150 LOG.error("Removal of vpninterface {} failed due to {}", elanInterface, ex);
2152 if (isLockAcquired) {
2153 NeutronvpnUtils.unlock(elanInterface);
2159 private void createExternalVpnInterface(Uuid vpnId, String infName) {
2160 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, null);
2163 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2164 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2165 if (vpnId == null || infName == null) {
2166 LOG.debug("vpn id or interface is null");
2170 Boolean wrtConfigTxnPresent = true;
2171 if (wrtConfigTxn == null) {
2172 wrtConfigTxnPresent = false;
2173 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2176 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2177 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2179 .setVpnInstanceName(vpnId.getValue())
2180 .setIsRouterInterface(isRouterInterface);
2181 if (adjacencies != null) {
2182 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2184 VpnInterface vpnIf = vpnb.build();
2186 LOG.info("Creating vpn interface {}", vpnIf);
2187 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2188 } catch (Exception ex) {
2189 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2192 if (!wrtConfigTxnPresent) {
2193 wrtConfigTxn.submit();
2197 private String getshowVpnConfigCLIHelp() {
2198 StringBuilder help = new StringBuilder("Usage:");
2199 help.append("display vpn-config [-vid/--vpnid <id>]");
2200 return help.toString();
2203 private void checkAndPublishSubnetAddNotification(Uuid subnetId, String subnetIp, String vpnName,
2204 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2205 SubnetAddedToVpnBuilder builder = new SubnetAddedToVpnBuilder();
2207 LOG.info("publish notification called");
2209 builder.setSubnetId(subnetId);
2210 builder.setSubnetIp(subnetIp);
2211 builder.setVpnName(vpnName);
2212 builder.setExternalVpn(isExternalvpn);
2213 builder.setElanTag(elanTag);
2215 notificationPublishService.putNotification(builder.build());
2218 private void checkAndPublishSubnetDelNotification(Uuid subnetId, String subnetIp, String vpnName,
2219 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2220 SubnetDeletedFromVpnBuilder builder = new SubnetDeletedFromVpnBuilder();
2222 LOG.info("publish notification called");
2224 builder.setSubnetId(subnetId);
2225 builder.setSubnetIp(subnetIp);
2226 builder.setVpnName(vpnName);
2227 builder.setExternalVpn(isExternalvpn);
2228 builder.setElanTag(elanTag);
2230 notificationPublishService.putNotification(builder.build());
2233 private void checkAndPublishSubnetUpdNotification(Uuid subnetId, String subnetIp, String vpnName,
2234 Boolean isExternalvpn, Long elanTag) throws InterruptedException {
2235 SubnetUpdatedInVpnBuilder builder = new SubnetUpdatedInVpnBuilder();
2237 LOG.info("publish notification called");
2239 builder.setSubnetId(subnetId);
2240 builder.setSubnetIp(subnetIp);
2241 builder.setVpnName(vpnName);
2242 builder.setExternalVpn(isExternalvpn);
2243 builder.setElanTag(elanTag);
2245 notificationPublishService.putNotification(builder.build());
2248 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2249 InterruptedException {
2250 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2251 .setVpnId(vpnId).build();
2252 LOG.info("publishing notification upon association of router to VPN");
2253 notificationPublishService.putNotification(routerAssociatedToVpn);
2256 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2257 InterruptedException {
2258 RouterDisassociatedFromVpn routerDisassociatedFromVpn = new RouterDisassociatedFromVpnBuilder().setRouterId
2259 (routerId).setVpnId(vpnId).build();
2260 LOG.info("publishing notification upon disassociation of router from VPN");
2261 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2264 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2265 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);