2 * Copyright © 2015, 2017 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 com.google.common.base.Optional;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import com.google.common.util.concurrent.SettableFuture;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.EventListener;
18 import java.util.HashMap;
19 import java.util.Iterator;
20 import java.util.List;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.Future;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
26 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
29 import org.opendaylight.genius.mdsalutil.MDSALUtil;
30 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
31 import org.opendaylight.netvirt.elanmanager.api.IElanService;
32 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
33 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
34 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
35 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargets;
36 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.VpnTargetsBuilder;
37 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
38 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetBuilder;
39 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTargetKey;
40 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
41 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceBuilder;
42 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
43 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
44 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
45 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
46 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.AdjacencyKey;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
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.Subnetmaps;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createl3vpn.input.L3vpn;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstances;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getl3vpn.output.L3vpnInstancesBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfacesKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteInputBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.AddStaticRouteOutput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.RemoveStaticRouteInputBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.VpnRpcService;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
116 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
117 import org.opendaylight.yangtools.yang.common.RpcError;
118 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
119 import org.opendaylight.yangtools.yang.common.RpcResult;
120 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
121 import org.slf4j.Logger;
122 import org.slf4j.LoggerFactory;
124 public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, EventListener {
125 private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnManager.class);
126 private final DataBroker dataBroker;
127 private final NeutronvpnNatManager nvpnNatManager;
128 private final NotificationPublishService notificationPublishService;
129 private final VpnRpcService vpnRpcService;
130 private final NeutronFloatingToFixedIpMappingChangeListener floatingIpMapListener;
131 private final NeutronvpnConfig neutronvpnConfig;
132 private final IMdsalApiManager mdsalUtil;
133 private final IElanService elanService;
135 public NeutronvpnManager(
136 final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
137 final NotificationPublishService notiPublishService, final NeutronvpnNatManager vpnNatMgr,
138 final VpnRpcService vpnRpcSrv, final IElanService elanService,
139 final NeutronFloatingToFixedIpMappingChangeListener neutronFloatingToFixedIpMappingChangeListener,
140 final NeutronvpnConfig neutronvpnConfig) {
141 this.dataBroker = dataBroker;
142 mdsalUtil = mdsalManager;
143 nvpnNatManager = vpnNatMgr;
144 notificationPublishService = notiPublishService;
145 vpnRpcService = vpnRpcSrv;
146 this.elanService = elanService;
147 floatingIpMapListener = neutronFloatingToFixedIpMappingChangeListener;
148 LOG.info("neutronvpnConfig: {}", neutronvpnConfig);
149 this.neutronvpnConfig = neutronvpnConfig;
153 public void close() throws Exception {
154 LOG.info("{} close", getClass().getSimpleName());
157 public NeutronvpnConfig getNeutronvpnConfig() {
158 return neutronvpnConfig;
161 // TODO Clean up the exception handling
162 @SuppressWarnings("checkstyle:IllegalCatch")
163 protected void updateSubnetNodeWithFixedIps(Uuid subnetId, Uuid routerId,
164 Uuid routerInterfaceName, String fixedIp,
165 String routerIntfMacAddress) {
166 Subnetmap subnetmap = null;
167 SubnetmapBuilder builder = null;
168 InstanceIdentifier<Subnetmap> id =
169 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
171 synchronized (subnetId.getValue().intern()) {
172 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
173 if (sn.isPresent()) {
174 builder = new SubnetmapBuilder(sn.get());
175 LOG.debug("WithRouterFixedIPs: Updating existing subnetmap node for subnet ID {}",
176 subnetId.getValue());
178 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
179 LOG.debug("WithRouterFixedIPs: creating new subnetmap node for subnet ID {}",
180 subnetId.getValue());
183 builder.setRouterId(routerId);
184 builder.setRouterInterfaceName(routerInterfaceName);
185 builder.setRouterIntfMacAddress(routerIntfMacAddress);
187 if (fixedIp != null) {
188 List<String> fixedIps = builder.getRouterInterfaceFixedIps();
189 if (fixedIps == null) {
190 fixedIps = new ArrayList<>();
192 fixedIps.add(fixedIp);
193 builder.setRouterInterfaceFixedIps(fixedIps);
195 builder.setRouterInterfaceFixedIps(null);
197 subnetmap = builder.build();
198 LOG.debug("WithRouterFixedIPs Creating/Updating subnetMap node for Router FixedIps: {} ",
199 subnetId.getValue());
200 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
202 } catch (Exception e) {
203 LOG.error("WithRouterFixedIPs: Updation of subnetMap for Router FixedIps failed for node: {}",
204 subnetId.getValue());
208 // TODO Clean up the exception handling
209 @SuppressWarnings("checkstyle:IllegalCatch")
210 protected Subnetmap updateSubnetNode(Uuid subnetId, String subnetIp, Uuid tenantId, Uuid networkId, Uuid routerId,
212 Subnetmap subnetmap = null;
213 SubnetmapBuilder builder = null;
214 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
215 .child(Subnetmap.class, new SubnetmapKey(subnetId))
218 synchronized (subnetId.getValue().intern()) {
219 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
220 if (sn.isPresent()) {
221 builder = new SubnetmapBuilder(sn.get());
222 LOG.debug("updating existing subnetmap node for subnet ID {}", subnetId.getValue());
224 builder = new SubnetmapBuilder().setKey(new SubnetmapKey(subnetId)).setId(subnetId);
225 LOG.debug("creating new subnetmap node for subnet ID {}", subnetId.getValue());
228 if (subnetIp != null) {
229 builder.setSubnetIp(subnetIp);
231 if (routerId != null) {
232 builder.setRouterId(routerId);
234 if (networkId != null) {
235 builder.setNetworkId(networkId);
238 builder.setVpnId(vpnId);
240 if (tenantId != null) {
241 builder.setTenantId(tenantId);
244 subnetmap = builder.build();
245 LOG.debug("Creating/Updating subnetMap node: {} ", subnetId.getValue());
246 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
248 } catch (Exception e) {
249 LOG.error("Updation of subnetMap failed for node: {}", subnetId.getValue());
254 // TODO Clean up the exception handling
255 @SuppressWarnings("checkstyle:IllegalCatch")
256 protected Subnetmap removeFromSubnetNode(Uuid subnetId, Uuid networkId, Uuid routerId, Uuid vpnId, Uuid portId) {
257 Subnetmap subnetmap = null;
258 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class)
259 .child(Subnetmap.class, new SubnetmapKey(subnetId))
262 synchronized (subnetId.getValue().intern()) {
263 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
264 if (sn.isPresent()) {
265 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
266 if (routerId != null) {
267 builder.setRouterId(null);
269 if (networkId != null) {
270 builder.setNetworkId(null);
273 builder.setVpnId(null);
275 if (portId != null && builder.getPortList() != null) {
276 List<Uuid> portList = builder.getPortList();
277 portList.remove(portId);
278 builder.setPortList(portList);
281 subnetmap = builder.build();
282 LOG.debug("Removing from existing subnetmap node: {} ", subnetId.getValue());
283 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
285 LOG.warn("removing from non-existing subnetmap node: {} ", subnetId.getValue());
288 } catch (Exception e) {
289 LOG.error("Removal from subnetmap failed for node: {}", subnetId.getValue());
294 // TODO Clean up the exception handling
295 @SuppressWarnings("checkstyle:IllegalCatch")
296 protected Subnetmap updateSubnetmapNodeWithPorts(Uuid subnetId, Uuid portId, Uuid directPortId) {
297 Subnetmap subnetmap = null;
298 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
299 new SubnetmapKey(subnetId)).build();
301 synchronized (subnetId.getValue().intern()) {
302 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
303 if (sn.isPresent()) {
304 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
305 if (null != portId) {
306 List<Uuid> portList = builder.getPortList();
307 if (null == portList) {
308 portList = new ArrayList<>();
310 portList.add(portId);
311 builder.setPortList(portList);
312 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
315 if (null != directPortId) {
316 List<Uuid> directPortList = builder.getDirectPortList();
317 if (null == directPortList) {
318 directPortList = new ArrayList<>();
320 directPortList.add(directPortId);
321 builder.setDirectPortList(directPortList);
322 LOG.debug("Updating existing subnetmap node {} with port {}", subnetId.getValue(),
323 directPortId.getValue());
325 subnetmap = builder.build();
326 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
328 LOG.error("Trying to update non-existing subnetmap node {} ", subnetId.getValue());
331 } catch (Exception e) {
332 LOG.error("Updating port list of a given subnetMap failed for node: {} with exception{}",
333 subnetId.getValue(), e);
338 // TODO Clean up the exception handling
339 @SuppressWarnings("checkstyle:IllegalCatch")
340 protected Subnetmap removePortsFromSubnetmapNode(Uuid subnetId, Uuid portId, Uuid directPortId) {
341 Subnetmap subnetmap = null;
342 InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,
343 new SubnetmapKey(subnetId)).build();
345 synchronized (subnetId.getValue().intern()) {
346 Optional<Subnetmap> sn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
347 if (sn.isPresent()) {
348 SubnetmapBuilder builder = new SubnetmapBuilder(sn.get());
349 if (null != portId && null != builder.getPortList()) {
350 List<Uuid> portList = builder.getPortList();
351 portList.remove(portId);
352 builder.setPortList(portList);
353 LOG.debug("Removing port {} from existing subnetmap node: {} ", portId.getValue(),
354 subnetId.getValue());
356 if (null != directPortId && null != builder.getDirectPortList()) {
357 List<Uuid> directPortList = builder.getDirectPortList();
358 directPortList.remove(directPortId);
359 builder.setDirectPortList(directPortList);
360 LOG.debug("Removing direct port {} from existing subnetmap node: {} ", directPortId
361 .getValue(), subnetId.getValue());
363 subnetmap = builder.build();
364 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, id, subnetmap);
366 LOG.error("Trying to remove port from non-existing subnetmap node {}", subnetId.getValue());
369 } catch (Exception e) {
370 LOG.error("Removing a port from port list of a subnetmap failed for node: {} with expection {}",
371 subnetId.getValue(), e);
376 // TODO Clean up the exception handling
377 @SuppressWarnings("checkstyle:IllegalCatch")
378 protected void deleteSubnetMapNode(Uuid subnetId) {
379 InstanceIdentifier<Subnetmap> subnetMapIdentifier =
380 InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class,new SubnetmapKey(subnetId)).build();
381 LOG.debug("removing subnetMap node: {} ", subnetId.getValue());
383 synchronized (subnetId.getValue().intern()) {
384 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetMapIdentifier);
386 } catch (Exception e) {
387 LOG.error("Delete subnetMap node failed for subnet : {} ", subnetId.getValue());
391 // TODO Clean up the exception handling
392 @SuppressWarnings("checkstyle:IllegalCatch")
393 private void updateVpnInstanceNode(String vpnName, List<String> rd, List<String> irt, List<String> ert) {
395 VpnInstanceBuilder builder = null;
396 List<VpnTarget> vpnTargetList = new ArrayList<>();
397 boolean isLockAcquired = false;
398 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
399 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
401 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
403 LOG.debug("Creating/Updating a new vpn-instance node: {} ", vpnName);
404 if (optionalVpn.isPresent()) {
405 builder = new VpnInstanceBuilder(optionalVpn.get());
406 LOG.debug("updating existing vpninstance node");
408 builder = new VpnInstanceBuilder().setKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName);
410 if (irt != null && !irt.isEmpty()) {
411 if (ert != null && !ert.isEmpty()) {
412 List<String> commonRT = new ArrayList<>(irt);
413 commonRT.retainAll(ert);
415 for (String common : commonRT) {
418 VpnTarget vpnTarget =
419 new VpnTargetBuilder().setKey(new VpnTargetKey(common)).setVrfRTValue(common)
420 .setVrfRTType(VpnTarget.VrfRTType.Both).build();
421 vpnTargetList.add(vpnTarget);
424 for (String importRT : irt) {
425 VpnTarget vpnTarget =
426 new VpnTargetBuilder().setKey(new VpnTargetKey(importRT)).setVrfRTValue(importRT)
427 .setVrfRTType(VpnTarget.VrfRTType.ImportExtcommunity).build();
428 vpnTargetList.add(vpnTarget);
432 if (ert != null && !ert.isEmpty()) {
433 for (String exportRT : ert) {
434 VpnTarget vpnTarget =
435 new VpnTargetBuilder().setKey(new VpnTargetKey(exportRT)).setVrfRTValue(exportRT)
436 .setVrfRTType(VpnTarget.VrfRTType.ExportExtcommunity).build();
437 vpnTargetList.add(vpnTarget);
441 VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
443 Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
445 if (rd != null && !rd.isEmpty()) {
446 ipv4vpnBuilder.setRouteDistinguisher(rd.get(0));
449 VpnInstance newVpn = builder.setIpv4Family(ipv4vpnBuilder.build()).build();
450 isLockAcquired = NeutronvpnUtils.lock(vpnName);
451 LOG.debug("Creating/Updating vpn-instance for {} ", vpnName);
452 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier, newVpn);
453 } catch (Exception e) {
454 LOG.error("Update VPN Instance node failed for node: {} {} {} {}", vpnName, rd, irt, ert);
456 if (isLockAcquired) {
457 NeutronvpnUtils.unlock(vpnName);
462 // TODO Clean up the exception handling
463 @SuppressWarnings("checkstyle:IllegalCatch")
464 private void deleteVpnMapsNode(Uuid vpnid) {
465 boolean isLockAcquired = false;
466 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
467 .child(VpnMap.class, new VpnMapKey(vpnid))
469 LOG.debug("removing vpnMaps node: {} ", vpnid.getValue());
471 isLockAcquired = NeutronvpnUtils.lock(vpnid.getValue());
472 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
473 } catch (Exception e) {
474 LOG.error("Delete vpnMaps node failed for vpn : {} ", vpnid.getValue());
476 if (isLockAcquired) {
477 NeutronvpnUtils.unlock(vpnid.getValue());
482 // TODO Clean up the exception handling
483 @SuppressWarnings("checkstyle:IllegalCatch")
484 private void updateVpnMaps(Uuid vpnId, String name, Uuid router, Uuid tenantId, List<Uuid> networks) {
485 VpnMapBuilder builder;
486 boolean isLockAcquired = false;
487 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
488 .child(VpnMap.class, new VpnMapKey(vpnId))
491 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
493 if (optionalVpnMap.isPresent()) {
494 builder = new VpnMapBuilder(optionalVpnMap.get());
496 builder = new VpnMapBuilder().setKey(new VpnMapKey(vpnId)).setVpnId(vpnId);
500 builder.setName(name);
502 if (tenantId != null) {
503 builder.setTenantId(tenantId);
505 if (router != null) {
506 builder.setRouterId(router);
508 if (networks != null) {
509 List<Uuid> nwList = builder.getNetworkIds();
510 if (nwList == null) {
511 nwList = new ArrayList<>();
513 nwList.addAll(networks);
514 builder.setNetworkIds(nwList);
517 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
518 LOG.debug("Creating/Updating vpnMaps node: {} ", vpnId.getValue());
519 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier, builder.build());
520 LOG.debug("VPNMaps DS updated for VPN {} ", vpnId.getValue());
521 } catch (Exception e) {
522 LOG.error("UpdateVpnMaps failed for node: {} ", vpnId.getValue());
524 if (isLockAcquired) {
525 NeutronvpnUtils.unlock(vpnId.getValue());
530 // TODO Clean up the exception handling
531 @SuppressWarnings("checkstyle:IllegalCatch")
532 private void clearFromVpnMaps(Uuid vpnId, Uuid routerId, List<Uuid> networkIds) {
533 boolean isLockAcquired = false;
534 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
535 .child(VpnMap.class, new VpnMapKey(vpnId))
537 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
539 if (optionalVpnMap.isPresent()) {
540 VpnMap vpnMap = optionalVpnMap.get();
541 VpnMapBuilder vpnMapBuilder = new VpnMapBuilder(vpnMap);
542 if (routerId != null) {
543 if (vpnMap.getNetworkIds() == null && routerId.equals(vpnMap.getVpnId())) {
545 // remove entire node in case of internal VPN
546 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
547 LOG.debug("removing vpnMaps node: {} ", vpnId);
548 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
549 } catch (Exception e) {
550 LOG.error("Deletion of vpnMaps node failed for vpn {}", vpnId.getValue());
552 if (isLockAcquired) {
553 NeutronvpnUtils.unlock(vpnId.getValue());
558 vpnMapBuilder.setRouterId(null);
560 if (networkIds != null) {
561 List<Uuid> vpnNw = vpnMap.getNetworkIds();
562 for (Uuid nw : networkIds) {
565 if (vpnNw.isEmpty()) {
566 LOG.debug("setting networks null in vpnMaps node: {} ", vpnId.getValue());
567 vpnMapBuilder.setNetworkIds(null);
569 vpnMapBuilder.setNetworkIds(vpnNw);
574 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
575 LOG.debug("clearing from vpnMaps node: {} ", vpnId.getValue());
576 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier,
577 vpnMapBuilder.build());
578 } catch (Exception e) {
579 LOG.error("Clearing from vpnMaps node failed for vpn {}", vpnId.getValue());
581 if (isLockAcquired) {
582 NeutronvpnUtils.unlock(vpnId.getValue());
586 LOG.error("VPN : {} not found", vpnId.getValue());
588 LOG.debug("Clear from VPNMaps DS successful for VPN {} ", vpnId.getValue());
591 // TODO Clean up the exception handling
592 @SuppressWarnings("checkstyle:IllegalCatch")
593 private void deleteVpnInstance(Uuid vpnId) {
594 boolean isLockAcquired = false;
595 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
596 .child(VpnInstance.class,
597 new VpnInstanceKey(vpnId.getValue()))
600 isLockAcquired = NeutronvpnUtils.lock(vpnId.getValue());
601 LOG.debug("Deleting vpnInstance {}", vpnId.getValue());
602 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
603 } catch (Exception e) {
604 LOG.error("Deletion of VPNInstance node failed for VPN {}", vpnId.getValue());
606 if (isLockAcquired) {
607 NeutronvpnUtils.unlock(vpnId.getValue());
612 protected void createVpnInterface(Uuid vpnId, Uuid routerId, Port port,
613 WriteTransaction wrtConfigTxn) {
614 String infName = port.getUuid().getValue();
615 List<Adjacency> adjList = new ArrayList<>();
616 Boolean isRouterInterface = false;
617 if (port.getDeviceOwner() != null) {
618 isRouterInterface = port.getDeviceOwner().equals(NeutronConstants.DEVICE_OWNER_ROUTER_INF);
620 LOG.trace("createVpnInterface - isRouterInterface:{}", isRouterInterface);
622 if (routerId != null) {
623 rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
625 List<FixedIps> ips = port.getFixedIps();
626 // create adjacency list
627 for (FixedIps ip : ips) {
628 // create vm adjacency
629 String ipValue = String.valueOf(ip.getIpAddress().getValue());
630 String ipPrefix = (ip.getIpAddress().getIpv4Address() != null) ? ipValue + "/32" : ipValue + "/128";
631 Adjacency vmAdj = new AdjacencyBuilder().setKey(new AdjacencyKey(ipPrefix)).setIpAddress(ipPrefix)
632 .setMacAddress(port.getMacAddress().getValue()).setPrimaryAdjacency(true)
633 .setSubnetId(ip.getSubnetId()).build();
635 // create extra route adjacency
636 if (rtr != null && rtr.getRoutes() != null) {
637 List<Routes> routeList = rtr.getRoutes();
638 List<Adjacency> erAdjList = getAdjacencyforExtraRoute(vpnId, routeList, ipValue);
639 if (erAdjList != null && !erAdjList.isEmpty()) {
640 adjList.addAll(erAdjList);
643 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
644 .getMacAddress().getValue(), isRouterInterface, wrtConfigTxn);
646 // create vpn-interface on this neutron port
647 Adjacencies adjs = new AdjacenciesBuilder().setAdjacency(adjList).build();
648 writeVpnInterfaceToDs(vpnId, infName, adjs, isRouterInterface, wrtConfigTxn);
649 if (routerId != null) {
650 addToNeutronRouterInterfacesMap(routerId, infName);
654 // TODO Clean up the exception handling
655 @SuppressWarnings("checkstyle:IllegalCatch")
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(),
672 ipValue, wrtConfigTxn);
674 } catch (Exception ex) {
675 LOG.error("Deletion of vpninterface {} failed due to {}", infName, ex);
677 if (routerId != null) {
678 removeFromNeutronRouterInterfacesMap(routerId, infName);
680 if (!wrtConfigTxnPresent) {
681 wrtConfigTxn.submit();
685 // TODO Clean up the exception handling
686 @SuppressWarnings("checkstyle:IllegalCatch")
687 protected void updateVpnInterface(Uuid vpnId, Uuid oldVpnId, Port port, boolean isBeingAssociated,
688 boolean isSubnetIp) {
689 if (vpnId == null || port == null) {
692 boolean isLockAcquired = false;
693 String infName = port.getUuid().getValue();
694 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
697 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
698 isLockAcquired = NeutronvpnUtils.lock(infName);
699 Optional<VpnInterface> optionalVpnInterface = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
700 .CONFIGURATION, vpnIfIdentifier);
701 if (optionalVpnInterface.isPresent()) {
702 VpnInterfaceBuilder vpnIfBuilder = new VpnInterfaceBuilder(optionalVpnInterface.get())
703 .setVpnInstanceName(vpnId.getValue());
704 LOG.debug("Updating vpn interface {}", infName);
705 if (!isBeingAssociated) {
706 Adjacencies adjs = vpnIfBuilder.getAugmentation(Adjacencies.class);
707 List<Adjacency> adjacencyList = (adjs != null) ? adjs.getAdjacency() : new ArrayList<>();
708 Iterator<Adjacency> adjacencyIter = adjacencyList.iterator();
709 while (adjacencyIter.hasNext()) {
710 Adjacency adjacency = adjacencyIter.next();
711 String mipToQuery = adjacency.getIpAddress().split("/")[0];
712 InstanceIdentifier<LearntVpnVipToPort> id =
713 NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(oldVpnId.getValue(), mipToQuery);
714 Optional<LearntVpnVipToPort> optionalVpnVipToPort =
715 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
716 if (optionalVpnVipToPort.isPresent()) {
717 LOG.trace("Removing adjacencies from vpninterface {} upon dissociation of router {} "
718 + "from VPN " + "{}", infName, vpnId, oldVpnId);
719 adjacencyIter.remove();
720 NeutronvpnUtils.removeLearntVpnVipToPort(dataBroker, oldVpnId.getValue(), mipToQuery);
721 LOG.trace("Entry for fixedIP {} for port {} on VPN removed from "
722 + "VpnPortFixedIPToPortData", mipToQuery, infName, vpnId.getValue());
725 Adjacencies adjacencies = new AdjacenciesBuilder().setAdjacency(adjacencyList).build();
726 vpnIfBuilder.addAugmentation(Adjacencies.class, adjacencies);
728 List<FixedIps> ips = port.getFixedIps();
729 for (FixedIps ip : ips) {
730 String ipValue = String.valueOf(ip.getIpAddress().getValue());
731 if (oldVpnId != null) {
732 NeutronvpnUtils.removeVpnPortFixedIpToPort(dataBroker, oldVpnId.getValue(),
733 ipValue, writeConfigTxn);
735 NeutronvpnUtils.createVpnPortFixedIpToPort(dataBroker, vpnId.getValue(), ipValue, infName, port
736 .getMacAddress().getValue(), isSubnetIp, writeConfigTxn);
738 writeConfigTxn.merge(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIfBuilder
740 writeConfigTxn.submit();
742 LOG.error("VPN Interface {} not found", infName);
744 } catch (Exception ex) {
745 LOG.error("Updation of vpninterface {} failed due to {}", infName, ex);
747 if (isLockAcquired) {
748 NeutronvpnUtils.unlock(infName);
753 public void createL3InternalVpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt,
754 List<String> ert, Uuid router, List<Uuid> networks) {
756 // Update VPN Instance node
757 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
759 // Update local vpn-subnet DS
760 updateVpnMaps(vpn, name, router, tenant, networks);
762 if (router != null) {
763 Uuid existingVpn = NeutronvpnUtils.getVpnForRouter(dataBroker, router, true);
764 if (existingVpn != null) {
765 // use case when a cluster is rebooted and router add DCN is received, triggering #createL3InternalVpn
767 // if before reboot, router was already associated to VPN, should not proceed associating router to
768 // internal VPN. Adding to RouterInterfacesMap is also not needed since it's a config DS and will be
769 // preserved upon reboot.
770 // For a non-reboot case #associateRouterToInternalVPN already takes care of adding to
771 // RouterInterfacesMap via #createVPNInterface call.
772 LOG.info("Associating router to Internal VPN skipped for VPN {} due to router {} already associated "
773 + "to external VPN {}", vpn.getValue(), router.getValue(), existingVpn.getValue());
776 associateRouterToInternalVpn(vpn, router);
781 * Performs the creation of a Neutron L3VPN, associating the new VPN to the
782 * specified Neutron Networks and Routers.
784 * @param vpn Uuid of the VPN tp be created
785 * @param name Representative name of the new VPN
786 * @param tenant Uuid of the Tenant under which the VPN is going to be created
787 * @param rd Route-distinguisher for the VPN
788 * @param irt A list of Import Route Targets
789 * @param ert A list of Export Route Targets
790 * @param router UUID of the neutron router the VPN may be associated to
791 * @param networks UUID of the neutron network the VPN may be associated to
792 * @throws Exception if association of L3VPN failed
794 public void createL3Vpn(Uuid vpn, String name, Uuid tenant, List<String> rd, List<String> irt, List<String> ert,
795 Uuid router, List<Uuid> networks) throws Exception {
797 // Update VPN Instance node
798 updateVpnInstanceNode(vpn.getValue(), rd, irt, ert);
800 // Please note that router and networks will be filled into VPNMaps
801 // by subsequent calls here to associateRouterToVpn and
802 // associateNetworksToVpn
803 updateVpnMaps(vpn, name, null, tenant, null);
805 if (router != null) {
806 associateRouterToVpn(vpn, router);
808 if (networks != null) {
809 List<String> failStrings = associateNetworksToVpn(vpn, networks);
810 if (failStrings != null && !failStrings.isEmpty()) {
811 LOG.error("L3VPN {} association to networks failed with error message {}. ",
812 vpn.getValue(), failStrings.get(0));
813 throw new Exception(failStrings.get(0));
819 * It handles the invocations to the createL3VPN RPC method.
822 // TODO Clean up the exception handling
823 @SuppressWarnings("checkstyle:IllegalCatch")
824 public Future<RpcResult<CreateL3VPNOutput>> createL3VPN(CreateL3VPNInput input) {
826 CreateL3VPNOutputBuilder opBuilder = new CreateL3VPNOutputBuilder();
827 SettableFuture<RpcResult<CreateL3VPNOutput>> result = SettableFuture.create();
828 List<RpcError> errorList = new ArrayList<>();
829 int failurecount = 0;
830 int warningcount = 0;
832 List<L3vpn> vpns = input.getL3vpn();
833 for (L3vpn vpn : vpns) {
834 RpcError error = null;
836 if (NeutronvpnUtils.doesVpnExist(dataBroker, vpn.getId())) {
837 msg = String.format("Creation of L3VPN failed for VPN %s due to VPN with the same ID already present",
838 vpn.getId().getValue());
840 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
841 errorList.add(error);
845 if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
846 msg = String.format("Creation of L3VPN failed for VPN %s due to absence of RD/iRT/eRT input",
847 vpn.getId().getValue());
849 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
850 errorList.add(error);
854 if (vpn.getRouteDistinguisher().size() > 1) {
855 msg = String.format("Creation of L3VPN failed for VPN %s due to multiple RD input %s",
856 vpn.getId().getValue(), vpn.getRouteDistinguisher());
858 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
859 errorList.add(error);
863 List<String> existingRDs = NeutronvpnUtils.getExistingRDs(dataBroker);
864 if (existingRDs.contains(vpn.getRouteDistinguisher().get(0))) {
865 msg = String.format("Creation of L3VPN failed for VPN %s as another VPN with the same RD %s "
866 + "is already configured",
867 vpn.getId().getValue(), vpn.getRouteDistinguisher().get(0));
869 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
870 errorList.add(error);
874 if (vpn.getRouterId() != null) {
875 if (NeutronvpnUtils.getNeutronRouter(dataBroker, vpn.getRouterId()) == null) {
876 msg = String.format("Creation of L3VPN failed for VPN %s due to router not found %s",
877 vpn.getId().getValue(), vpn.getRouterId().getValue());
879 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
880 errorList.add(error);
884 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, vpn.getRouterId(), true);
886 msg = String.format("Creation of L3VPN failed for VPN %s due to router %s already associated to "
887 + "another VPN %s", vpn.getId().getValue(), vpn.getRouterId().getValue(),
890 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
891 errorList.add(error);
896 if (vpn.getNetworkIds() != null) {
897 for (Uuid nw : vpn.getNetworkIds()) {
898 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
899 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
900 if (network == null) {
901 msg = String.format("Creation of L3VPN failed for VPN %s due to network not found %s",
902 vpn.getId().getValue(), nw.getValue());
904 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
905 errorList.add(error);
907 } else if (vpnId != null) {
908 msg = String.format("Creation of L3VPN failed for VPN %s due to network %s already associated"
909 + " to another VPN %s", vpn.getId().getValue(), nw.getValue(),
912 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-input", msg);
913 errorList.add(error);
922 createL3Vpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
923 vpn.getImportRT(), vpn.getExportRT(), vpn.getRouterId(), vpn.getNetworkIds());
924 } catch (Exception ex) {
925 msg = String.format("Creation of L3VPN failed for VPN %s", vpn.getId().getValue());
927 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
928 errorList.add(error);
932 // if at least one succeeds; result is success
933 // if none succeeds; result is failure
934 if (failurecount + warningcount == vpns.size()) {
935 result.set(RpcResultBuilder.<CreateL3VPNOutput>failed().withRpcErrors(errorList).build());
937 List<String> errorResponseList = new ArrayList<>();
938 if (!errorList.isEmpty()) {
939 for (RpcError rpcError : errorList) {
940 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
941 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
942 errorResponseList.add(errorResponse);
945 errorResponseList.add("Operation successful with no errors");
947 opBuilder.setResponse(errorResponseList);
948 result.set(RpcResultBuilder.<CreateL3VPNOutput>success().withResult(opBuilder.build()).build());
954 * It handles the invocations to the neutronvpn:getL3VPN RPC method.
957 // TODO Clean up the exception handling
958 @SuppressWarnings("checkstyle:IllegalCatch")
959 public Future<RpcResult<GetL3VPNOutput>> getL3VPN(GetL3VPNInput input) {
961 GetL3VPNOutputBuilder opBuilder = new GetL3VPNOutputBuilder();
962 SettableFuture<RpcResult<GetL3VPNOutput>> result = SettableFuture.create();
963 Uuid inputVpnId = input.getId();
964 List<VpnInstance> vpns = new ArrayList<>();
967 if (inputVpnId == null) {
969 InstanceIdentifier<VpnInstances> vpnsIdentifier = InstanceIdentifier.builder(VpnInstances.class)
971 Optional<VpnInstances> optionalVpns = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
972 .CONFIGURATION, vpnsIdentifier);
973 if (optionalVpns.isPresent() && !optionalVpns.get().getVpnInstance().isEmpty()) {
974 for (VpnInstance vpn : optionalVpns.get().getVpnInstance()) {
975 // eliminating implicitly created (router and VLAN provider external network specific) VPNs
976 // from getL3VPN output
977 if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
983 result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
987 String name = inputVpnId.getValue();
988 InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
989 .child(VpnInstance.class, new VpnInstanceKey(name)).build();
990 // read VpnInstance Info
991 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
993 // eliminating implicitly created (router or VLAN provider external network specific) VPN from
995 if (optionalVpn.isPresent() && optionalVpn.get().getIpv4Family().getRouteDistinguisher() != null) {
996 vpns.add(optionalVpn.get());
998 String message = String.format("GetL3VPN failed because VPN %s is not present", name);
1000 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withWarning(ErrorType.PROTOCOL,
1001 "invalid-value", message).build());
1004 List<L3vpnInstances> l3vpnList = new ArrayList<>();
1005 for (VpnInstance vpnInstance : vpns) {
1006 Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
1007 // create VpnMaps id
1008 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
1009 .class, new VpnMapKey(vpnId)).build();
1010 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
1012 List<String> rd = Arrays.asList(vpnInstance.getIpv4Family().getRouteDistinguisher().split(","));
1013 List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
1015 List<String> ertList = new ArrayList<>();
1016 List<String> irtList = new ArrayList<>();
1018 for (VpnTarget vpnTarget : vpnTargetList) {
1019 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
1020 ertList.add(vpnTarget.getVrfRTValue());
1022 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
1023 irtList.add(vpnTarget.getVrfRTValue());
1025 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
1026 ertList.add(vpnTarget.getVrfRTValue());
1027 irtList.add(vpnTarget.getVrfRTValue());
1031 l3vpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
1032 Optional<VpnMap> optionalVpnMap = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1034 if (optionalVpnMap.isPresent()) {
1035 VpnMap vpnMap = optionalVpnMap.get();
1036 l3vpn.setRouterId(vpnMap.getRouterId()).setNetworkIds(vpnMap.getNetworkIds())
1037 .setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
1039 l3vpnList.add(l3vpn.build());
1042 opBuilder.setL3vpnInstances(l3vpnList);
1043 result.set(RpcResultBuilder.<GetL3VPNOutput>success().withResult(opBuilder.build()).build());
1045 } catch (Exception ex) {
1046 String message = String.format("GetL3VPN failed due to %s", ex.getMessage());
1047 LOG.error(message, ex);
1048 result.set(RpcResultBuilder.<GetL3VPNOutput>failed().withError(ErrorType.APPLICATION, message).build());
1054 * It handles the invocations to the neutronvpn:deleteL3VPN RPC method.
1057 // TODO Clean up the exception handling
1058 @SuppressWarnings("checkstyle:IllegalCatch")
1059 public Future<RpcResult<DeleteL3VPNOutput>> deleteL3VPN(DeleteL3VPNInput input) {
1061 DeleteL3VPNOutputBuilder opBuilder = new DeleteL3VPNOutputBuilder();
1062 SettableFuture<RpcResult<DeleteL3VPNOutput>> result = SettableFuture.create();
1063 List<RpcError> errorList = new ArrayList<>();
1065 int failurecount = 0;
1066 int warningcount = 0;
1067 List<Uuid> vpns = input.getId();
1068 for (Uuid vpn : vpns) {
1072 InstanceIdentifier<VpnInstance> vpnIdentifier =
1073 InstanceIdentifier.builder(VpnInstances.class)
1074 .child(VpnInstance.class, new VpnInstanceKey(vpn.getValue())).build();
1075 Optional<VpnInstance> optionalVpn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1076 .CONFIGURATION, vpnIdentifier);
1077 if (optionalVpn.isPresent()) {
1080 msg = String.format("VPN with vpnid: %s does not exist", vpn.getValue());
1082 error = RpcResultBuilder.newWarning(ErrorType.PROTOCOL, "invalid-value", msg);
1083 errorList.add(error);
1086 } catch (Exception ex) {
1087 msg = String.format("Deletion of L3VPN failed when deleting for uuid %s", vpn.getValue());
1089 error = RpcResultBuilder.newError(ErrorType.APPLICATION, msg, ex.getMessage());
1090 errorList.add(error);
1094 // if at least one succeeds; result is success
1095 // if none succeeds; result is failure
1096 if (failurecount + warningcount == vpns.size()) {
1097 result.set(RpcResultBuilder.<DeleteL3VPNOutput>failed().withRpcErrors(errorList).build());
1099 List<String> errorResponseList = new ArrayList<>();
1100 if (!errorList.isEmpty()) {
1101 for (RpcError rpcError : errorList) {
1102 String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
1103 .getErrorType(), rpcError.getTag(), rpcError.getMessage());
1104 errorResponseList.add(errorResponse);
1107 errorResponseList.add("Operation successful with no errors");
1109 opBuilder.setResponse(errorResponseList);
1110 result.set(RpcResultBuilder.<DeleteL3VPNOutput>success().withResult(opBuilder.build()).build());
1115 protected void addSubnetToVpn(final Uuid vpnId, Uuid subnet) {
1116 LOG.debug("Adding subnet {} to vpn {}", subnet.getValue(), vpnId.getValue());
1117 Subnetmap sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1118 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1119 // Check if there are ports on this subnet and add corresponding
1121 List<Uuid> portList = sn.getPortList();
1122 if (portList != null) {
1123 for (final Uuid portId : sn.getPortList()) {
1124 LOG.debug("adding vpn-interface for port {}", portId.getValue());
1125 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1126 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1127 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1128 List<ListenableFuture<Void>> futures = new ArrayList<>();
1129 createVpnInterface(vpnId, routerId, NeutronvpnUtils.getNeutronPort(dataBroker, portId),
1131 futures.add(wrtConfigTxn.submit());
1138 protected void updateVpnForSubnet(Uuid vpnId, Uuid subnet, boolean isBeingAssociated) {
1139 LOG.debug("Updating VPN {} for subnet {}", vpnId.getValue(), subnet.getValue());
1140 // Read the subnet first to see if its already associated to a VPN
1141 Uuid oldVpnId = null;
1142 InstanceIdentifier<Subnetmap> snId = InstanceIdentifier.builder(Subnetmaps.class)
1143 .child(Subnetmap.class, new SubnetmapKey(subnet)).build();
1144 Subnetmap sn = null;
1145 Optional<Subnetmap> optSn = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, snId);
1146 if (optSn.isPresent()) {
1148 oldVpnId = sn.getVpnId();
1149 List<String> ips = sn.getRouterInterfaceFixedIps();
1150 for (String ipValue : ips) {
1151 // Update the association of router-interface to external vpn
1153 NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, oldVpnId.getValue(), ipValue);
1154 if (portName != null) {
1155 updateVpnInterface(vpnId, oldVpnId,
1156 NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(portName)),
1157 isBeingAssociated, true);
1161 sn = updateSubnetNode(subnet, null, null, null, null, vpnId);
1162 // Check for ports on this subnet and update association of
1163 // corresponding vpn-interfaces to external vpn
1164 List<Uuid> portList = sn.getPortList();
1165 if (portList != null) {
1166 for (Uuid port : sn.getPortList()) {
1167 LOG.debug("Updating vpn-interface for port {} isBeingAssociated {}",
1168 port.getValue(), isBeingAssociated);
1169 updateVpnInterface(vpnId, oldVpnId, NeutronvpnUtils.getNeutronPort(dataBroker, port),
1170 isBeingAssociated, false);
1175 public InstanceIdentifier<RouterInterfaces> getRouterInterfacesId(Uuid routerId) {
1176 return InstanceIdentifier.builder(RouterInterfacesMap.class)
1177 .child(RouterInterfaces.class, new RouterInterfacesKey(routerId)).build();
1180 protected void addToNeutronRouterInterfacesMap(Uuid routerId, String interfaceName) {
1181 synchronized (routerId.getValue().intern()) {
1182 InstanceIdentifier<RouterInterfaces> routerInterfacesId = getRouterInterfacesId(routerId);
1183 Optional<RouterInterfaces> optRouterInterfaces = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType
1184 .CONFIGURATION, routerInterfacesId);
1185 Interfaces routerInterface = new InterfacesBuilder().setKey(new InterfacesKey(interfaceName))
1186 .setInterfaceId(interfaceName).build();
1187 if (optRouterInterfaces.isPresent()) {
1188 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1189 .class, new InterfacesKey(interfaceName)), routerInterface);
1191 RouterInterfacesBuilder builder = new RouterInterfacesBuilder().setRouterId(routerId);
1192 List<Interfaces> interfaces = new ArrayList<>();
1193 interfaces.add(routerInterface);
1194 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId.child(Interfaces
1195 .class, new InterfacesKey(interfaceName)), routerInterface);
1200 protected void removeFromNeutronRouterInterfacesMap(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))
1206 .setInterfaceId(interfaceName).build();
1207 if (optRouterInterfaces.isPresent()) {
1208 RouterInterfaces routerInterfaces = optRouterInterfaces.get();
1209 List<Interfaces> interfaces = routerInterfaces.getInterfaces();
1210 if (interfaces != null && interfaces.remove(routerInterface)) {
1211 if (interfaces.isEmpty()) {
1212 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1214 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION,
1215 routerInterfacesId.child(Interfaces.class, new InterfacesKey(interfaceName)));
1223 * Creates the corresponding static routes in the specified VPN. These static routes must be point to an
1224 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink. Otherwise the
1225 * route will be ignored.
1227 * @param vpnName the VPN identifier
1228 * @param interVpnLinkRoutes The list of static routes
1229 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1231 public void addInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1232 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1233 for ( Routes route : interVpnLinkRoutes ) {
1234 String nexthop = String.valueOf(route.getNexthop().getValue());
1235 String destination = String.valueOf(route.getDestination().getValue());
1236 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1237 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1238 AddStaticRouteInput rpcInput =
1239 new AddStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1240 .setVpnInstanceName(vpnName.getValue())
1242 Future<RpcResult<AddStaticRouteOutput>> labelOuputFtr = vpnRpcService.addStaticRoute(rpcInput);
1243 RpcResult<AddStaticRouteOutput> rpcResult;
1245 rpcResult = labelOuputFtr.get();
1246 if ( rpcResult.isSuccessful() ) {
1247 LOG.debug("Label generated for destination {} is: {}",
1248 destination, rpcResult.getResult().getLabel());
1250 LOG.warn("RPC call to add a static Route to {} with nexthop {} returned with errors {}",
1251 destination, nexthop, rpcResult.getErrors());
1253 } catch (InterruptedException | ExecutionException e) {
1254 LOG.warn("Error happened while invoking addStaticRoute RPC: ", e);
1257 // Any other case is a fault.
1258 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1259 String.valueOf(route.getDestination().getValue()), nexthop );
1266 * Removes the corresponding static routes from the specified VPN. These static routes point to an
1267 * InterVpnLink endpoint and the specified VPN must be the other end of the InterVpnLink.
1269 * @param vpnName the VPN identifier
1270 * @param interVpnLinkRoutes The list of static routes
1271 * @param nexthopsXinterVpnLinks A Map with the correspondence nextHop-InterVpnLink
1273 public void removeInterVpnRoutes(Uuid vpnName, List<Routes> interVpnLinkRoutes,
1274 HashMap<String, InterVpnLink> nexthopsXinterVpnLinks) {
1275 for ( Routes route : interVpnLinkRoutes ) {
1276 String nexthop = String.valueOf(route.getNexthop().getValue());
1277 String destination = String.valueOf(route.getDestination().getValue());
1278 InterVpnLink interVpnLink = nexthopsXinterVpnLinks.get(nexthop);
1279 if ( isNexthopTheOtherVpnLinkEndpoint(nexthop, vpnName.getValue(), interVpnLink) ) {
1280 RemoveStaticRouteInput rpcInput =
1281 new RemoveStaticRouteInputBuilder().setDestination(destination).setNexthop(nexthop)
1282 .setVpnInstanceName(vpnName.getValue())
1284 vpnRpcService.removeStaticRoute(rpcInput);
1286 // Any other case is a fault.
1287 LOG.warn("route with destination {} and nexthop {} does not apply to any InterVpnLink",
1288 String.valueOf(route.getDestination().getValue()), nexthop );
1295 * Returns true if the specified nexthop is the other endpoint in an
1296 * InterVpnLink, regarding one of the VPN's point of view.
1298 private boolean isNexthopTheOtherVpnLinkEndpoint(String nexthop, String thisVpnUuid, InterVpnLink interVpnLink) {
1300 interVpnLink != null
1301 && ( (interVpnLink.getFirstEndpoint().getVpnUuid().getValue().equals(thisVpnUuid)
1302 && interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(nexthop))
1303 || (interVpnLink.getSecondEndpoint().getVpnUuid().getValue().equals(thisVpnUuid )
1304 && interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(nexthop)) );
1307 protected List<Adjacency> getAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList, String fixedIp) {
1308 List<Adjacency> adjList = new ArrayList<>();
1309 Map<String, List<String>> adjMap = new HashMap<>();
1310 for (Routes route : routeList) {
1311 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1312 LOG.error("Incorrect input received for extra route. {}", route);
1314 String nextHop = String.valueOf(route.getNexthop().getValue());
1315 String destination = String.valueOf(route.getDestination().getValue());
1316 if (!nextHop.equals(fixedIp)) {
1317 LOG.trace("FixedIP {} is not extra route nexthop for destination {}", fixedIp, destination);
1320 LOG.trace("Adding extra route for destination {} onto vpn {} with nexthop {} ", destination,
1321 vpnId.getValue(), nextHop);
1322 List<String> hops = adjMap.computeIfAbsent(destination, k -> new ArrayList<>());
1323 if (!hops.contains(nextHop)) {
1329 for (String destination : adjMap.keySet()) {
1330 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination)
1331 .setNextHopIpList(adjMap.get(destination)).setKey(new AdjacencyKey(destination)).build();
1337 // TODO Clean up the exception handling
1338 @SuppressWarnings("checkstyle:IllegalCatch")
1339 protected void updateVpnInterfaceWithExtraRouteAdjacency(Uuid vpnId, List<Routes> routeList) {
1340 for (Routes route : routeList) {
1341 if (route == null || route.getNexthop() == null || route.getDestination() == null) {
1342 LOG.error("Incorrect input received for extra route. {}", route);
1344 String nextHop = String.valueOf(route.getNexthop().getValue());
1345 String destination = String.valueOf(route.getDestination().getValue());
1346 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1348 if (infName != null) {
1349 LOG.trace("Updating extra route for destination {} onto vpn {} with nexthop {} and infName {}",
1350 destination, vpnId.getValue(), nextHop, infName);
1351 boolean isLockAcquired = false;
1353 InstanceIdentifier<VpnInterface> identifier = InstanceIdentifier.builder(VpnInterfaces.class)
1354 .child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1355 InstanceIdentifier<Adjacency> path = identifier.augmentation(Adjacencies.class)
1356 .child(Adjacency.class, new AdjacencyKey(destination));
1357 Adjacency erAdj = new AdjacencyBuilder().setIpAddress(destination)
1358 .setNextHopIpList(Collections.singletonList(nextHop)).setKey(new AdjacencyKey(destination))
1360 isLockAcquired = NeutronvpnUtils.lock(infName);
1361 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, path, erAdj);
1362 } catch (Exception e) {
1363 LOG.error("exception in adding extra route with destination: {}, next hop: {}",
1364 destination, nextHop, e);
1366 if (isLockAcquired) {
1367 NeutronvpnUtils.unlock(infName);
1371 LOG.debug("Unable to find VPN NextHop interface to apply extra-route destination {} on VPN {} "
1372 + "with nexthop {}", destination, vpnId.getValue(), nextHop);
1378 // TODO Clean up the exception handling
1379 @SuppressWarnings("checkstyle:IllegalCatch")
1380 protected void removeAdjacencyforExtraRoute(Uuid vpnId, List<Routes> routeList) {
1381 for (Routes route : routeList) {
1382 if (route != null && route.getNexthop() != null && route.getDestination() != null) {
1383 boolean isLockAcquired = false;
1384 String nextHop = String.valueOf(route.getNexthop().getValue());
1385 String destination = String.valueOf(route.getDestination().getValue());
1386 String infName = NeutronvpnUtils.getNeutronPortNameFromVpnPortFixedIp(dataBroker, vpnId.getValue(),
1388 if (infName == null) {
1389 LOG.error("Unable to find VPN NextHop interface to remove extra-route destination {} on VPN {} "
1390 + "with nexthop {}", destination, vpnId.getValue(), nextHop);
1391 // Proceed to remove the next extra-route
1394 LOG.trace("Removing extra route for destination {} on vpn {} with nexthop {} and infName {}",
1395 destination, vpnId.getValue(), nextHop, infName);
1397 InstanceIdentifier<Adjacency> adjacencyIdentifier =
1398 InstanceIdentifier.builder(VpnInterfaces.class)
1399 .child(VpnInterface.class, new VpnInterfaceKey(infName))
1400 .augmentation(Adjacencies.class)
1401 .child(Adjacency.class, new AdjacencyKey(destination))
1404 // Looking for existing prefix in MDSAL database
1405 Optional<Adjacency> adjacency = MDSALUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1406 adjacencyIdentifier);
1407 boolean updateNextHops = false;
1408 List<String> nextHopList = new ArrayList<>();
1409 if (adjacency.isPresent()) {
1410 List<String> nhListRead = adjacency.get().getNextHopIpList();
1411 if (nhListRead.size() > 1) { // ECMP case
1412 for (String nextHopRead : nhListRead) {
1413 if (nextHopRead.equals(nextHop)) {
1414 updateNextHops = true;
1416 nextHopList.add(nextHopRead);
1423 isLockAcquired = NeutronvpnUtils.lock(infName);
1424 if (updateNextHops) {
1425 // An update must be done, not including the current next hop
1426 InstanceIdentifier<VpnInterface> vpnIfIdentifier = InstanceIdentifier.builder(
1427 VpnInterfaces.class).child(VpnInterface.class, new VpnInterfaceKey(infName)).build();
1428 Adjacency newAdj = new AdjacencyBuilder(adjacency.get()).setIpAddress(destination)
1429 .setNextHopIpList(nextHopList)
1430 .setKey(new AdjacencyKey(destination))
1432 Adjacencies erAdjs =
1433 new AdjacenciesBuilder().setAdjacency(Collections.singletonList(newAdj)).build();
1434 VpnInterface vpnIf = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
1435 .addAugmentation(Adjacencies.class, erAdjs).build();
1436 MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
1438 // Remove the whole route
1439 MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, adjacencyIdentifier);
1440 LOG.trace("extra route {} deleted successfully", route);
1442 } catch (Exception e) {
1443 LOG.error("exception in deleting extra route: {}" + e);
1445 if (isLockAcquired) {
1446 NeutronvpnUtils.unlock(infName);
1450 LOG.error("Incorrect input received for extra route. {}", route);
1455 protected void removeL3Vpn(Uuid id) {
1457 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, id);
1458 Uuid router = (vpnMap != null) ? vpnMap.getRouterId() : null;
1459 // dissociate router
1460 if (router != null) {
1461 dissociateRouterFromVpn(id, router);
1463 // dissociate networks
1464 if (!id.equals(router)) {
1465 dissociateNetworksFromVpn(id, vpnMap.getNetworkIds());
1467 // remove entire vpnMaps node
1468 deleteVpnMapsNode(id);
1470 // remove vpn-instance
1471 deleteVpnInstance(id);
1474 protected void removeSubnetFromVpn(final Uuid vpnId, Uuid subnet) {
1475 LOG.debug("Removing subnet {} from vpn {}", subnet.getValue(), vpnId.getValue());
1476 final Uuid routerId = NeutronvpnUtils.getVpnMap(dataBroker, vpnId).getRouterId();
1477 Subnetmap sn = NeutronvpnUtils.getSubnetmap(dataBroker, subnet);
1479 // Check if there are ports on this subnet; remove corresponding vpn-interfaces
1480 List<Uuid> portList = sn.getPortList();
1481 if (portList != null) {
1482 for (final Uuid portId : sn.getPortList()) {
1483 LOG.debug("removing vpn-interface for port {}", portId.getValue());
1484 final DataStoreJobCoordinator portDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1485 portDataStoreCoordinator.enqueueJob("PORT-" + portId.getValue(), () -> {
1486 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
1487 List<ListenableFuture<Void>> futures = new ArrayList<>();
1488 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1490 deleteVpnInterface(vpnId, routerId, port, wrtConfigTxn);
1492 LOG.error("Cannot proceed with deleteVpnInterface for port {} in subnet {} since port is "
1493 + "absent in Neutron config DS", portId.getValue(), subnet.getValue());
1495 futures.add(wrtConfigTxn.submit());
1500 // update subnet-vpn association
1501 removeFromSubnetNode(subnet, null, null, vpnId, null);
1503 LOG.warn("Subnetmap for subnet {} not found", subnet.getValue());
1507 // TODO Clean up the exception handling
1508 @SuppressWarnings("checkstyle:IllegalCatch")
1509 protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
1510 updateVpnMaps(vpnId, null, routerId, null, null);
1511 LOG.debug("Updating association of subnets to external vpn {}", vpnId.getValue());
1512 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1513 if (routerSubnets != null) {
1514 for (Uuid subnetId : routerSubnets) {
1515 updateVpnForSubnet(vpnId, subnetId, true);
1519 checkAndPublishRouterAssociatedtoVpnNotification(routerId, vpnId);
1520 LOG.debug("notification upon association of router {} to VPN {} published", routerId.getValue(),
1522 } catch (Exception e) {
1523 LOG.error("publishing of notification upon association of router {} to VPN {} failed : ", routerId
1524 .getValue(), vpnId.getValue(), e);
1528 protected void associateRouterToInternalVpn(Uuid vpnId, Uuid routerId) {
1529 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1530 LOG.debug("Adding subnets to internal vpn {}", vpnId.getValue());
1531 for (Uuid subnet : routerSubnets) {
1532 addSubnetToVpn(vpnId, subnet);
1536 // TODO Clean up the exception handling
1537 @SuppressWarnings("checkstyle:IllegalCatch")
1538 protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
1540 List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(dataBroker, routerId);
1541 if (routerSubnets != null) {
1542 for (Uuid subnetId : routerSubnets) {
1543 LOG.debug("Updating association of subnets to internal vpn {}", routerId.getValue());
1544 updateVpnForSubnet(routerId, subnetId, false);
1547 clearFromVpnMaps(vpnId, routerId, null);
1549 checkAndPublishRouterDisassociatedFromVpnNotification(routerId, vpnId);
1550 LOG.debug("notification upon disassociation of router {} from VPN {} published", routerId.getValue(),
1552 } catch (Exception e) {
1553 LOG.error("publishing of notification upon disassociation of router {} from VPN {} failed : ", routerId
1554 .getValue(), vpnId.getValue(), e);
1558 protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
1559 List<String> failedNwList = new ArrayList<>();
1560 List<Uuid> passedNwList = new ArrayList<>();
1561 if (!networks.isEmpty()) {
1562 // process corresponding subnets for VPN
1563 for (Uuid nw : networks) {
1564 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1565 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1566 if (network == null) {
1567 failedNwList.add(String.format("network %s not found", nw.getValue()));
1568 } else if (vpnId != null) {
1569 failedNwList.add(String.format("network %s already associated to another VPN %s", nw.getValue(),
1572 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1573 LOG.debug("Adding network subnets...{}", networkSubnets);
1574 if (networkSubnets != null) {
1575 for (Uuid subnet : networkSubnets) {
1576 // check if subnet added as router interface to some router
1577 Uuid subnetVpnId = NeutronvpnUtils.getVpnForSubnet(dataBroker, subnet);
1578 if (subnetVpnId == null) {
1579 addSubnetToVpn(vpn, subnet);
1580 passedNwList.add(nw);
1582 failedNwList.add(String.format("subnet %s already added as router interface bound to "
1583 + "internal/external VPN %s", subnet.getValue(), subnetVpnId.getValue()));
1587 if (NeutronvpnUtils.getIsExternal(network)) {
1588 nvpnNatManager.addExternalNetworkToVpn(network, vpn);
1592 updateVpnMaps(vpn, null, null, null, passedNwList);
1594 return failedNwList;
1597 protected List<String> dissociateNetworksFromVpn(Uuid vpn, List<Uuid> networks) {
1598 List<String> failedNwList = new ArrayList<>();
1599 List<Uuid> passedNwList = new ArrayList<>();
1600 if (networks != null && !networks.isEmpty()) {
1601 // process corresponding subnets for VPN
1602 for (Uuid nw : networks) {
1603 Network network = NeutronvpnUtils.getNeutronNetwork(dataBroker, nw);
1604 if (network == null) {
1605 failedNwList.add(String.format("network %s not found", nw.getValue()));
1607 Uuid vpnId = NeutronvpnUtils.getVpnForNetwork(dataBroker, nw);
1608 if (vpn.equals(vpnId)) {
1609 List<Uuid> networkSubnets = NeutronvpnUtils.getSubnetIdsFromNetworkId(dataBroker, nw);
1610 LOG.debug("Removing network subnets...");
1611 if (networkSubnets != null) {
1612 for (Uuid subnet : networkSubnets) {
1613 removeSubnetFromVpn(vpn, subnet);
1614 passedNwList.add(nw);
1618 if (vpnId == null) {
1619 failedNwList.add(String.format("input network %s not associated to any vpn yet", nw
1622 failedNwList.add(String.format("input network %s associated to a another vpn %s instead "
1623 + "of the one given as input", nw.getValue(), vpnId.getValue()));
1626 if (NeutronvpnUtils.getIsExternal(network)) {
1627 nvpnNatManager.removeExternalNetworkFromVpn(network);
1631 clearFromVpnMaps(vpn, null, passedNwList);
1633 return failedNwList;
1637 * It handles the invocations to the neutronvpn:associateNetworks RPC method.
1640 // TODO Clean up the exception handling
1641 @SuppressWarnings("checkstyle:IllegalCatch")
1642 public Future<RpcResult<AssociateNetworksOutput>> associateNetworks(AssociateNetworksInput input) {
1644 AssociateNetworksOutputBuilder opBuilder = new AssociateNetworksOutputBuilder();
1645 SettableFuture<RpcResult<AssociateNetworksOutput>> result = SettableFuture.create();
1646 LOG.debug("associateNetworks {}", input);
1647 StringBuilder returnMsg = new StringBuilder();
1648 Uuid vpnId = input.getVpnId();
1651 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1652 List<Uuid> netIds = input.getNetworkId();
1653 if (netIds != null && !netIds.isEmpty()) {
1654 List<String> failed = associateNetworksToVpn(vpnId, netIds);
1655 if (!failed.isEmpty()) {
1656 returnMsg.append(failed);
1660 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1662 if (returnMsg.length() != 0) {
1663 String message = String.format("associate Networks to vpn %s failed due to %s",
1664 vpnId.getValue(), returnMsg);
1666 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: %s",
1668 opBuilder.setResponse(errorResponse);
1669 result.set(RpcResultBuilder.<AssociateNetworksOutput>success().withResult(opBuilder.build()).build());
1671 result.set(RpcResultBuilder.<AssociateNetworksOutput>success().build());
1673 } catch (Exception ex) {
1674 String message = String.format("associate Networks to vpn %s failed due to %s",
1675 input.getVpnId().getValue(), ex.getMessage());
1676 LOG.error(message, ex);
1677 result.set(RpcResultBuilder.<AssociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
1680 LOG.debug("associateNetworks returns..");
1685 * It handles the invocations to the neutronvpn:associateRouter RPC method.
1688 // TODO Clean up the exception handling
1689 @SuppressWarnings("checkstyle:IllegalCatch")
1690 public Future<RpcResult<Void>> associateRouter(AssociateRouterInput input) {
1692 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1693 LOG.debug("associateRouter {}", input);
1694 StringBuilder returnMsg = new StringBuilder();
1695 Uuid vpnId = input.getVpnId();
1696 Uuid routerId = input.getRouterId();
1698 VpnMap vpnMap = NeutronvpnUtils.getVpnMap(dataBroker, vpnId);
1699 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1700 if (vpnMap != null) {
1702 Uuid extVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1703 if (vpnMap.getRouterId() != null) {
1704 returnMsg.append("vpn ").append(vpnId.getValue()).append(" already associated to router ")
1705 .append(vpnMap.getRouterId().getValue());
1706 } else if (extVpnId != null) {
1707 returnMsg.append("router ").append(routerId.getValue()).append(" already associated to "
1708 + "another VPN ").append(extVpnId.getValue());
1710 associateRouterToVpn(vpnId, routerId);
1713 returnMsg.append("router not found : ").append(routerId.getValue());
1716 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1718 if (returnMsg.length() != 0) {
1719 String message = String.format("associate router to vpn %s failed due to %s", routerId.getValue(),
1722 result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1725 result.set(RpcResultBuilder.<Void>success().build());
1727 } catch (Exception ex) {
1728 String message = String.format("associate router %s to vpn %s failed due to %s", routerId.getValue(),
1729 vpnId.getValue(), ex.getMessage());
1730 LOG.error(message, ex);
1731 result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
1733 LOG.debug("associateRouter returns..");
1737 /** It handles the invocations to the neutronvpn:getFixedIPsForNeutronPort RPC method.
1740 // TODO Clean up the exception handling
1741 @SuppressWarnings("checkstyle:IllegalCatch")
1742 public Future<RpcResult<GetFixedIPsForNeutronPortOutput>> getFixedIPsForNeutronPort(
1743 GetFixedIPsForNeutronPortInput input) {
1744 GetFixedIPsForNeutronPortOutputBuilder opBuilder = new GetFixedIPsForNeutronPortOutputBuilder();
1745 SettableFuture<RpcResult<GetFixedIPsForNeutronPortOutput>> result = SettableFuture.create();
1746 Uuid portId = input.getPortId();
1747 StringBuilder returnMsg = new StringBuilder();
1749 List<String> fixedIPList = new ArrayList<>();
1750 Port port = NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1752 List<FixedIps> fixedIPs = port.getFixedIps();
1753 for (FixedIps ip : fixedIPs) {
1754 fixedIPList.add(String.valueOf(ip.getIpAddress().getValue()));
1757 returnMsg.append("neutron port: ").append(portId.getValue()).append(" not found");
1759 if (returnMsg.length() != 0) {
1760 String message = String.format("Retrieval of FixedIPList for neutron port failed due to %s", returnMsg);
1762 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed()
1763 .withWarning(ErrorType.PROTOCOL, "invalid-value", message).build());
1765 opBuilder.setFixedIPs(fixedIPList);
1766 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().withResult(opBuilder.build())
1768 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>success().build());
1770 } catch (Exception ex) {
1771 String message = String.format("Retrieval of FixedIPList for neutron port %s failed due to %s",
1772 portId.getValue(), ex.getMessage());
1773 LOG.error(message, ex);
1774 result.set(RpcResultBuilder.<GetFixedIPsForNeutronPortOutput>failed()
1775 .withError(ErrorType.APPLICATION, message).build());
1781 * It handles the invocations to the neutronvpn:dissociateNetworks RPC method.
1784 // TODO Clean up the exception handling
1785 @SuppressWarnings("checkstyle:IllegalCatch")
1786 public Future<RpcResult<DissociateNetworksOutput>> dissociateNetworks(DissociateNetworksInput input) {
1788 DissociateNetworksOutputBuilder opBuilder = new DissociateNetworksOutputBuilder();
1789 SettableFuture<RpcResult<DissociateNetworksOutput>> result = SettableFuture.create();
1791 LOG.debug("dissociateNetworks {}", input);
1792 StringBuilder returnMsg = new StringBuilder();
1793 Uuid vpnId = input.getVpnId();
1796 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1797 List<Uuid> netIds = input.getNetworkId();
1798 if (netIds != null && !netIds.isEmpty()) {
1799 List<String> failed = dissociateNetworksFromVpn(vpnId, netIds);
1800 if (!failed.isEmpty()) {
1801 returnMsg.append(failed);
1805 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1807 if (returnMsg.length() != 0) {
1808 String message = String.format("dissociate Networks to vpn %s failed due to %s", vpnId.getValue(),
1811 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1813 opBuilder.setResponse(errorResponse);
1814 result.set(RpcResultBuilder.<DissociateNetworksOutput>success().withResult(opBuilder.build()).build());
1816 result.set(RpcResultBuilder.<DissociateNetworksOutput>success().build());
1818 } catch (Exception ex) {
1819 String message = String.format("dissociate Networks to vpn %s failed due to %s",
1820 input.getVpnId().getValue(), ex.getMessage());
1821 LOG.error(message, ex);
1822 result.set(RpcResultBuilder.<DissociateNetworksOutput>failed().withError(ErrorType.APPLICATION, message)
1825 LOG.debug("dissociateNetworks returns..");
1830 * It handles the invocations to the neutronvpn:dissociateRouter RPC method.
1833 // TODO Clean up the exception handling
1834 @SuppressWarnings("checkstyle:IllegalCatch")
1835 public Future<RpcResult<Void>> dissociateRouter(DissociateRouterInput input) {
1837 SettableFuture<RpcResult<Void>> result = SettableFuture.create();
1839 LOG.debug("dissociateRouter {}", input);
1840 StringBuilder returnMsg = new StringBuilder();
1841 Uuid vpnId = input.getVpnId();
1842 Uuid routerId = input.getRouterId();
1844 if (NeutronvpnUtils.getVpnMap(dataBroker, vpnId) != null) {
1845 if (routerId != null) {
1846 Router rtr = NeutronvpnUtils.getNeutronRouter(dataBroker, routerId);
1848 Uuid routerVpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1849 if (vpnId.equals(routerVpnId)) {
1850 dissociateRouterFromVpn(vpnId, routerId);
1852 if (routerVpnId == null) {
1853 returnMsg.append("input router ").append(routerId.getValue())
1854 .append(" not associated to any vpn yet");
1856 returnMsg.append("input router ").append(routerId.getValue())
1857 .append(" associated to vpn ")
1858 .append(routerVpnId.getValue()).append("instead of the vpn given as input");
1862 returnMsg.append("router not found : ").append(routerId.getValue());
1866 returnMsg.append("VPN not found : ").append(vpnId.getValue());
1868 if (returnMsg.length() != 0) {
1869 String message = String.format("dissociate router %s to vpn %s failed due to %s", routerId.getValue(),
1870 vpnId.getValue(), returnMsg);
1872 String errorResponse = String.format("ErrorType: PROTOCOL, ErrorTag: invalid-value, ErrorMessage: "
1874 result.set(RpcResultBuilder.<Void>failed().withWarning(ErrorType.PROTOCOL, "invalid-value", message)
1877 result.set(RpcResultBuilder.<Void>success().build());
1879 } catch (Exception ex) {
1880 String message = String.format("disssociate router %s to vpn %s failed due to %s", routerId.getValue(),
1881 vpnId.getValue(), ex.getMessage());
1882 LOG.error(message, ex);
1883 result.set(RpcResultBuilder.<Void>failed().withError(ErrorType.APPLICATION, message).build());
1885 LOG.debug("dissociateRouter returns..");
1890 protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
1891 // check if the router is associated to some VPN
1892 Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true);
1893 if (vpnId != null) {
1894 // remove existing external vpn interfaces
1895 for (Uuid subnetId : routerSubnetIds) {
1896 removeSubnetFromVpn(vpnId, subnetId);
1898 clearFromVpnMaps(vpnId, routerId, null);
1900 // remove existing internal vpn interfaces
1901 for (Uuid subnetId : routerSubnetIds) {
1902 removeSubnetFromVpn(routerId, subnetId);
1905 // delete entire vpnMaps node for internal VPN
1906 deleteVpnMapsNode(routerId);
1908 // delete vpn-instance for internal VPN
1909 deleteVpnInstance(routerId);
1912 protected Subnet getNeutronSubnet(Uuid subnetId) {
1913 return NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1916 protected IpAddress getNeutronSubnetGateway(Uuid subnetId) {
1917 Subnet sn = NeutronvpnUtils.getNeutronSubnet(dataBroker, subnetId);
1919 return sn.getGatewayIp();
1925 protected Network getNeutronNetwork(Uuid networkId) {
1926 return NeutronvpnUtils.getNeutronNetwork(dataBroker, networkId);
1929 protected Port getNeutronPort(String name) {
1930 return NeutronvpnUtils.getNeutronPort(dataBroker, new Uuid(name));
1933 protected Port getNeutronPort(Uuid portId) {
1934 return NeutronvpnUtils.getNeutronPort(dataBroker, portId);
1937 protected List<Uuid> getSubnetsforVpn(Uuid vpnid) {
1938 List<Uuid> subnets = new ArrayList<>();
1940 InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
1941 Optional<Subnetmaps> subnetmaps = NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1943 if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
1944 List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
1945 for (Subnetmap subnetMap : subnetMapList) {
1946 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
1947 subnets.add(subnetMap.getId());
1955 * Implementation of the "vpnservice:neutron-ports-show" Karaf CLI command.
1957 * @return a List of String to be printed on screen
1959 // TODO Clean up the exception handling and the console output
1960 @SuppressWarnings({"checkstyle:IllegalCatch", "checkstyle:RegexpSinglelineJava"})
1961 public List<String> showNeutronPortsCLI() {
1962 List<String> result = new ArrayList<>();
1963 result.add(String.format(" %-36s %-19s %-13s %-20s ", "Port ID", "Mac Address", "Prefix Length",
1965 result.add("-------------------------------------------------------------------------------------------");
1966 InstanceIdentifier<Ports> portidentifier = InstanceIdentifier.create(Neutron.class).child(Ports.class);
1968 Optional<Ports> ports =
1969 NeutronvpnUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, portidentifier);
1970 if (ports.isPresent() && ports.get().getPort() != null) {
1971 for (Port port : ports.get().getPort()) {
1972 List<FixedIps> fixedIPs = port.getFixedIps();
1974 if (fixedIPs != null && !fixedIPs.isEmpty()) {
1975 List<String> ipList = new ArrayList<>();
1976 for (FixedIps fixedIp : fixedIPs) {
1977 IpAddress ipAddress = fixedIp.getIpAddress();
1978 if (ipAddress.getIpv4Address() != null) {
1979 ipList.add(ipAddress.getIpv4Address().getValue());
1981 ipList.add((ipAddress.getIpv6Address().getValue()));
1984 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
1985 .getMacAddress().getValue(), NeutronvpnUtils.getIPPrefixFromPort(dataBroker, port),
1986 ipList.toString()));
1988 result.add(String.format(" %-36s %-19s %-13s %-20s ", port.getUuid().getValue(), port
1989 .getMacAddress().getValue(), "Not Assigned", "Not " + "Assigned"));
1991 } catch (Exception e) {
1992 LOG.error("Failed to retrieve neutronPorts info for port {}: ", port.getUuid().getValue(),
1994 System.out.println("Failed to retrieve neutronPorts info for port: " + port.getUuid()
1995 .getValue() + ": " + e.getMessage());
1999 } catch (Exception e) {
2000 LOG.error("Failed to retrieve neutronPorts info : ", e);
2001 System.out.println("Failed to retrieve neutronPorts info : " + e.getMessage());
2007 * Implementation of the "vpnservice:l3vpn-config-show" karaf CLI command.
2009 * @param vpnuuid Uuid of the VPN whose config must be shown
2010 * @return formatted output list
2012 @SuppressWarnings("checkstyle:RegexpSinglelineJava")
2013 public List<String> showVpnConfigCLI(Uuid vpnuuid) {
2014 List<String> result = new ArrayList<>();
2015 if (vpnuuid == null) {
2016 System.out.println("");
2017 System.out.println("Displaying VPN config for all VPNs");
2018 System.out.println("To display VPN config for a particular VPN, use the following syntax");
2019 System.out.println(getshowVpnConfigCLIHelp());
2022 RpcResult<GetL3VPNOutput> rpcResult = getL3VPN(new GetL3VPNInputBuilder().setId(vpnuuid).build()).get();
2023 if (rpcResult.isSuccessful()) {
2025 result.add(String.format(" %-37s %-37s %-7s ", "VPN ID", "Tenant ID", "RD"));
2027 result.add(String.format(" %-80s ", "Import-RTs"));
2029 result.add(String.format(" %-80s ", "Export-RTs"));
2031 result.add(String.format(" %-76s ", "Subnet IDs"));
2033 result.add("------------------------------------------------------------------------------------");
2035 List<L3vpnInstances> vpnList = rpcResult.getResult().getL3vpnInstances();
2036 for (L3vpnInstance vpn : vpnList) {
2037 String tenantId = vpn.getTenantId() != null ? vpn.getTenantId().getValue()
2039 result.add(String.format(" %-37s %-37s %-7s ", vpn.getId().getValue(), tenantId,
2040 vpn.getRouteDistinguisher()));
2042 result.add(String.format(" %-80s ", vpn.getImportRT()));
2044 result.add(String.format(" %-80s ", vpn.getExportRT()));
2047 Uuid vpnid = vpn.getId();
2048 List<Uuid> subnetList = getSubnetsforVpn(vpnid);
2049 if (!subnetList.isEmpty()) {
2050 for (Uuid subnetuuid : subnetList) {
2051 result.add(String.format(" %-76s ", subnetuuid.getValue()));
2054 result.add(String.format(" %-76s ", "\" \""));
2057 result.add("----------------------------------------");
2061 String errortag = rpcResult.getErrors().iterator().next().getTag();
2062 if (errortag == "") {
2063 System.out.println("");
2064 System.out.println("No VPN has been configured yet");
2065 } else if (errortag == "invalid-value") {
2066 System.out.println("");
2067 System.out.println("VPN " + vpnuuid.getValue() + " is not present");
2069 System.out.println("error getting VPN info : " + rpcResult.getErrors());
2070 System.out.println(getshowVpnConfigCLIHelp());
2073 } catch (InterruptedException | ExecutionException e) {
2074 LOG.error("error getting VPN info : ", e);
2075 System.out.println("error getting VPN info : " + e.getMessage());
2080 protected void createExternalVpnInterfaces(Uuid extNetId) {
2081 if (extNetId == null) {
2082 LOG.trace("external network is null");
2086 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2087 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2088 LOG.trace("No external ports attached to external network {}", extNetId.getValue());
2092 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2093 for (String elanInterface : extElanInterfaces) {
2094 createExternalVpnInterface(extNetId, elanInterface, wrtConfigTxn);
2096 wrtConfigTxn.submit();
2099 // TODO Clean up the exception handling
2100 @SuppressWarnings("checkstyle:IllegalCatch")
2101 protected void removeExternalVpnInterfaces(Uuid extNetId) {
2102 Collection<String> extElanInterfaces = elanService.getExternalElanInterfaces(extNetId.getValue());
2103 if (extElanInterfaces == null || extElanInterfaces.isEmpty()) {
2104 LOG.trace("No external ports attached for external network {}", extNetId);
2109 WriteTransaction wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2110 for (String elanInterface : extElanInterfaces) {
2111 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils
2112 .buildVpnInterfaceIdentifier(elanInterface);
2113 LOG.info("Removing vpn interface {}", elanInterface);
2114 wrtConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier);
2116 wrtConfigTxn.submit();
2118 } catch (Exception ex) {
2119 LOG.error("Removal of vpninterfaces {} failed due to {}", extElanInterfaces, ex);
2123 private void createExternalVpnInterface(Uuid vpnId, String infName, WriteTransaction wrtConfigTxn) {
2124 writeVpnInterfaceToDs(vpnId, infName, null, false /* not a router iface */, wrtConfigTxn);
2127 // TODO Clean up the exception handling
2128 @SuppressWarnings("checkstyle:IllegalCatch")
2129 private void writeVpnInterfaceToDs(Uuid vpnId, String infName, Adjacencies adjacencies,
2130 Boolean isRouterInterface, WriteTransaction wrtConfigTxn) {
2131 if (vpnId == null || infName == null) {
2132 LOG.debug("vpn id or interface is null");
2136 Boolean wrtConfigTxnPresent = true;
2137 if (wrtConfigTxn == null) {
2138 wrtConfigTxnPresent = false;
2139 wrtConfigTxn = dataBroker.newWriteOnlyTransaction();
2142 InstanceIdentifier<VpnInterface> vpnIfIdentifier = NeutronvpnUtils.buildVpnInterfaceIdentifier(infName);
2143 VpnInterfaceBuilder vpnb = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(infName))
2145 .setVpnInstanceName(vpnId.getValue())
2146 .setIsRouterInterface(isRouterInterface);
2147 if (adjacencies != null) {
2148 vpnb.addAugmentation(Adjacencies.class, adjacencies);
2150 VpnInterface vpnIf = vpnb.build();
2152 LOG.info("Creating vpn interface {}", vpnIf);
2153 wrtConfigTxn.put(LogicalDatastoreType.CONFIGURATION, vpnIfIdentifier, vpnIf);
2154 } catch (Exception ex) {
2155 LOG.error("Creation of vpninterface {} failed due to {}", infName, ex);
2158 if (!wrtConfigTxnPresent) {
2159 wrtConfigTxn.submit();
2163 private String getshowVpnConfigCLIHelp() {
2164 StringBuilder help = new StringBuilder("Usage:");
2165 help.append("display vpn-config [-vid/--vpnid <id>]");
2166 return help.toString();
2169 private void checkAndPublishRouterAssociatedtoVpnNotification(Uuid routerId, Uuid vpnId) throws
2170 InterruptedException {
2171 RouterAssociatedToVpn routerAssociatedToVpn = new RouterAssociatedToVpnBuilder().setRouterId(routerId)
2172 .setVpnId(vpnId).build();
2173 LOG.info("publishing notification upon association of router to VPN");
2174 notificationPublishService.putNotification(routerAssociatedToVpn);
2177 private void checkAndPublishRouterDisassociatedFromVpnNotification(Uuid routerId, Uuid vpnId) throws
2178 InterruptedException {
2179 RouterDisassociatedFromVpn routerDisassociatedFromVpn =
2180 new RouterDisassociatedFromVpnBuilder().setRouterId(routerId).setVpnId(vpnId).build();
2181 LOG.info("publishing notification upon disassociation of router from VPN");
2182 notificationPublishService.putNotification(routerDisassociatedFromVpn);
2185 protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) {
2186 floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName);