Cross compute traffic for external network vpn will go over flat/vlan provider networ...
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / neutronvpn / NeutronvpnUtils.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netvirt.neutronvpn;
10
11 import com.google.common.base.Optional;
12 import com.google.common.collect.ImmutableBiMap;
13 import com.google.common.collect.Sets;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.TimeUnit;
28 import java.util.concurrent.atomic.AtomicInteger;
29 import java.util.concurrent.locks.ReadWriteLock;
30 import java.util.concurrent.locks.ReentrantReadWriteLock;
31 import org.apache.commons.lang3.StringUtils;
32 import org.apache.commons.lang3.tuple.ImmutablePair;
33 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
34 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
35 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
36 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
37 import org.opendaylight.genius.mdsalutil.MDSALUtil;
38 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
39 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
40 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
41 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
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.VpnInterfaceKey;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeFlat;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeGre;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVlan;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeVxlan;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.NetworkL3Extension;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeGre;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVxlan;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.portsecurity.rev150712.PortSecurityExtension;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.qos.rev160613.qos.attributes.qos.policies.QosPolicy;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
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.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinkStates;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.InterVpnLinks;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkState;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.link.states.InterVpnLinkStateKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
121 import org.opendaylight.yangtools.yang.binding.DataObject;
122 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
123 import org.opendaylight.yangtools.yang.common.RpcResult;
124 import org.slf4j.Logger;
125 import org.slf4j.LoggerFactory;
126
127 public class NeutronvpnUtils {
128
129     private static final Logger LOG = LoggerFactory.getLogger(NeutronvpnUtils.class);
130     private static final ImmutableBiMap<Class<? extends NetworkTypeBase>, Class<? extends SegmentTypeBase>>
131         NETWORK_MAP =
132         new ImmutableBiMap.Builder<Class<? extends NetworkTypeBase>, Class<? extends SegmentTypeBase>>()
133             .put(NetworkTypeFlat.class, SegmentTypeFlat.class)
134             .put(NetworkTypeGre.class, SegmentTypeGre.class)
135             .put(NetworkTypeVlan.class, SegmentTypeVlan.class)
136             .put(NetworkTypeVxlan.class, SegmentTypeVxlan.class)
137             .build();
138
139     public static ConcurrentHashMap<Uuid, Network> networkMap = new ConcurrentHashMap<>();
140     public static ConcurrentHashMap<Uuid, Router> routerMap = new ConcurrentHashMap<>();
141     public static ConcurrentHashMap<Uuid, Port> portMap = new ConcurrentHashMap<>();
142     public static ConcurrentHashMap<Uuid, Subnet> subnetMap = new ConcurrentHashMap<>();
143     public static Map<IpAddress, Set<Uuid>> subnetGwIpMap = new ConcurrentHashMap<>();
144     public static ConcurrentHashMap<Uuid, QosPolicy> qosPolicyMap = new ConcurrentHashMap<>();
145     public static ConcurrentHashMap<Uuid, HashMap<Uuid, Port>> qosPortsMap = new ConcurrentHashMap<>();
146     public static ConcurrentHashMap<Uuid, HashMap<Uuid, Network>> qosNetworksMap = new ConcurrentHashMap<>();
147     private static final Set<Class<? extends NetworkTypeBase>> SUPPORTED_NETWORK_TYPES = Sets.newConcurrentHashSet();
148
149     private static long LOCK_WAIT_TIME = 10L;
150     private static TimeUnit secUnit = TimeUnit.SECONDS;
151
152     static {
153         registerSupportedNetworkType(NetworkTypeFlat.class);
154         registerSupportedNetworkType(NetworkTypeVlan.class);
155         registerSupportedNetworkType(NetworkTypeVxlan.class);
156         registerSupportedNetworkType(NetworkTypeGre.class);
157     }
158
159     private NeutronvpnUtils() {
160         throw new UnsupportedOperationException("Utility class should not be instantiated");
161     }
162
163     static ConcurrentHashMap<String, ImmutablePair<ReadWriteLock,AtomicInteger>> locks = new ConcurrentHashMap<>();
164
165     public static void registerSupportedNetworkType(Class<? extends NetworkTypeBase> netType) {
166         SUPPORTED_NETWORK_TYPES.add(netType);
167     }
168
169     public static void unregisterSupportedNetworkType(Class<? extends NetworkTypeBase> netType) {
170         SUPPORTED_NETWORK_TYPES.remove(netType);
171     }
172
173     protected static Subnetmap getSubnetmap(DataBroker broker, Uuid subnetId) {
174         InstanceIdentifier id = buildSubnetMapIdentifier(subnetId);
175         Optional<Subnetmap> sn = read(broker, LogicalDatastoreType.CONFIGURATION, id);
176
177         if (sn.isPresent()) {
178             return sn.get();
179         }
180         return null;
181     }
182
183     protected static VpnMap getVpnMap(DataBroker broker, Uuid id) {
184         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
185                 new VpnMapKey(id)).build();
186         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
187         if (optionalVpnMap.isPresent()) {
188             return optionalVpnMap.get();
189         }
190         LOG.error("getVpnMap failed, VPN {} not present", id.getValue());
191         return null;
192     }
193
194     protected static Uuid getVpnForNetwork(DataBroker broker, Uuid network) {
195         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
196         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
197         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
198             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
199             for (VpnMap vpnMap : allMaps) {
200                 List<Uuid> netIds = vpnMap.getNetworkIds();
201                 if (netIds != null && netIds.contains(network)) {
202                     return vpnMap.getVpnId();
203                 }
204             }
205         }
206         return null;
207     }
208
209     protected static Uuid getVpnForSubnet(DataBroker broker, Uuid subnetId) {
210         InstanceIdentifier<Subnetmap> subnetmapIdentifier = buildSubnetMapIdentifier(subnetId);
211         Optional<Subnetmap> optionalSubnetMap = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapIdentifier);
212         if (optionalSubnetMap.isPresent()) {
213             return optionalSubnetMap.get().getVpnId();
214         }
215         return null;
216     }
217
218     protected static Uuid getNetworkForSubnet(DataBroker broker, Uuid subnetId) {
219         InstanceIdentifier<Subnetmap> subnetmapIdentifier = buildSubnetMapIdentifier(subnetId);
220         Optional<Subnetmap> optionalSubnetMap = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapIdentifier);
221         if (optionalSubnetMap.isPresent()) {
222             return optionalSubnetMap.get().getNetworkId();
223         }
224         return null;
225     }
226
227     // @param external vpn - true if external vpn being fetched, false for internal vpn
228     protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
229         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
230         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
231         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
232             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
233             if (routerId != null) {
234                 for (VpnMap vpnMap : allMaps) {
235                     if (routerId.equals(vpnMap.getRouterId())) {
236                         if (externalVpn) {
237                             if (!routerId.equals(vpnMap.getVpnId())) {
238                                 return vpnMap.getVpnId();
239                             }
240                         } else {
241                             if (routerId.equals(vpnMap.getVpnId())) {
242                                 return vpnMap.getVpnId();
243                             }
244                         }
245                     }
246                 }
247             }
248         }
249         return null;
250     }
251
252     protected static Uuid getRouterforVpn(DataBroker broker, Uuid vpnId) {
253         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
254                 new VpnMapKey(vpnId)).build();
255         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
256         if (optionalVpnMap.isPresent()) {
257             VpnMap vpnMap = optionalVpnMap.get();
258             return vpnMap.getRouterId();
259         }
260         return null;
261     }
262
263     protected static List<Uuid> getNetworksforVpn(DataBroker broker, Uuid vpnId) {
264         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
265                 new VpnMapKey(vpnId)).build();
266         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
267         if (optionalVpnMap.isPresent()) {
268             VpnMap vpnMap = optionalVpnMap.get();
269             return vpnMap.getNetworkIds();
270         }
271         return null;
272     }
273
274     protected static List<Uuid> getSubnetsforVpn(DataBroker broker, Uuid vpnid) {
275         List<Uuid> subnets = new ArrayList<>();
276         // read subnetmaps
277         InstanceIdentifier<Subnetmaps> subnetmapsid = InstanceIdentifier.builder(Subnetmaps.class).build();
278         Optional<Subnetmaps> subnetmaps = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapsid);
279         if (subnetmaps.isPresent() && subnetmaps.get().getSubnetmap() != null) {
280             List<Subnetmap> subnetMapList = subnetmaps.get().getSubnetmap();
281             for (Subnetmap subnetMap : subnetMapList) {
282                 if (subnetMap.getVpnId() != null && subnetMap.getVpnId().equals(vpnid)) {
283                     subnets.add(subnetMap.getId());
284                 }
285             }
286         }
287         return subnets;
288     }
289
290     protected static String getNeutronPortNameFromVpnPortFixedIp(DataBroker broker, String vpnName, String fixedIp) {
291         InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
292         Optional<VpnPortipToPort> vpnPortipToPortData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
293         if (vpnPortipToPortData.isPresent()) {
294             return vpnPortipToPortData.get().getPortName();
295         }
296         return null;
297     }
298
299     protected static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
300         InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
301         Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
302         if (optionalNetworkMap.isPresent()) {
303             return optionalNetworkMap.get().getSubnetIdList();
304         }
305         return null;
306     }
307
308     protected static List<Uuid> getPortIdsFromSubnetId(DataBroker broker, Uuid subnetId) {
309         InstanceIdentifier id = buildSubnetMapIdentifier(subnetId);
310         Optional<Subnetmap> optionalSubnetmap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
311         if (optionalSubnetmap.isPresent()) {
312             return optionalSubnetmap.get().getPortList();
313         }
314         return null;
315     }
316
317     protected static Router getNeutronRouter(DataBroker broker, Uuid routerId) {
318         Router router = null;
319         router = routerMap.get(routerId);
320         if (router != null) {
321             return router;
322         }
323         InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
324                 .class, new RouterKey(routerId));
325         Optional<Router> rtr = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
326         if (rtr.isPresent()) {
327             router = rtr.get();
328         }
329         return router;
330     }
331
332     protected static Network getNeutronNetwork(DataBroker broker, Uuid networkId) {
333         Network network = null;
334         network = networkMap.get(networkId);
335         if (network != null) {
336             return network;
337         }
338         LOG.debug("getNeutronNetwork for {}", networkId.getValue());
339         InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class)
340             .child(Network.class, new NetworkKey(networkId));
341         Optional<Network> net = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
342         if (net.isPresent()) {
343             network = net.get();
344         }
345         return network;
346     }
347
348     protected static Port getNeutronPort(DataBroker broker, Uuid portId) {
349         Port prt = null;
350         prt = portMap.get(portId);
351         if (prt != null) {
352             return prt;
353         }
354         LOG.debug("getNeutronPort for {}", portId.getValue());
355         InstanceIdentifier<Port> inst = InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class,
356                 new PortKey(portId));
357         Optional<Port> port = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
358         if (port.isPresent()) {
359             prt = port.get();
360         }
361         return prt;
362     }
363
364     /**
365      * Returns port_security_enabled status with the port.
366      *
367      * @param port the port
368      * @return port_security_enabled status
369      */
370     protected static boolean getPortSecurityEnabled(Port port) {
371         String deviceOwner = port.getDeviceOwner();
372         if (deviceOwner != null && deviceOwner.startsWith("network:")) {
373             // port with device owner of network:xxx is created by
374             // neutorn for its internal use. So security group doesn't apply.
375             // router interface, dhcp port and floating ip.
376             return false;
377         }
378         PortSecurityExtension portSecurity = port.getAugmentation(PortSecurityExtension.class);
379         if (portSecurity != null) {
380             return portSecurity.isPortSecurityEnabled();
381         }
382         return false;
383     }
384
385     /**
386      * Gets security group UUIDs delta   .
387      *
388      * @param port1SecurityGroups the port 1 security groups
389      * @param port2SecurityGroups the port 2 security groups
390      * @return the security groups delta
391      */
392     protected static List<Uuid> getSecurityGroupsDelta(List<Uuid> port1SecurityGroups,
393             List<Uuid> port2SecurityGroups) {
394         if (port1SecurityGroups == null) {
395             return null;
396         }
397
398         if (port2SecurityGroups == null) {
399             return port1SecurityGroups;
400         }
401
402         List<Uuid> list1 = new ArrayList<>(port1SecurityGroups);
403         List<Uuid> list2 = new ArrayList<>(port2SecurityGroups);
404         for (Iterator<Uuid> iterator = list1.iterator(); iterator.hasNext();) {
405             Uuid securityGroup1 = iterator.next();
406             for (Uuid securityGroup2 : list2) {
407                 if (securityGroup1.getValue().equals(securityGroup2.getValue())) {
408                     iterator.remove();
409                     break;
410                 }
411             }
412         }
413         return list1;
414     }
415
416     /**
417      * Gets the fixed ips delta.
418      *
419      * @param port1FixedIps the port 1 fixed ips
420      * @param port2FixedIps the port 2 fixed ips
421      * @return the fixed ips delta
422      */
423     protected static List<FixedIps> getFixedIpsDelta(List<FixedIps> port1FixedIps, List<FixedIps> port2FixedIps) {
424         if (port1FixedIps == null) {
425             return null;
426         }
427
428         if (port2FixedIps == null) {
429             return port1FixedIps;
430         }
431
432         List<FixedIps> list1 = new ArrayList<>(port1FixedIps);
433         List<FixedIps> list2 = new ArrayList<>(port2FixedIps);
434         for (Iterator<FixedIps> iterator = list1.iterator(); iterator.hasNext();) {
435             FixedIps fixedIps1 = iterator.next();
436             for (FixedIps fixedIps2 : list2) {
437                 if (fixedIps1.getIpAddress().equals(fixedIps2.getIpAddress())) {
438                     iterator.remove();
439                     break;
440                 }
441             }
442         }
443         return list1;
444     }
445
446     /**
447      * Gets the allowed address pairs delta.
448      *
449      * @param port1AllowedAddressPairs the port 1 allowed address pairs
450      * @param port2AllowedAddressPairs the port 2 allowed address pairs
451      * @return the allowed address pairs delta
452      */
453     protected static List<AllowedAddressPairs> getAllowedAddressPairsDelta(
454         List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
455             .AllowedAddressPairs> port1AllowedAddressPairs,
456         List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
457             .AllowedAddressPairs> port2AllowedAddressPairs) {
458         if (port1AllowedAddressPairs == null) {
459             return null;
460         }
461
462         if (port2AllowedAddressPairs == null) {
463             return getAllowedAddressPairsForAclService(port1AllowedAddressPairs);
464         }
465
466         List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
467             .AllowedAddressPairs> list1 =
468                 new ArrayList<>(port1AllowedAddressPairs);
469         List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
470             .AllowedAddressPairs> list2 =
471                 new ArrayList<>(port2AllowedAddressPairs);
472         for (Iterator<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
473             .AllowedAddressPairs> iterator =
474              list1.iterator(); iterator.hasNext();) {
475             org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
476                 .AllowedAddressPairs allowedAddressPair1 = iterator.next();
477             for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
478                      .AllowedAddressPairs allowedAddressPair2 : list2) {
479                 if (allowedAddressPair1.getKey().equals(allowedAddressPair2.getKey())) {
480                     iterator.remove();
481                     break;
482                 }
483             }
484         }
485         return getAllowedAddressPairsForAclService(list1);
486     }
487
488     /**
489      * Gets the acl allowed address pairs.
490      *
491      * @param macAddress the mac address
492      * @param ipAddress the ip address
493      * @return the acl allowed address pairs
494      */
495     protected static AllowedAddressPairs getAclAllowedAddressPairs(MacAddress macAddress,
496             org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddress ipAddress) {
497         AllowedAddressPairsBuilder aclAllowedAdressPairBuilder = new AllowedAddressPairsBuilder();
498         aclAllowedAdressPairBuilder.setMacAddress(macAddress);
499         if (ipAddress != null && ipAddress.getValue() != null) {
500             if (ipAddress.getIpPrefix() != null) {
501                 aclAllowedAdressPairBuilder.setIpAddress(new IpPrefixOrAddress(ipAddress.getIpPrefix()));
502             } else {
503                 aclAllowedAdressPairBuilder.setIpAddress(new IpPrefixOrAddress(ipAddress.getIpAddress()));
504             }
505         }
506         return aclAllowedAdressPairBuilder.build();
507     }
508
509     /**
510      * Gets the allowed address pairs for acl service.
511      *
512      * @param macAddress the mac address
513      * @param fixedIps the fixed ips
514      * @return the allowed address pairs for acl service
515      */
516     protected static List<AllowedAddressPairs> getAllowedAddressPairsForAclService(MacAddress macAddress,
517             List<FixedIps> fixedIps) {
518         List<AllowedAddressPairs> aclAllowedAddressPairs = new ArrayList<>();
519         for (FixedIps fixedIp : fixedIps) {
520             aclAllowedAddressPairs.add(getAclAllowedAddressPairs(macAddress,
521                     new org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddress(
522                             fixedIp.getIpAddress().getValue())));
523         }
524         return aclAllowedAddressPairs;
525     }
526
527     /**
528      * Gets the allowed address pairs for acl service.
529      *
530      * @param portAllowedAddressPairs the port allowed address pairs
531      * @return the allowed address pairs for acl service
532      */
533     protected static List<AllowedAddressPairs> getAllowedAddressPairsForAclService(
534         List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
535             .AllowedAddressPairs> portAllowedAddressPairs) {
536         List<AllowedAddressPairs> aclAllowedAddressPairs = new ArrayList<>();
537         for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.AllowedAddressPairs
538                  portAllowedAddressPair : portAllowedAddressPairs) {
539             aclAllowedAddressPairs.add(getAclAllowedAddressPairs(portAllowedAddressPair.getMacAddress(),
540                 portAllowedAddressPair.getIpAddress()));
541         }
542         return aclAllowedAddressPairs;
543     }
544
545     /**
546      * Gets the IPv6 Link Local Address corresponding to the MAC Address.
547      *
548      * @param macAddress the mac address
549      * @return the allowed address pairs for acl service which includes the MAC + IPv6LLA
550      */
551     protected static AllowedAddressPairs updateIPv6LinkLocalAddressForAclService(MacAddress macAddress) {
552         IpAddress ipv6LinkLocalAddress = getIpv6LinkLocalAddressFromMac(macAddress);
553         return getAclAllowedAddressPairs(macAddress,
554                 new org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.types.rev160517.IpPrefixOrAddress(
555                         ipv6LinkLocalAddress.getValue()));
556     }
557
558     /**
559      * Gets the updated security groups.
560      *
561      * @param aclInterfaceSecurityGroups the acl interface security groups
562      * @param origSecurityGroups the orig security groups
563      * @param newSecurityGroups the new security groups
564      * @return the updated security groups
565      */
566     protected static List<Uuid> getUpdatedSecurityGroups(List<Uuid> aclInterfaceSecurityGroups,
567             List<Uuid> origSecurityGroups, List<Uuid> newSecurityGroups) {
568         List<Uuid> addedGroups = getSecurityGroupsDelta(newSecurityGroups, origSecurityGroups);
569         List<Uuid> deletedGroups = getSecurityGroupsDelta(origSecurityGroups, newSecurityGroups);
570         List<Uuid> updatedSecurityGroups =
571                 aclInterfaceSecurityGroups != null ? new ArrayList<>(aclInterfaceSecurityGroups) : new ArrayList<>();
572         if (addedGroups != null) {
573             updatedSecurityGroups.addAll(addedGroups);
574         }
575         if (deletedGroups != null) {
576             updatedSecurityGroups.removeAll(deletedGroups);
577         }
578         return updatedSecurityGroups;
579     }
580
581     /**
582      * Gets the allowed address pairs for fixed ips.
583      *
584      * @param aclInterfaceAllowedAddressPairs the acl interface allowed address pairs
585      * @param portMacAddress the port mac address
586      * @param origFixedIps the orig fixed ips
587      * @param newFixedIps the new fixed ips
588      * @return the allowed address pairs for fixed ips
589      */
590     protected static List<AllowedAddressPairs> getAllowedAddressPairsForFixedIps(
591             List<AllowedAddressPairs> aclInterfaceAllowedAddressPairs, MacAddress portMacAddress,
592             List<FixedIps> origFixedIps, List<FixedIps> newFixedIps) {
593         List<FixedIps> addedFixedIps = getFixedIpsDelta(newFixedIps, origFixedIps);
594         List<FixedIps> deletedFixedIps = getFixedIpsDelta(origFixedIps, newFixedIps);
595         List<AllowedAddressPairs> updatedAllowedAddressPairs =
596             aclInterfaceAllowedAddressPairs != null
597                 ? new ArrayList<>(aclInterfaceAllowedAddressPairs) : new ArrayList<>();
598         if (deletedFixedIps != null) {
599             updatedAllowedAddressPairs.removeAll(getAllowedAddressPairsForAclService(portMacAddress, deletedFixedIps));
600         }
601         if (addedFixedIps != null) {
602             updatedAllowedAddressPairs.addAll(getAllowedAddressPairsForAclService(portMacAddress, addedFixedIps));
603         }
604         return updatedAllowedAddressPairs;
605     }
606
607     /**
608      * Gets the updated allowed address pairs.
609      *
610      * @param aclInterfaceAllowedAddressPairs the acl interface allowed address pairs
611      * @param origAllowedAddressPairs the orig allowed address pairs
612      * @param newAllowedAddressPairs the new allowed address pairs
613      * @return the updated allowed address pairs
614      */
615     protected static List<AllowedAddressPairs> getUpdatedAllowedAddressPairs(
616             List<AllowedAddressPairs> aclInterfaceAllowedAddressPairs,
617             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
618                 .AllowedAddressPairs> origAllowedAddressPairs,
619             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes
620                 .AllowedAddressPairs> newAllowedAddressPairs) {
621         List<AllowedAddressPairs> addedAllowedAddressPairs =
622             getAllowedAddressPairsDelta(newAllowedAddressPairs,origAllowedAddressPairs);
623         List<AllowedAddressPairs> deletedAllowedAddressPairs =
624             getAllowedAddressPairsDelta(origAllowedAddressPairs, newAllowedAddressPairs);
625         List<AllowedAddressPairs> updatedAllowedAddressPairs =
626             aclInterfaceAllowedAddressPairs != null
627                 ? new ArrayList<>(aclInterfaceAllowedAddressPairs) : new ArrayList<>();
628         if (addedAllowedAddressPairs != null) {
629             updatedAllowedAddressPairs.addAll(addedAllowedAddressPairs);
630         }
631         if (deletedAllowedAddressPairs != null) {
632             updatedAllowedAddressPairs.removeAll(deletedAllowedAddressPairs);
633         }
634         return updatedAllowedAddressPairs;
635     }
636
637     /**
638      * Populate interface acl builder.
639      *
640      * @param interfaceAclBuilder the interface acl builder
641      * @param port the port
642      */
643     protected static void populateInterfaceAclBuilder(InterfaceAclBuilder interfaceAclBuilder, Port port) {
644         // Handle security group enabled
645         List<Uuid> securityGroups = port.getSecurityGroups();
646         if (securityGroups != null) {
647             interfaceAclBuilder.setSecurityGroups(securityGroups);
648         }
649         List<AllowedAddressPairs> aclAllowedAddressPairs = NeutronvpnUtils.getAllowedAddressPairsForAclService(
650                 port.getMacAddress(), port.getFixedIps());
651         // Update the allowed address pair with the IPv6 LLA that is auto configured on the port.
652         aclAllowedAddressPairs.add(NeutronvpnUtils.updateIPv6LinkLocalAddressForAclService(port.getMacAddress()));
653         List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.AllowedAddressPairs>
654             portAllowedAddressPairs = port.getAllowedAddressPairs();
655         if (portAllowedAddressPairs != null) {
656             aclAllowedAddressPairs.addAll(NeutronvpnUtils.getAllowedAddressPairsForAclService(portAllowedAddressPairs));
657         }
658         interfaceAclBuilder.setAllowedAddressPairs(aclAllowedAddressPairs);
659     }
660
661     protected static Subnet getNeutronSubnet(DataBroker broker, Uuid subnetId) {
662         Subnet subnet = null;
663         subnet = subnetMap.get(subnetId);
664         if (subnet != null) {
665             return subnet;
666         }
667         InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).child(Subnets.class).child(Subnet
668                 .class, new SubnetKey(subnetId));
669         Optional<Subnet> sn = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
670
671         if (sn.isPresent()) {
672             subnet = sn.get();
673         }
674         return subnet;
675     }
676
677     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
678         LOG.debug("getNeutronRouterSubnetIds for {}", routerId.getValue());
679         List<Uuid> subnetIdList = new ArrayList<>();
680         Optional<Subnetmaps> subnetMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
681             InstanceIdentifier.builder(Subnetmaps.class).build());
682         if (subnetMaps.isPresent() && subnetMaps.get().getSubnetmap() != null) {
683             for (Subnetmap subnetmap : subnetMaps.get().getSubnetmap()) {
684                 if (routerId.equals(subnetmap.getRouterId())) {
685                     subnetIdList.add(subnetmap.getId());
686                 }
687             }
688         }
689         LOG.debug("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
690         return subnetIdList;
691     }
692
693     // TODO Clean up the exception handling
694     @SuppressWarnings("checkstyle:IllegalCatch")
695     protected static boolean lock(String lockName) {
696         if (locks.get(lockName) != null) {
697             synchronized (locks) {
698                 if (locks.get(lockName) == null) {
699                     locks.putIfAbsent(lockName, new ImmutablePair<>(new
700                             ReentrantReadWriteLock(), new AtomicInteger(0)));
701                 }
702                 locks.get(lockName).getRight().incrementAndGet();
703             }
704             try {
705                 if (locks.get(lockName) != null) {
706                     locks.get(lockName).getLeft().writeLock().tryLock(LOCK_WAIT_TIME, secUnit);
707                 }
708             } catch (InterruptedException e) {
709                 locks.get(lockName).getRight().decrementAndGet();
710                 LOG.error("Unable to acquire lock for  {}", lockName);
711                 throw new RuntimeException(String.format("Unable to acquire lock for %s", lockName), e.getCause());
712             }
713         } else {
714             locks.putIfAbsent(lockName, new ImmutablePair<>(new ReentrantReadWriteLock(),
715                     new AtomicInteger(0)));
716             locks.get(lockName).getRight().incrementAndGet();
717             try {
718                 locks.get(lockName).getLeft().writeLock().tryLock(LOCK_WAIT_TIME, secUnit);
719             } catch (Exception e) {
720                 locks.get(lockName).getRight().decrementAndGet();
721                 LOG.error("Unable to acquire lock for  {}", lockName);
722                 throw new RuntimeException(String.format("Unable to acquire lock for %s", lockName), e.getCause());
723             }
724         }
725         return true;
726     }
727
728     // TODO Clean up the exception handling
729     @SuppressWarnings("checkstyle:IllegalCatch")
730     protected static boolean unlock(String lockName) {
731         if (locks.get(lockName) != null) {
732             try {
733                 locks.get(lockName).getLeft().writeLock().unlock();
734             } catch (Exception e) {
735                 LOG.error("Unable to un-lock for " + lockName, e);
736                 return false;
737             }
738             if (0 == locks.get(lockName).getRight().decrementAndGet()) {
739                 synchronized (locks) {
740                     if (locks.get(lockName).getRight().get() == 0) {
741                         locks.remove(lockName);
742                     }
743                 }
744             }
745         }
746         return true;
747     }
748
749     // TODO Clean up the exception handling and the console output
750     @SuppressWarnings({"checkstyle:IllegalCatch", "checkstyle:RegexpSinglelineJava"})
751     protected static Short getIPPrefixFromPort(DataBroker broker, Port port) {
752         try {
753             Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
754             SubnetKey subnetkey = new SubnetKey(subnetUUID);
755             InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
756                     .class).child(Subnet.class, subnetkey);
757             Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
758             if (subnet.isPresent()) {
759                 String cidr = String.valueOf(subnet.get().getCidr().getValue());
760                 // Extract the prefix length from cidr
761                 String[] parts = cidr.split("/");
762                 if (parts.length == 2) {
763                     return Short.valueOf(parts[1]);
764                 } else {
765                     LOG.trace("Could not retrieve prefix from subnet CIDR");
766                     System.out.println("Could not retrieve prefix from subnet CIDR");
767                 }
768             } else {
769                 LOG.trace("Unable to read on subnet datastore");
770             }
771         } catch (Exception e) {
772             LOG.error("Failed to retrieve IP prefix from port : ", e);
773             System.out.println("Failed to retrieve IP prefix from port : " + e.getMessage());
774         }
775         return null;
776     }
777
778     // TODO Clean up the exception handling
779     @SuppressWarnings("checkstyle:IllegalCatch")
780     protected static void createVpnPortFixedIpToPort(DataBroker broker,String vpnName, String fixedIp,
781                                                      String portName, String macAddress, boolean isSubnetIp,
782                                                      WriteTransaction writeConfigTxn) {
783         InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier(vpnName, fixedIp);
784         VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder()
785             .setKey(new VpnPortipToPortKey(fixedIp, vpnName))
786             .setVpnName(vpnName).setPortFixedip(fixedIp)
787             .setPortName(portName).setMacAddress(macAddress).setSubnetIp(isSubnetIp);
788         try {
789             if (writeConfigTxn != null) {
790                 writeConfigTxn.put(LogicalDatastoreType.CONFIGURATION, id, builder.build());
791             } else {
792                 MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, builder.build());
793             }
794             LOG.trace("Neutron port with fixedIp: {}, vpn {}, interface {}, mac {}, isSubnetIp {} added to "
795                 + "VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress, isSubnetIp);
796         } catch (Exception e) {
797             LOG.error("Failure while creating VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp,
798                     e);
799         }
800     }
801
802     // TODO Clean up the exception handling
803     @SuppressWarnings("checkstyle:IllegalCatch")
804     protected static void removeVpnPortFixedIpToPort(DataBroker broker, String vpnName,
805                                                      String fixedIp, WriteTransaction writeConfigTxn) {
806         InstanceIdentifier<VpnPortipToPort> id = NeutronvpnUtils.buildVpnPortipToPortIdentifier(vpnName, fixedIp);
807         try {
808             if (writeConfigTxn != null) {
809                 writeConfigTxn.delete(LogicalDatastoreType.CONFIGURATION, id);
810             } else {
811                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
812             }
813             LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from LearntVpnPortipToPort DS", fixedIp,
814                     vpnName);
815         } catch (Exception e) {
816             LOG.error("Failure while removing VPNPortFixedIpToPort map for vpn {} - fixedIP {}", vpnName, fixedIp,
817                     e);
818         }
819     }
820
821     // TODO Clean up the exception handling
822     @SuppressWarnings("checkstyle:IllegalCatch")
823     protected static void removeLearntVpnVipToPort(DataBroker broker, String vpnName, String fixedIp) {
824         InstanceIdentifier<LearntVpnVipToPort> id = NeutronvpnUtils.buildLearntVpnVipToPortIdentifier(vpnName, fixedIp);
825         try {
826             synchronized ((vpnName + fixedIp).intern()) {
827                 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
828             }
829             LOG.trace("Neutron router port with fixedIp: {}, vpn {} removed from LearntVpnPortipToPort DS", fixedIp,
830                     vpnName);
831         } catch (Exception e) {
832             LOG.error("Failure while removing LearntVpnPortFixedIpToPort map for vpn {} - fixedIP {}",
833                 vpnName, fixedIp, e);
834         }
835     }
836
837     public static void addToNetworkCache(Network network) {
838         networkMap.put(network.getUuid(), network);
839     }
840
841     public static void removeFromNetworkCache(Network network) {
842         networkMap.remove(network.getUuid());
843     }
844
845     public static void addToRouterCache(Router router) {
846         routerMap.put(router.getUuid(), router);
847     }
848
849     public static void removeFromRouterCache(Router router) {
850         routerMap.remove(router.getUuid());
851     }
852
853     public static void addToPortCache(Port port) {
854         portMap.put(port.getUuid(), port);
855     }
856
857     public static void removeFromPortCache(Port port) {
858         portMap.remove(port.getUuid());
859     }
860
861     public static void addToSubnetCache(Subnet subnet) {
862         subnetMap.put(subnet.getUuid(), subnet);
863         IpAddress gatewayIp = subnet.getGatewayIp();
864         if (gatewayIp != null) {
865             subnetGwIpMap.computeIfAbsent(gatewayIp, k -> Sets.newConcurrentHashSet()).add(subnet.getUuid());
866         }
867     }
868
869     public static void removeFromSubnetCache(Subnet subnet) {
870         subnetMap.remove(subnet.getUuid());
871         IpAddress gatewayIp = subnet.getGatewayIp();
872         if (gatewayIp != null) {
873             Set<Uuid> gwIps = subnetGwIpMap.get(gatewayIp);
874             if (gwIps != null) {
875                 gwIps.remove(subnet.getUuid());
876             }
877         }
878     }
879
880     public static String getSegmentationIdFromNeutronNetwork(Network network) {
881         String segmentationId = null;
882         NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
883         if (providerExtension != null) {
884             Class<? extends NetworkTypeBase> networkType = providerExtension.getNetworkType();
885             segmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(network, networkType);
886         }
887
888         return segmentationId;
889     }
890
891     public static Class<? extends SegmentTypeBase> getSegmentTypeFromNeutronNetwork(Network network) {
892         NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
893         return providerExtension != null ? NETWORK_MAP.get(providerExtension.getNetworkType()) : null;
894     }
895
896     public static String getPhysicalNetworkName(Network network) {
897         NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
898         return providerExtension != null ? providerExtension.getPhysicalNetwork() : null;
899     }
900
901     public static Collection<Uuid> getSubnetIdsForGatewayIp(IpAddress ipAddress) {
902         return subnetGwIpMap.getOrDefault(ipAddress, Collections.emptySet());
903     }
904
905     static InstanceIdentifier<VpnPortipToPort> buildVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
906         InstanceIdentifier<VpnPortipToPort> id =
907             InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
908                 .child(VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
909         return id;
910     }
911
912     static InstanceIdentifier<LearntVpnVipToPort> buildLearntVpnVipToPortIdentifier(String vpnName, String fixedIp) {
913         InstanceIdentifier<LearntVpnVipToPort> id =
914             InstanceIdentifier.builder(LearntVpnVipToPortData.class)
915                 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(fixedIp, vpnName)).build();
916         return id;
917     }
918
919     static Boolean getIsExternal(Network network) {
920         return network.getAugmentation(NetworkL3Extension.class) != null
921                 && network.getAugmentation(NetworkL3Extension.class).isExternal();
922     }
923
924     public static void addToQosPolicyCache(QosPolicy qosPolicy) {
925         qosPolicyMap.put(qosPolicy.getUuid(),qosPolicy);
926     }
927
928     public static void removeFromQosPolicyCache(QosPolicy qosPolicy) {
929         qosPolicyMap.remove(qosPolicy.getUuid());
930     }
931
932     public static void addToQosPortsCache(Uuid qosUuid, Port port) {
933         if (qosPortsMap.containsKey(qosUuid)) {
934             if (!qosPortsMap.get(qosUuid).containsKey(port.getUuid())) {
935                 qosPortsMap.get(qosUuid).put(port.getUuid(), port);
936             }
937         } else {
938             HashMap<Uuid, Port> portMap = new HashMap<>();
939             portMap.put(port.getUuid(), port);
940             qosPortsMap.put(qosUuid, portMap);
941         }
942     }
943
944     public static void removeFromQosPortsCache(Uuid qosUuid, Port port) {
945         if (qosPortsMap.containsKey(qosUuid) && qosPortsMap.get(qosUuid).containsKey(port.getUuid())) {
946             qosPortsMap.get(qosUuid).remove(port.getUuid(), port);
947         }
948     }
949
950     public static void addToQosNetworksCache(Uuid qosUuid, Network network) {
951         if (qosNetworksMap.containsKey(qosUuid)) {
952             if (!qosNetworksMap.get(qosUuid).containsKey(network.getUuid())) {
953                 qosNetworksMap.get(qosUuid).put(network.getUuid(), network);
954             }
955         } else {
956             HashMap<Uuid, Network> networkMap = new HashMap<>();
957             networkMap.put(network.getUuid(), network);
958             qosNetworksMap.put(qosUuid, networkMap);
959         }
960     }
961
962     public static void removeFromQosNetworksCache(Uuid qosUuid, Network network) {
963         if (qosNetworksMap.containsKey(qosUuid) && qosNetworksMap.get(qosUuid).containsKey(network.getUuid())) {
964             qosNetworksMap.get(qosUuid).remove(network.getUuid(), network);
965         }
966     }
967
968     static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
969         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
970                 NetworkMapKey(networkId)).build();
971         return id;
972     }
973
974     static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
975         InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).child(VpnInterface
976                 .class, new VpnInterfaceKey(ifName)).build();
977         return id;
978     }
979
980     static InstanceIdentifier<Subnetmap> buildSubnetMapIdentifier(Uuid subnetId) {
981         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
982                 SubnetmapKey(subnetId)).build();
983         return id;
984     }
985
986     static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
987         InstanceIdentifier<Interface> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new
988                 InterfaceKey(interfaceName)).build();
989         return id;
990     }
991
992     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext
993             .routers.Routers> buildExtRoutersIdentifier(Uuid routerId) {
994         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers
995                 .Routers> id = InstanceIdentifier.builder(ExtRouters.class).child(org.opendaylight.yang.gen.v1.urn
996                 .opendaylight.netvirt.natservice.rev160111.ext.routers.Routers.class, new RoutersKey(routerId
997                 .getValue())).build();
998         return id;
999     }
1000
1001     static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1002         return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1003                 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1004     }
1005
1006     // TODO Clean up the exception handling
1007     @SuppressWarnings("checkstyle:IllegalCatch")
1008     static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
1009                                                    InstanceIdentifier<T> path) {
1010         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
1011         Optional<T> result = Optional.absent();
1012         try {
1013             result = tx.read(datastoreType, path).get();
1014         } catch (Exception e) {
1015             throw new RuntimeException(e);
1016         }
1017         return result;
1018     }
1019
1020     static ProviderTypes getProviderNetworkType(Network network) {
1021         if (network == null) {
1022             LOG.error("Error in getting provider network type since network is null");
1023             return null;
1024         }
1025         NetworkProviderExtension npe = network.getAugmentation(NetworkProviderExtension.class);
1026         if (npe != null) {
1027             Class<? extends NetworkTypeBase> networkTypeBase = npe.getNetworkType();
1028             if (networkTypeBase != null) {
1029                 if (networkTypeBase.isAssignableFrom(NetworkTypeFlat.class)) {
1030                     return ProviderTypes.FLAT;
1031                 } else if (networkTypeBase.isAssignableFrom(NetworkTypeVlan.class)) {
1032                     return ProviderTypes.VLAN;
1033                 } else if (networkTypeBase.isAssignableFrom(NetworkTypeVxlan.class)) {
1034                     return ProviderTypes.VXLAN;
1035                 } else if (networkTypeBase.isAssignableFrom(NetworkTypeGre.class)) {
1036                     return ProviderTypes.GRE;
1037                 }
1038             }
1039         }
1040         return null;
1041     }
1042
1043     static boolean isNetworkTypeSupported(Network network) {
1044         NetworkProviderExtension npe = network.getAugmentation(NetworkProviderExtension.class);
1045         return npe != null && npe.getNetworkType() != null && SUPPORTED_NETWORK_TYPES.contains(npe.getNetworkType());
1046     }
1047
1048     static boolean isNetworkOfType(Network network, Class<? extends NetworkTypeBase> type) {
1049         NetworkProviderExtension npe = network.getAugmentation(NetworkProviderExtension.class);
1050         return npe != null && npe.getNetworkType() != null && type.isAssignableFrom(npe.getNetworkType());
1051     }
1052
1053     static boolean isFlatOrVlanNetwork(Network network) {
1054         return network != null
1055                 && (isNetworkOfType(network, NetworkTypeVlan.class) || isNetworkOfType(network, NetworkTypeFlat.class));
1056     }
1057
1058     static boolean isVlanOrVxlanNetwork(Class<? extends NetworkTypeBase> type) {
1059         return type.isAssignableFrom(NetworkTypeVxlan.class) || type.isAssignableFrom(NetworkTypeVlan.class);
1060     }
1061
1062     /**
1063      * Get inter-VPN link state.
1064      *
1065      * @param broker data broker
1066      * @param vpnLinkName VPN link name
1067      * @return Optional of InterVpnLinkState
1068      */
1069     public static Optional<InterVpnLinkState> getInterVpnLinkState(DataBroker broker, String vpnLinkName) {
1070         InstanceIdentifier<InterVpnLinkState> vpnLinkStateIid = InstanceIdentifier.builder(InterVpnLinkStates.class)
1071                 .child(InterVpnLinkState.class, new InterVpnLinkStateKey(vpnLinkName)).build();
1072         return read(broker, LogicalDatastoreType.CONFIGURATION, vpnLinkStateIid);
1073     }
1074
1075     /**
1076      * Returns an InterVpnLink by searching by one of its endpoint's IP.
1077      *
1078      * @param broker The Databroker
1079      * @param endpointIp IP to search for
1080      * @return a InterVpnLink
1081      */
1082     public static Optional<InterVpnLink> getInterVpnLinkByEndpointIp(DataBroker broker, String endpointIp) {
1083         InstanceIdentifier<InterVpnLinks> interVpnLinksIid = InstanceIdentifier.builder(InterVpnLinks.class).build();
1084         Optional<InterVpnLinks> interVpnLinksOpData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1085                 interVpnLinksIid);
1086         if (interVpnLinksOpData.isPresent()) {
1087             List<InterVpnLink> allInterVpnLinks = interVpnLinksOpData.get().getInterVpnLink();
1088             for (InterVpnLink interVpnLink : allInterVpnLinks) {
1089                 if (interVpnLink.getFirstEndpoint().getIpAddress().getValue().equals(endpointIp)
1090                         || interVpnLink.getSecondEndpoint().getIpAddress().getValue().equals(endpointIp)) {
1091                     return Optional.of(interVpnLink);
1092                 }
1093             }
1094         }
1095         return Optional.absent();
1096     }
1097
1098
1099     public static Set<RouterDpnList> getAllRouterDpnList(DataBroker broker, BigInteger dpid) {
1100         Set<RouterDpnList> ret = new HashSet<>();
1101         InstanceIdentifier<NeutronRouterDpns> routerDpnId =
1102                 InstanceIdentifier.create(NeutronRouterDpns.class);
1103         Optional<NeutronRouterDpns> neutronRouterDpnsOpt =
1104             MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerDpnId);
1105         if (neutronRouterDpnsOpt.isPresent()) {
1106             NeutronRouterDpns neutronRouterDpns = neutronRouterDpnsOpt.get();
1107             List<RouterDpnList> routerDpnLists = neutronRouterDpns.getRouterDpnList();
1108             for (RouterDpnList routerDpnList : routerDpnLists) {
1109                 if (routerDpnList.getDpnVpninterfacesList() != null) {
1110                     for (DpnVpninterfacesList dpnInterfaceList : routerDpnList.getDpnVpninterfacesList()) {
1111                         if (dpnInterfaceList.getDpnId().equals(dpid)) {
1112                             ret.add(routerDpnList);
1113                         }
1114                     }
1115                 }
1116             }
1117         }
1118         return ret;
1119     }
1120
1121     protected static Integer getUniqueRDId(IdManagerService idManager, String poolName, String idKey) {
1122         AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
1123         try {
1124             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
1125             RpcResult<AllocateIdOutput> rpcResult = result.get();
1126             if (rpcResult.isSuccessful()) {
1127                 return rpcResult.getResult().getIdValue().intValue();
1128             } else {
1129                 LOG.debug("RPC Call to Get Unique Id returned with Errors", rpcResult.getErrors());
1130             }
1131         } catch (InterruptedException | ExecutionException e) {
1132             LOG.debug("Exception when getting Unique Id", e);
1133         }
1134         return null;
1135     }
1136
1137     protected static void releaseRDId(IdManagerService idManager, String poolName, String idKey) {
1138         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
1139         try {
1140             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
1141             RpcResult<Void> rpcResult = result.get();
1142             if (!rpcResult.isSuccessful()) {
1143                 LOG.debug("RPC Call to Get Unique Id returned with Errors", rpcResult.getErrors());
1144             } else {
1145                 LOG.info("ID for RD " + idKey + " released successfully");
1146             }
1147         } catch (InterruptedException | ExecutionException e) {
1148             LOG.debug("Exception when trying to release ID into the pool", idKey, e);
1149         }
1150     }
1151
1152     protected static IpAddress getIpv6LinkLocalAddressFromMac(MacAddress mac) {
1153         byte[] octets = bytesFromHexString(mac.getValue());
1154
1155         /* As per the RFC2373, steps involved to generate a LLA include
1156            1. Convert the 48 bit MAC address to 64 bit value by inserting 0xFFFE
1157               between OUI and NIC Specific part.
1158            2. Invert the Universal/Local flag in the OUI portion of the address.
1159            3. Use the prefix "FE80::/10" along with the above 64 bit Interface
1160               identifier to generate the IPv6 LLA. */
1161
1162         StringBuffer interfaceID = new StringBuffer();
1163         short u8byte = (short) (octets[0] & 0xff);
1164         u8byte ^= 1 << 1;
1165         interfaceID.append(Integer.toHexString(0xFF & u8byte));
1166         interfaceID.append(StringUtils.leftPad(Integer.toHexString(0xFF & octets[1]), 2, "0"));
1167         interfaceID.append(":");
1168         interfaceID.append(Integer.toHexString(0xFF & octets[2]));
1169         interfaceID.append("ff:fe");
1170         interfaceID.append(StringUtils.leftPad(Integer.toHexString(0xFF & octets[3]), 2, "0"));
1171         interfaceID.append(":");
1172         interfaceID.append(Integer.toHexString(0xFF & octets[4]));
1173         interfaceID.append(StringUtils.leftPad(Integer.toHexString(0xFF & octets[5]), 2, "0"));
1174
1175         Ipv6Address ipv6LLA = new Ipv6Address("fe80:0:0:0:" + interfaceID.toString());
1176         IpAddress ipAddress = new IpAddress(ipv6LLA.getValue().toCharArray());
1177         return ipAddress;
1178     }
1179
1180     protected static byte[] bytesFromHexString(String values) {
1181         String target = "";
1182         if (values != null) {
1183             target = values;
1184         }
1185         String[] octets = target.split(":");
1186
1187         byte[] ret = new byte[octets.length];
1188         for (int i = 0; i < octets.length; i++) {
1189             ret[i] = Integer.valueOf(octets[i], 16).byteValue();
1190         }
1191         return ret;
1192     }
1193
1194     static List<String> getExistingRDs(DataBroker broker) {
1195         List<String> existingRDs = new ArrayList<>();
1196         InstanceIdentifier<VpnInstances> path = InstanceIdentifier.builder(VpnInstances.class).build();
1197         Optional<VpnInstances> vpnInstancesOptional =
1198             NeutronvpnUtils.read(broker, LogicalDatastoreType.CONFIGURATION, path);
1199         if (vpnInstancesOptional.isPresent() && vpnInstancesOptional.get().getVpnInstance() != null) {
1200             for (VpnInstance vpnInstance : vpnInstancesOptional.get().getVpnInstance()) {
1201                 if (vpnInstance.getIpv4Family() == null) {
1202                     continue;
1203                 }
1204                 List<String> rds = vpnInstance.getIpv4Family().getRouteDistinguisher();
1205                 if (rds != null) {
1206                     existingRDs.addAll(rds);
1207                 }
1208             }
1209         }
1210         return existingRDs;
1211     }
1212
1213     protected static boolean doesVpnExist(DataBroker broker, Uuid vpnId) {
1214         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
1215                 new VpnMapKey(vpnId)).build();
1216         return read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier).isPresent();
1217     }
1218
1219     protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1220         .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1221         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1222             .rev160111.external.subnets.Subnets> subnetsIdentifier =
1223                 InstanceIdentifier.builder(ExternalSubnets.class)
1224                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1225                         .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1226         return read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1227     }
1228 }