Remove unneeded code from VpnUtil
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnUtil.java
1 /*
2  * Copyright (c) 2016 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.vpnmanager;
10
11 import java.math.BigInteger;
12 import java.net.InetAddress;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.LinkedList;
16 import java.util.List;
17 import java.util.Objects;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Future;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
23 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
26 import org.opendaylight.genius.mdsalutil.FlowEntity;
27 import org.opendaylight.genius.mdsalutil.InstructionInfo;
28 import org.opendaylight.genius.mdsalutil.InstructionType;
29 import org.opendaylight.genius.mdsalutil.MDSALUtil;
30 import org.opendaylight.genius.mdsalutil.MatchFieldType;
31 import org.opendaylight.genius.mdsalutil.MatchInfo;
32 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
33 import org.opendaylight.genius.mdsalutil.NwConstants;
34 import org.opendaylight.genius.mdsalutil.NWUtil;
35 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
36 import org.opendaylight.genius.utils.cache.DataStoreCache;
37 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
38 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
39 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
40 import org.opendaylight.netvirt.vpnmanager.utilities.InterfaceUtils;
41 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
42 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
43 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
44 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
45 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
46 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
47 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
48 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TimeUnits;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInputBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanTagNameMap;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagName;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntryKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.RouterInterfaces;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnToExtraroute;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIds;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIdsBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.VpnIdsKey;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterface;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces.RouterInterfaceKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.Vpn;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.VpnBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.VpnKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.vpn.Extraroute;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroute.vpn.ExtrarouteKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceInputBuilder;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetPortFromInterfaceOutput;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.L3nexthop;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthops;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3nexthop.rev150409.l3nexthop.VpnNexthopsKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.RouterInterfacesMap;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortBuilder;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionBase;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV4;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
166 import org.opendaylight.yangtools.yang.binding.DataObject;
167 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
168 import org.opendaylight.yangtools.yang.common.RpcResult;
169 import org.opendaylight.yangtools.yang.data.impl.schema.tree.SchemaValidationFailedException;
170 import org.slf4j.Logger;
171 import org.slf4j.LoggerFactory;
172
173 import com.google.common.base.Optional;
174 import com.google.common.primitives.Ints;
175 import com.google.common.util.concurrent.CheckedFuture;
176 import com.google.common.util.concurrent.FutureCallback;
177 import com.google.common.util.concurrent.Futures;
178
179 public class VpnUtil {
180     private static final Logger LOG = LoggerFactory.getLogger(VpnUtil.class);
181     private static final int DEFAULT_PREFIX_LENGTH = 32;
182     private static final String PREFIX_SEPARATOR = "/";
183
184     static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
185         return InstanceIdentifier.builder(VpnInterfaces.class)
186                 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
187     }
188
189     static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
190         return InstanceIdentifier.builder(VpnInstances.class)
191                 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
192     }
193
194     static VpnInterface getVpnInterface(String intfName, String vpnName, Adjacencies aug, BigInteger dpnId, Boolean isSheduledForRemove) {
195         return new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(intfName)).setVpnInstanceName(vpnName).setDpnId(dpnId)
196                 .setScheduledForRemove(isSheduledForRemove).addAugmentation(Adjacencies.class, aug)
197                 .build();
198     }
199
200     static InstanceIdentifier<Prefixes> getPrefixToInterfaceIdentifier(long vpnId, String ipPrefix) {
201         return InstanceIdentifier.builder(PrefixToInterface.class)
202                 .child(VpnIds.class, new VpnIdsKey(vpnId)).child(Prefixes.class,
203                         new PrefixesKey(ipPrefix)).build();
204     }
205
206     static InstanceIdentifier<VpnIds> getPrefixToInterfaceIdentifier(long vpnId) {
207         return InstanceIdentifier.builder(PrefixToInterface.class)
208                 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
209     }
210
211     static VpnIds getPrefixToInterface(long vpnId) {
212         return new VpnIdsBuilder().setKey(new VpnIdsKey(vpnId)).setVpnId(vpnId).build();
213     }
214
215     static Prefixes getPrefixToInterface(BigInteger dpId, String vpnInterfaceName, String ipPrefix) {
216         return new PrefixesBuilder().setDpnId(dpId).setVpnInterfaceName(
217                 vpnInterfaceName).setIpAddress(ipPrefix).build();
218     }
219
220     static InstanceIdentifier<Extraroute> getVpnToExtrarouteIdentifier(String vrfId, String ipPrefix) {
221         return InstanceIdentifier.builder(VpnToExtraroute.class)
222                 .child(Vpn.class, new VpnKey(vrfId)).child(Extraroute.class,
223                         new ExtrarouteKey(ipPrefix)).build();
224     }
225
226     static InstanceIdentifier<Vpn> getVpnToExtrarouteIdentifier(String vrfId) {
227         return InstanceIdentifier.builder(VpnToExtraroute.class)
228                 .child(Vpn.class, new VpnKey(vrfId)).build();
229     }
230
231     static Vpn getVpnToExtraRoute(String vrfId) {
232         return new VpnBuilder().setKey(new VpnKey(vrfId)).setVrfId(vrfId).build();
233     }
234
235     /**
236      * Get VRF table given a Route Distinguisher
237      *
238      * @param broker dataBroker service reference
239      * @param rd Route-Distinguisher
240      * @return VrfTables that holds the list of VrfEntries of the specified rd
241      */
242     public static VrfTables getVrfTable(DataBroker broker, String rd) {
243         InstanceIdentifier<VrfTables> id =
244                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
245         Optional<VrfTables> vrfTable = read(broker, LogicalDatastoreType.CONFIGURATION, id);
246         return vrfTable.isPresent() ? vrfTable.get() : null;
247     }
248
249     /**
250      * Retrieves the VrfEntries that belong to a given VPN filtered out by
251      * Origin, searching by its Route-Distinguisher
252      *
253      * @param broker dataBroker service reference
254      * @param rd     Route-distinguisher of the VPN
255      * @param originsToConsider Only entries whose origin is included in this
256      *     list will be considered
257      * @return the list of VrfEntries
258      */
259     public static List<VrfEntry> getVrfEntriesByOrigin(DataBroker broker, String rd,
260                                                        List<RouteOrigin> originsToConsider) {
261         List<VrfEntry> result = new ArrayList<VrfEntry>();
262         List<VrfEntry> allVpnVrfEntries = getAllVrfEntries(broker, rd);
263         for (VrfEntry vrfEntry : allVpnVrfEntries) {
264             if (originsToConsider.contains(RouteOrigin.value(vrfEntry.getOrigin()))) {
265                 result.add(vrfEntry);
266             }
267         }
268         return result;
269     }
270
271     static List<Prefixes> getAllPrefixesToInterface(DataBroker broker, long vpnId) {
272         Optional<VpnIds> vpnIds = read(broker, LogicalDatastoreType.OPERATIONAL, getPrefixToInterfaceIdentifier(vpnId));
273         if (vpnIds.isPresent()) {
274             return vpnIds.get().getPrefixes();
275         }
276         return new ArrayList<Prefixes>();
277     }
278
279     static List<Extraroute> getAllExtraRoutes(DataBroker broker, String vrfId) {
280         Optional<Vpn> extraRoutes = read(broker, LogicalDatastoreType.OPERATIONAL, getVpnToExtrarouteIdentifier(vrfId));
281         if (extraRoutes.isPresent()) {
282             return extraRoutes.get().getExtraroute();
283         }
284         return new ArrayList<Extraroute>();
285     }
286
287     /**
288      * Retrieves all the VrfEntries that belong to a given VPN searching by its
289      * Route-Distinguisher
290      *
291      * @param broker dataBroker service reference
292      * @param rd     Route-distinguisher of the VPN
293      * @return the list of VrfEntries
294      */
295     public static List<VrfEntry> getAllVrfEntries(DataBroker broker, String rd) {
296         VrfTables vrfTables = VpnUtil.getVrfTable(broker, rd);
297         return (vrfTables != null) ? vrfTables.getVrfEntry() : new ArrayList<VrfEntry>();
298     }
299
300     //FIXME: Implement caches for DS reads
301     public static VpnInstance getVpnInstance(DataBroker broker, String vpnInstanceName) {
302         InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class).child(VpnInstance.class,
303                 new VpnInstanceKey(vpnInstanceName)).build();
304         Optional<VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
305         return (vpnInstance.isPresent()) ? vpnInstance.get() : null;
306     }
307
308     static List<VpnInstance> getAllVpnInstances(DataBroker broker) {
309         InstanceIdentifier<VpnInstances> id = InstanceIdentifier.builder(VpnInstances.class).build();
310         Optional<VpnInstances> optVpnInstances = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
311         if (optVpnInstances.isPresent()) {
312             return optVpnInstances.get().getVpnInstance();
313         } else {
314             return Collections.emptyList();
315         }
316     }
317
318     static List<VpnInstanceOpDataEntry> getAllVpnInstanceOpData(DataBroker broker) {
319         InstanceIdentifier<VpnInstanceOpData> id = InstanceIdentifier.builder(VpnInstanceOpData.class).build();
320         Optional<VpnInstanceOpData> vpnInstanceOpDataOptional = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, id);
321         if (vpnInstanceOpDataOptional.isPresent()) {
322             return vpnInstanceOpDataOptional.get().getVpnInstanceOpDataEntry();
323         } else {
324             return new ArrayList<VpnInstanceOpDataEntry>();
325         }
326     }
327
328     public static List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
329             .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> getDpnVpnInterfaces(DataBroker broker,
330                     VpnInstance vpnInstance, BigInteger dpnId) {
331         String rd = getRdFromVpnInstance(vpnInstance);
332         InstanceIdentifier<VpnToDpnList> dpnToVpnId = getVpnToDpnListIdentifier(rd, dpnId);
333         Optional<VpnToDpnList> dpnInVpn = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, dpnToVpnId);
334         return dpnInVpn.isPresent() ? dpnInVpn.get().getVpnInterfaces() : Collections.emptyList();
335     }
336
337     public static String getRdFromVpnInstance(VpnInstance vpnInstance) {
338         VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
339         LOG.trace("vpnConfig {}", vpnConfig);
340         String rd = vpnConfig.getRouteDistinguisher();
341         if (rd == null || rd.isEmpty()) {
342             rd = vpnInstance.getVpnInstanceName();
343             LOG.trace("rd is null or empty. Assigning VpnInstanceName to rd {}", rd);
344         }
345
346         return rd;
347     }
348
349     static VrfEntry getVrfEntry(DataBroker broker, String rd, String ipPrefix) {
350
351         VrfTables vrfTable = getVrfTable(broker, rd);
352         // TODO: why check VrfTables if we later go for the specific VrfEntry?
353         if (vrfTable != null) {
354             InstanceIdentifier<VrfEntry> vrfEntryId =
355                     InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).
356                             child(VrfEntry.class, new VrfEntryKey(ipPrefix)).build();
357             Optional<VrfEntry> vrfEntry = read(broker, LogicalDatastoreType.CONFIGURATION, vrfEntryId);
358             if (vrfEntry.isPresent()) {
359                 return vrfEntry.get();
360             }
361         }
362         return null;
363     }
364
365     static List<Adjacency> getAdjacenciesForVpnInterfaceFromConfig(DataBroker broker, String intfName) {
366         final InstanceIdentifier<VpnInterface> identifier = getVpnInterfaceIdentifier(intfName);
367         InstanceIdentifier<Adjacencies> path = identifier.augmentation(Adjacencies.class);
368         Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, path);
369
370         if (adjacencies.isPresent()) {
371             List<Adjacency> nextHops = adjacencies.get().getAdjacency();
372             return nextHops;
373         }
374         return null;
375     }
376
377     static Extraroute getVpnToExtraroute(String ipPrefix, List<String> nextHopList) {
378         return new ExtrarouteBuilder().setPrefix(ipPrefix).setNexthopIpList(nextHopList).build();
379     }
380
381     public static List<Extraroute> getVpnExtraroutes(DataBroker broker, String vpnRd) {
382         InstanceIdentifier<Vpn> vpnExtraRoutesId =
383                 InstanceIdentifier.builder(VpnToExtraroute.class).child(Vpn.class, new VpnKey(vpnRd)).build();
384         Optional<Vpn> vpnOpc = read(broker, LogicalDatastoreType.OPERATIONAL, vpnExtraRoutesId);
385         return vpnOpc.isPresent() ? vpnOpc.get().getExtraroute() : new ArrayList<Extraroute>();
386     }
387
388     static Adjacencies getVpnInterfaceAugmentation(List<Adjacency> nextHopList) {
389         return new AdjacenciesBuilder().setAdjacency(nextHopList).build();
390     }
391
392     public static InstanceIdentifier<IdPool> getPoolId(String poolName) {
393         InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
394                 InstanceIdentifier.builder(IdPools.class).child(IdPool.class, new IdPoolKey(poolName));
395         InstanceIdentifier<IdPool> id = idBuilder.build();
396         return id;
397     }
398
399     static InstanceIdentifier<VpnInterfaces> getVpnInterfacesIdentifier() {
400         return InstanceIdentifier.builder(VpnInterfaces.class).build();
401     }
402
403     static InstanceIdentifier<Interface> getInterfaceIdentifier(String interfaceName) {
404         return InstanceIdentifier.builder(Interfaces.class)
405                 .child(Interface.class, new InterfaceKey(interfaceName)).build();
406     }
407
408     static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
409         return InstanceIdentifier.builder(VpnInstanceOpData.class)
410                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
411                 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
412     }
413
414     public static BigInteger getCookieArpFlow(int interfaceTag) {
415         return VpnConstants.COOKIE_L3_BASE.add(new BigInteger("0110000", 16)).add(
416                 BigInteger.valueOf(interfaceTag));
417     }
418
419     public static BigInteger getCookieL3(int vpnId) {
420         return VpnConstants.COOKIE_L3_BASE.add(new BigInteger("0610000", 16)).add(BigInteger.valueOf(vpnId));
421     }
422
423     public static String getFlowRef(BigInteger dpnId, short tableId, int ethType, int lPortTag, int arpType) {
424         return new StringBuffer().append(VpnConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
425                 .append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(ethType).append(lPortTag)
426                 .append(NwConstants.FLOWID_SEPARATOR).append(arpType).toString();
427     }
428
429     public static int getUniqueId(IdManagerService idManager, String poolName, String idKey) {
430         AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
431
432         try {
433             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
434             RpcResult<AllocateIdOutput> rpcResult = result.get();
435             if (rpcResult.isSuccessful()) {
436                 return rpcResult.getResult().getIdValue().intValue();
437             } else {
438                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
439             }
440         } catch (InterruptedException | ExecutionException e) {
441             LOG.warn("Exception when getting Unique Id", e);
442         }
443         return 0;
444     }
445
446     public static void releaseId(IdManagerService idManager, String poolName, String idKey) {
447         ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
448         try {
449             Future<RpcResult<Void>> result = idManager.releaseId(idInput);
450             RpcResult<Void> rpcResult = result.get();
451             if (!rpcResult.isSuccessful()) {
452                 LOG.warn("RPC Call to Get Unique Id returned with Errors {}", rpcResult.getErrors());
453             }
454         } catch (InterruptedException | ExecutionException e) {
455             LOG.warn("Exception when getting Unique Id for key {}", idKey, e);
456         }
457     }
458
459     public static String getNextHopLabelKey(String rd, String prefix) {
460         return rd + VpnConstants.SEPARATOR + prefix;
461     }
462
463     /**
464      * Retrieves the VpnInstance name (typically the VPN Uuid) out from the
465      * route-distinguisher
466      *
467      * @param broker dataBroker service reference
468      * @param rd Route-Distinguisher
469      * @return the VpnInstance name
470      */
471     public static String getVpnNameFromRd(DataBroker broker, String rd) {
472         VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(broker, rd);
473         return (vpnInstanceOpData != null) ? vpnInstanceOpData.getVpnInstanceName() : null;
474     }
475
476     /**
477      * Retrieves the dataplane identifier of a specific VPN, searching by its
478      * VpnInstance name.
479      *
480      * @param broker dataBroker service reference
481      * @param vpnName Name of the VPN
482      * @return the dataplane identifier of the VPN, the VrfTag.
483      */
484     public static long getVpnId(DataBroker broker, String vpnName) {
485
486         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
487                 = getVpnInstanceToVpnIdIdentifier(vpnName);
488         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
489                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
490
491         long vpnId = VpnConstants.INVALID_ID;
492         if (vpnInstance.isPresent()) {
493             vpnId = vpnInstance.get().getVpnId();
494         }
495         return vpnId;
496     }
497
498     /**
499      * Retrieves the VPN Route Distinguisher searching by its Vpn instance name
500      *
501      * @param broker dataBroker service reference
502      * @param vpnName Name of the VPN
503      * @return the route-distinguisher of the VPN
504      */
505     public static String getVpnRd(DataBroker broker, String vpnName) {
506         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
507                 = getVpnInstanceToVpnIdIdentifier(vpnName);
508         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
509                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
510
511         String rd = null;
512         if (vpnInstance.isPresent()) {
513             rd = vpnInstance.get().getVrfId();
514         }
515         return rd;
516     }
517
518     /**
519      * Get VPN Route Distinguisher from VPN Instance Configuration
520      *
521      * @param broker dataBroker service reference
522      * @param vpnName Name of the VPN
523      * @return the route-distinguisher of the VPN
524      */
525     public static String getVpnRdFromVpnInstanceConfig(DataBroker broker, String vpnName) {
526         InstanceIdentifier<VpnInstance> id = InstanceIdentifier.builder(VpnInstances.class)
527                 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
528         Optional<VpnInstance> vpnInstance = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
529         String rd = null;
530         if (vpnInstance.isPresent()) {
531             VpnInstance instance = vpnInstance.get();
532             VpnAfConfig config = instance.getIpv4Family();
533             rd = config.getRouteDistinguisher();
534         }
535         return rd;
536     }
537
538     /**
539      * Remove from MDSAL all those VrfEntries in a VPN that have an specific RouteOrigin
540      *
541      * @param broker dataBroker service reference
542      * @param rd     Route Distinguisher
543      * @param origin Origin of the Routes to be removed (see {@link RouteOrigin})
544      */
545     public static void removeVrfEntriesByOrigin(DataBroker broker, String rd, RouteOrigin origin) {
546         InstanceIdentifier<VrfTables> vpnVrfTableIid =
547                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
548         Optional<VrfTables> vrfTablesOpc = read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid);
549         if (vrfTablesOpc.isPresent()) {
550             VrfTables vrfTables = vrfTablesOpc.get();
551             List<VrfEntry> newVrfEntries = new ArrayList<VrfEntry>();
552             for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) {
553                 if (origin == RouteOrigin.value(vrfEntry.getOrigin())) {
554                     delete(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid.child(VrfEntry.class,
555                             vrfEntry.getKey()));
556                 }
557             }
558         }
559     }
560
561     public static List<VrfEntry> findVrfEntriesByNexthop(DataBroker broker, String rd, String nexthop) {
562         InstanceIdentifier<VrfTables> vpnVrfTableIid =
563                 InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
564         Optional<VrfTables> vrfTablesOpc = read(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid);
565         List<VrfEntry> matches = new ArrayList<VrfEntry>();
566
567         if (vrfTablesOpc.isPresent()) {
568             VrfTables vrfTables = vrfTablesOpc.get();
569             for (VrfEntry vrfEntry : vrfTables.getVrfEntry()) {
570                 if (vrfEntry.getNextHopAddressList() != null && vrfEntry.getNextHopAddressList().contains(nexthop)) {
571                     matches.add(vrfEntry);
572                 }
573             }
574         }
575         return matches;
576     }
577
578     public static void removeVrfEntries(DataBroker broker, String rd, List<VrfEntry> vrfEntries) {
579         InstanceIdentifier<VrfTables> vpnVrfTableIid =
580             InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)).build();
581         for (VrfEntry vrfEntry : vrfEntries) {
582             delete(broker, LogicalDatastoreType.CONFIGURATION, vpnVrfTableIid.child(VrfEntry.class,
583                                                                                     vrfEntry.getKey()));
584         }
585     }
586
587     static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
588                 getVpnInstanceToVpnId(String vpnName, long vpnId, String rd) {
589
590         return new VpnInstanceBuilder().setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).build();
591
592     }
593
594     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
595                 getVpnInstanceToVpnIdIdentifier(String vpnName) {
596         return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
597                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
598                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
599     }
600
601     static RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
602         Optional<RouterInterface> optRouterInterface = read(broker, LogicalDatastoreType.CONFIGURATION, VpnUtil.getRouterInterfaceId(interfaceName));
603         if(optRouterInterface.isPresent()) {
604             return optRouterInterface.get();
605         }
606         return null;
607     }
608
609     static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds
610                 getVpnIdToVpnInstance(long vpnId, String vpnName, String rd, boolean isExternalVpn) {
611         return new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsBuilder()
612                 .setVpnId(vpnId).setVpnInstanceName(vpnName).setVrfId(rd).setExternalVpn(isExternalVpn).build();
613
614     }
615
616     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds>
617         getVpnIdToVpnInstanceIdentifier(long vpnId) {
618         return InstanceIdentifier.builder(VpnIdToVpnInstance.class)
619                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds.class,
620                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey(Long.valueOf(vpnId))).build();
621     }
622
623     /**
624      * Retrieves the Vpn Name searching by its VPN Tag.
625      *
626      * @param broker dataBroker service reference
627      * @param vpnId Dataplane identifier of the VPN
628      * @return the Vpn instance name
629      */
630     public static String getVpnName(DataBroker broker, long vpnId) {
631
632         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds> id
633                 = getVpnIdToVpnInstanceIdentifier(vpnId);
634         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds> vpnInstance
635                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
636
637         String vpnName = null;
638         if (vpnInstance.isPresent()) {
639             vpnName = vpnInstance.get().getVpnInstanceName();
640         }
641         return vpnName;
642     }
643
644     public static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String rd) {
645         return InstanceIdentifier.builder(VpnInstanceOpData.class)
646                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd)).build();
647     }
648
649     static InstanceIdentifier<RouterInterface> getRouterInterfaceId(String interfaceName) {
650         return InstanceIdentifier.builder(RouterInterfaces.class)
651                 .child(RouterInterface.class, new RouterInterfaceKey(interfaceName)).build();
652     }
653
654     static RouterInterface getRouterInterface(String interfaceName, String routerName) {
655         return new RouterInterfaceBuilder().setKey(new RouterInterfaceKey(interfaceName))
656                 .setInterfaceName(interfaceName).setRouterName(routerName).build();
657     }
658
659     public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
660         InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
661         return read(broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
662     }
663
664     static VpnInstanceOpDataEntry getVpnInstanceOpDataFromCache(DataBroker broker, String rd) {
665         InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
666         return (VpnInstanceOpDataEntry) DataStoreCache.get(VpnConstants.VPN_OP_INSTANCE_CACHE_NAME, id, rd, broker, false);
667     }
668
669     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
670         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
671         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
672
673         if (configuredVpnInterface.isPresent()) {
674             return configuredVpnInterface.get();
675         }
676         return null;
677     }
678
679     static String getNeutronRouterFromInterface(DataBroker broker, String interfaceName) {
680         InstanceIdentifier.InstanceIdentifierBuilder<RouterInterfacesMap> idBuilder =
681                             InstanceIdentifier.builder(RouterInterfacesMap.class);
682         InstanceIdentifier<RouterInterfacesMap> id = idBuilder.build();
683         Optional<RouterInterfacesMap> RouterInterfacesMap = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
684         if (RouterInterfacesMap.isPresent()) {
685               List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces> rtrInterfaces = RouterInterfacesMap.get().getRouterInterfaces();
686               for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.RouterInterfaces rtrInterface : rtrInterfaces) {
687                   List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces> rtrIfc = rtrInterface.getInterfaces();
688                   for(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces ifc : rtrIfc) {
689                       if (ifc.getInterfaceId().equals(interfaceName)) {
690                           return rtrInterface.getRouterId().getValue();
691                       }
692                   }
693               }
694         }
695         return null;
696     }
697
698     static VpnInterface getOperationalVpnInterface(DataBroker broker, String interfaceName) {
699         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
700         Optional<VpnInterface> operationalVpnInterface = read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId);
701
702         if (operationalVpnInterface.isPresent()) {
703             return operationalVpnInterface.get();
704         }
705         return null;
706     }
707
708     static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
709         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
710         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
711
712         if (configuredVpnInterface.isPresent()) {
713             return true;
714         }
715         return false;
716     }
717
718     static boolean isInterfaceAssociatedWithVpn(DataBroker broker, String vpnName, String interfaceName) {
719         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
720         Optional<VpnInterface> optConfiguredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
721
722         if (optConfiguredVpnInterface.isPresent()) {
723             String configuredVpnName = optConfiguredVpnInterface.get().getVpnInstanceName();
724             if ((configuredVpnName != null) && (configuredVpnName.equalsIgnoreCase(vpnName))) {
725                 return true;
726             }
727         }
728         return false;
729     }
730
731     static String getIpPrefix(String prefix) {
732         String prefixValues[] = prefix.split("/");
733         if (prefixValues.length == 1) {
734             prefix = prefix + PREFIX_SEPARATOR + DEFAULT_PREFIX_LENGTH;
735         }
736         return prefix;
737     }
738
739     static final FutureCallback<Void> DEFAULT_CALLBACK =
740             new FutureCallback<Void>() {
741                 @Override
742                 public void onSuccess(Void result) {
743                     LOG.debug("Success in Datastore operation");
744                 }
745
746                 @Override
747                 public void onFailure(Throwable error) {
748                     LOG.error("Error in Datastore operation", error);
749                 }
750
751                 ;
752             };
753
754     public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
755                                                           InstanceIdentifier<T> path) {
756
757         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
758
759         Optional<T> result = Optional.absent();
760         try {
761             result = tx.read(datastoreType, path).get();
762         } catch (Exception e) {
763             throw new RuntimeException(e);
764         } finally {
765             tx.close();
766         }
767
768         return result;
769     }
770
771     public static <T extends DataObject> void asyncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
772                                                           InstanceIdentifier<T> path, T data) {
773         asyncUpdate(broker, datastoreType, path, data, DEFAULT_CALLBACK);
774     }
775
776     public static <T extends DataObject> void asyncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
777                                                           InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
778         WriteTransaction tx = broker.newWriteOnlyTransaction();
779         tx.merge(datastoreType, path, data, true);
780         Futures.addCallback(tx.submit(), callback);
781     }
782
783     public static <T extends DataObject> void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
784                                                          InstanceIdentifier<T> path, T data) {
785         asyncWrite(broker, datastoreType, path, data, DEFAULT_CALLBACK);
786     }
787
788     public static <T extends DataObject> void asyncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
789                                                          InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
790         WriteTransaction tx = broker.newWriteOnlyTransaction();
791         tx.put(datastoreType, path, data, true);
792         Futures.addCallback(tx.submit(), callback);
793     }
794
795     public static <T extends DataObject> void tryDelete(DataBroker broker, LogicalDatastoreType datastoreType,
796                                                      InstanceIdentifier<T> path) {
797         try {
798             delete(broker, datastoreType, path, DEFAULT_CALLBACK);
799         } catch ( SchemaValidationFailedException sve ) {
800             LOG.info("Could not delete {}. SchemaValidationFailedException: {}", path, sve.getMessage());
801         } catch ( Exception e) {
802             LOG.info("Could not delete {}. Unhandled error: {}", path, e.getMessage());
803         }
804     }
805
806     public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
807                                                      InstanceIdentifier<T> path) {
808         delete(broker, datastoreType, path, DEFAULT_CALLBACK);
809     }
810
811
812     public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
813                                                      InstanceIdentifier<T> path, FutureCallback<Void> callback) {
814         WriteTransaction tx = broker.newWriteOnlyTransaction();
815         tx.delete(datastoreType, path);
816         Futures.addCallback(tx.submit(), callback);
817     }
818
819     public static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
820                                                         InstanceIdentifier<T> path, T data) {
821         WriteTransaction tx = broker.newWriteOnlyTransaction();
822         tx.put(datastoreType, path, data, true);
823         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
824         try {
825             futures.get();
826         } catch (InterruptedException | ExecutionException e) {
827             LOG.error("Error writing to datastore (path, data) : ({}, {})", path, data);
828             throw new RuntimeException(e.getMessage());
829         }
830     }
831
832     public static <T extends DataObject> void syncUpdate(DataBroker broker, LogicalDatastoreType datastoreType,
833                                                          InstanceIdentifier<T> path, T data) {
834         WriteTransaction tx = broker.newWriteOnlyTransaction();
835         tx.merge(datastoreType, path, data, true);
836         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
837         try {
838             futures.get();
839         } catch (InterruptedException | ExecutionException e) {
840             LOG.error("Error writing to datastore (path, data) : ({}, {})", path, data);
841             throw new RuntimeException(e.getMessage());
842         }
843     }
844
845     public static long getRemoteBCGroup(long elanTag) {
846         return VpnConstants.ELAN_GID_MIN + ((elanTag % VpnConstants.ELAN_GID_MIN) * 2);
847     }
848
849     // interface-index-tag operational container
850     public static IfIndexInterface getInterfaceInfoByInterfaceTag(DataBroker broker, long interfaceTag) {
851         InstanceIdentifier<IfIndexInterface> interfaceId = getInterfaceInfoEntriesOperationalDataPath(interfaceTag);
852         Optional<IfIndexInterface> existingInterfaceInfo = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, interfaceId);
853         if (existingInterfaceInfo.isPresent()) {
854             return existingInterfaceInfo.get();
855         }
856         return null;
857     }
858
859     private static InstanceIdentifier<IfIndexInterface> getInterfaceInfoEntriesOperationalDataPath(long interfaceTag) {
860         return InstanceIdentifier.builder(IfIndexesInterfaceMap.class).child(IfIndexInterface.class,
861                 new IfIndexInterfaceKey((int) interfaceTag)).build();
862     }
863
864     public static ElanTagName getElanInfoByElanTag(DataBroker broker, long elanTag) {
865         InstanceIdentifier<ElanTagName> elanId = getElanInfoEntriesOperationalDataPath(elanTag);
866         Optional<ElanTagName> existingElanInfo = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, elanId);
867         if (existingElanInfo.isPresent()) {
868             return existingElanInfo.get();
869         }
870         return null;
871     }
872
873     private static InstanceIdentifier<ElanTagName> getElanInfoEntriesOperationalDataPath(long elanTag) {
874         return InstanceIdentifier.builder(ElanTagNameMap.class).child(ElanTagName.class,
875                 new ElanTagNameKey(elanTag)).build();
876     }
877
878
879     // TODO: Move this to NwUtil
880     public static boolean isIpInSubnet(int ipAddress, String subnetCidr) {
881         String[] subSplit = subnetCidr.split("/");
882         if (subSplit.length < 2) {
883             return false;
884         }
885
886         String subnetStr = subSplit[0];
887         int subnet = 0;
888         try {
889             InetAddress subnetAddress = InetAddress.getByName(subnetStr);
890             subnet = Ints.fromByteArray(subnetAddress.getAddress());
891         } catch (Exception ex) {
892             LOG.error("Passed in Subnet IP string not convertible to InetAdddress " + subnetStr);
893             return false;
894         }
895         int prefixLength = Integer.valueOf(subSplit[1]);
896         int mask = -1 << (32 - prefixLength);
897         if ((subnet & mask) == (ipAddress & mask)) {
898             return true;
899         }
900         return false;
901     }
902
903     /**
904      * Returns the Path identifier to reach a specific interface in a specific DPN in a given VpnInstance
905      *
906      * @param vpnRd     Route-Distinguisher of the VpnInstance
907      * @param dpnId     Id of the DPN where the interface is
908      * @param ifaceName Interface name
909      * @return the Instance Identifier
910      */
911     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
912             .instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces>
913     getVpnToDpnInterfacePath(String vpnRd, BigInteger dpnId, String ifaceName) {
914
915         return
916                 InstanceIdentifier.builder(VpnInstanceOpData.class)
917                         .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vpnRd))
918                         .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId))
919                         .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
920                                 .instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class,
921                                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
922                                         .instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey(ifaceName))
923                         .build();
924     }
925
926     public static void removePrefixToInterfaceForVpnId(DataBroker broker, long vpnId, WriteTransaction writeTxn) {
927         try {
928             // Clean up PrefixToInterface Operational DS
929             if (writeTxn != null) {
930                 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
931                         InstanceIdentifier.builder(PrefixToInterface.class).child(
932                                 VpnIds.class, new VpnIdsKey(vpnId)).build());
933             } else {
934                 delete(broker, LogicalDatastoreType.OPERATIONAL,
935                         InstanceIdentifier.builder(PrefixToInterface.class).child(VpnIds.class, new VpnIdsKey(vpnId)).build(),
936                         DEFAULT_CALLBACK);
937             }
938         } catch (Exception e) {
939             LOG.error("Exception during cleanup of PrefixToInterface for VPN ID {}", vpnId, e);
940         }
941     }
942
943     public static void removeVpnExtraRouteForVpn(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
944         try {
945             // Clean up VPNExtraRoutes Operational DS
946             if (writeTxn != null) {
947                 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
948                         InstanceIdentifier.builder(VpnToExtraroute.class).child(Vpn.class, new VpnKey(vpnName)).build());
949             } else {
950                 delete(broker, LogicalDatastoreType.OPERATIONAL,
951                         InstanceIdentifier.builder(VpnToExtraroute.class).child(Vpn.class, new VpnKey(vpnName)).build(),
952                         DEFAULT_CALLBACK);
953             }
954         } catch (Exception e) {
955             LOG.error("Exception during cleanup of VPNToExtraRoute for VPN {}", vpnName, e);
956         }
957     }
958
959     public static void removeVpnOpInstance(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
960         try {
961             // Clean up VPNInstanceOpDataEntry
962             if (writeTxn != null) {
963                 writeTxn.delete(LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName));
964             } else {
965                 delete(broker, LogicalDatastoreType.OPERATIONAL, getVpnInstanceOpDataIdentifier(vpnName),
966                         DEFAULT_CALLBACK);
967             }
968         } catch (Exception e) {
969             LOG.error("Exception during cleanup of VPNInstanceOpDataEntry for VPN {}", vpnName, e);
970         }
971     }
972
973     public static void removeVpnInstanceToVpnId(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
974         try {
975             if (writeTxn != null) {
976                 writeTxn.delete(LogicalDatastoreType.CONFIGURATION, getVpnInstanceToVpnIdIdentifier(vpnName));
977             } else {
978                 delete(broker, LogicalDatastoreType.CONFIGURATION, getVpnInstanceToVpnIdIdentifier(vpnName),
979                         DEFAULT_CALLBACK);
980             }
981         } catch (Exception e) {
982             LOG.error("Exception during clean up of VpnInstanceToVpnId for VPN {}", vpnName, e);
983         }
984     }
985
986     public static void removeVpnIdToVpnInstance(DataBroker broker, long vpnId, WriteTransaction writeTxn) {
987         try {
988             if (writeTxn != null) {
989                 writeTxn.delete(LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId));
990             } else {
991                 delete(broker, LogicalDatastoreType.CONFIGURATION, getVpnIdToVpnInstanceIdentifier(vpnId),
992                         DEFAULT_CALLBACK);
993             }
994         } catch (Exception e) {
995             LOG.error("Exception during clean up of VpnIdToVpnInstance for VPNID {}", vpnId, e);
996         }
997     }
998
999     public static void removeVrfTableForVpn(DataBroker broker, String vpnName, WriteTransaction writeTxn) {
1000         // Clean up FIB Entries Config DS
1001         try {
1002             if (writeTxn != null) {
1003                 writeTxn.delete(LogicalDatastoreType.CONFIGURATION,
1004                         InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(vpnName)).build());
1005             } else {
1006                 delete(broker, LogicalDatastoreType.CONFIGURATION,
1007                         InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(vpnName)).build(),
1008                         DEFAULT_CALLBACK);
1009             }
1010         } catch (Exception e) {
1011             LOG.error("Exception during clean up of VrfTable from FIB for VPN {}", vpnName, e);
1012         }
1013     }
1014
1015     public static void removeL3nexthopForVpnId(DataBroker broker, long vpnId, WriteTransaction writeTxn) {
1016         try {
1017             // Clean up L3NextHop Operational DS
1018             if (writeTxn != null) {
1019                 writeTxn.delete(LogicalDatastoreType.OPERATIONAL,
1020                         InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, new VpnNexthopsKey(vpnId)).build());
1021             } else {
1022                 delete(broker, LogicalDatastoreType.OPERATIONAL,
1023                         InstanceIdentifier.builder(L3nexthop.class).child(VpnNexthops.class, new VpnNexthopsKey(vpnId)).build(),
1024                         DEFAULT_CALLBACK);
1025             }
1026         } catch (Exception e) {
1027             LOG.error("Exception during cleanup of L3NextHop for VPN ID {}", vpnId, e);
1028         }
1029     }
1030
1031     public static void scheduleVpnInterfaceForRemoval(DataBroker broker,String interfaceName, BigInteger dpnId,
1032                                                       String vpnInstanceName, Boolean isScheduledToRemove,
1033                                                       WriteTransaction writeOperTxn){
1034         InstanceIdentifier<VpnInterface> interfaceId = VpnUtil.getVpnInterfaceIdentifier(interfaceName);
1035         VpnInterface interfaceToUpdate = new VpnInterfaceBuilder().setKey(new VpnInterfaceKey(interfaceName)).setName(interfaceName)
1036                 .setDpnId(dpnId).setVpnInstanceName(vpnInstanceName).setScheduledForRemove(isScheduledToRemove).build();
1037         if (writeOperTxn != null) {
1038             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate, true);
1039         } else {
1040             VpnUtil.syncUpdate(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, interfaceToUpdate);
1041         }
1042     }
1043
1044     public static boolean isNeutronPortConfigured(DataBroker broker, String portId,
1045                                                   org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress targetIP) {
1046         InstanceIdentifier<Port> portIdentifier = InstanceIdentifier.create(Neutron.class).
1047                 child(Ports.class).child(Port.class, new PortKey(new Uuid(portId)));
1048         Optional<Port> optPort = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, portIdentifier);
1049         if (optPort.isPresent()) {
1050             Port port = optPort.get();
1051             for (FixedIps ip : port.getFixedIps()) {
1052                 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1053                     return true;
1054                 }
1055             }
1056         }
1057
1058         LOG.trace("No neutron ports found matching portId {} with targetIp {}", portId, targetIP);
1059         return false;
1060     }
1061
1062     protected static void createVpnPortFixedIpToPort(DataBroker broker, String vpnName, String fixedIp, String
1063             portName, String macAddress, boolean isSubnetIp, boolean isConfig, boolean isLearnt) {
1064         synchronized ((vpnName + fixedIp).intern()) {
1065             InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
1066             VpnPortipToPortBuilder builder = new VpnPortipToPortBuilder().setKey(
1067                     new VpnPortipToPortKey(fixedIp, vpnName)).setVpnName(vpnName).setPortFixedip(fixedIp).setPortName
1068                     (portName).setMacAddress(macAddress.toLowerCase()).setSubnetIp(isSubnetIp).setConfig(isConfig)
1069                     .setLearnt(isLearnt);
1070             MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, id, builder.build());
1071             LOG.debug("ARP learned for fixedIp: {}, vpn {}, interface {}, mac {}, isSubnetIp {} added to " +
1072                     "VpnPortipToPort DS", fixedIp, vpnName, portName, macAddress, isLearnt);
1073         }
1074     }
1075
1076     protected static void removeVpnPortFixedIpToPort(DataBroker broker, String vpnName, String fixedIp) {
1077         synchronized ((vpnName + fixedIp).intern()) {
1078             InstanceIdentifier<VpnPortipToPort> id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
1079             MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
1080             LOG.debug("Delete learned ARP for fixedIp: {}, vpn {} removed from VpnPortipToPort DS", fixedIp, vpnName);
1081         }
1082     }
1083
1084     static InstanceIdentifier<VpnPortipToPort> buildVpnPortipToPortIdentifier(String vpnName, String fixedIp) {
1085         InstanceIdentifier<VpnPortipToPort> id = InstanceIdentifier.builder(NeutronVpnPortipPortData.class).child
1086                 (VpnPortipToPort.class, new VpnPortipToPortKey(fixedIp, vpnName)).build();
1087         return id;
1088     }
1089
1090     static VpnPortipToPort getNeutronPortFromVpnPortFixedIp(DataBroker broker, String vpnName, String fixedIp) {
1091         InstanceIdentifier id = buildVpnPortipToPortIdentifier(vpnName, fixedIp);
1092         Optional<VpnPortipToPort> vpnPortipToPortData = read(broker, LogicalDatastoreType.OPERATIONAL, id);
1093         if (vpnPortipToPortData.isPresent()) {
1094             return (vpnPortipToPortData.get());
1095         }
1096         return null;
1097     }
1098
1099     public static List<BigInteger> getDpnsOnVpn(DataBroker dataBroker, String vpnInstanceName) {
1100         List<BigInteger> result = new ArrayList<BigInteger>();
1101         String rd = getVpnRd(dataBroker, vpnInstanceName);
1102         if ( rd == null ) {
1103             LOG.debug("Could not find Route-Distinguisher for VpnName={}", vpnInstanceName);
1104             return result;
1105         }
1106
1107         VpnInstanceOpDataEntry vpnInstanceOpData = getVpnInstanceOpData(dataBroker, rd);
1108         if ( vpnInstanceOpData == null ) {
1109             LOG.debug("Could not find OpState for VpnName={}", vpnInstanceName);
1110             return result;
1111         }
1112
1113         List<VpnToDpnList> vpnToDpnList = vpnInstanceOpData.getVpnToDpnList();
1114         if ( vpnToDpnList == null ) {
1115             LOG.debug("Could not find DPN footprint for VpnName={}", vpnInstanceName);
1116             return result;
1117         }
1118         for ( VpnToDpnList vpnToDpn : vpnToDpnList) {
1119             result.add(vpnToDpn.getDpnId());
1120         }
1121         return result;
1122     }
1123
1124     static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
1125         InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
1126         Optional<Routers> routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1127         if (routerData.isPresent()) {
1128             Uuid networkId = routerData.get().getNetworkId();
1129             if(networkId != null) {
1130                 return networkId.getValue();
1131             }
1132         }
1133         return null;
1134     }
1135
1136     static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
1137         InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class).child
1138                 (Routers.class, new RoutersKey(routerId)).build();
1139         return routerInstanceIndentifier;
1140     }
1141
1142     static Networks getExternalNetwork(DataBroker dataBroker, Uuid networkId) {
1143         InstanceIdentifier<Networks> netsIdentifier = InstanceIdentifier.builder(ExternalNetworks.class)
1144                 .child(Networks.class, new NetworksKey(networkId)).build();
1145         Optional<Networks> optionalNets = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, netsIdentifier);
1146         return optionalNets.isPresent() ? optionalNets.get() : null;
1147     }
1148
1149     static Uuid getExternalNetworkVpnId(DataBroker dataBroker, Uuid networkId) {
1150         Networks extNetwork = getExternalNetwork(dataBroker, networkId);
1151         return extNetwork != null ? extNetwork.getVpnid() : null;
1152     }
1153
1154     static List<Uuid> getExternalNetworkRouterIds(DataBroker dataBroker, Uuid networkId) {
1155         Networks extNetwork = getExternalNetwork(dataBroker, networkId);
1156         return extNetwork != null ? extNetwork.getRouterIds() : null;
1157     }
1158
1159     static Routers getExternalRouter(DataBroker dataBroker, String routerId) {
1160         InstanceIdentifier<Routers> id = InstanceIdentifier.builder(ExtRouters.class)
1161                 .child(Routers.class, new RoutersKey(routerId)).build();
1162         Optional<Routers> routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1163         return routerData.isPresent() ? routerData.get() : null;
1164     }
1165
1166     static Optional<List<String>> getAllSubnetGatewayMacAddressesforVpn(DataBroker broker, String vpnName) {
1167         Optional<List<String>> macAddressesOptional = Optional.absent();
1168         List<String> macAddresses = new ArrayList<>();
1169         Optional<Subnetmaps> subnetMapsData = read(broker, LogicalDatastoreType.CONFIGURATION, buildSubnetMapsWildCardPath());
1170         if (subnetMapsData.isPresent()) {
1171             List<Subnetmap> subnetMapList = subnetMapsData.get().getSubnetmap();
1172             if (subnetMapList != null && !subnetMapList.isEmpty()) {
1173                 for (Subnetmap subnet: subnetMapList) {
1174                     if (subnet.getVpnId() !=null && subnet.getVpnId().equals(Uuid.getDefaultInstance(vpnName))) {
1175                         String routerIntfMacAddress = subnet.getRouterIntfMacAddress();
1176                         if (routerIntfMacAddress != null && !routerIntfMacAddress.isEmpty()) {
1177                             macAddresses.add(subnet.getRouterIntfMacAddress());
1178                         }
1179                     }
1180                 }
1181             }
1182             if (!macAddresses.isEmpty()) {
1183                 return Optional.of(macAddresses);
1184             }
1185         }
1186         return macAddressesOptional;
1187     }
1188
1189     static InstanceIdentifier<Subnetmaps> buildSubnetMapsWildCardPath() {
1190         return InstanceIdentifier.create(Subnetmaps.class);
1191     }
1192
1193     static void setupSubnetMacIntoVpnInstance(DataBroker dataBroker, IMdsalApiManager mdsalManager,
1194             String vpnName, String srcMacAddress, BigInteger dpnId, WriteTransaction writeTx, int addOrRemove) {
1195         long vpnId = getVpnId(dataBroker, vpnName);
1196         if (dpnId.equals(BigInteger.ZERO)) {
1197             /* Apply the MAC on all DPNs in a VPN */
1198             List<BigInteger> dpIds = getDpnsOnVpn(dataBroker, vpnName);
1199             if (dpIds == null || dpIds.isEmpty()) {
1200                 return;
1201             }
1202             for (BigInteger dpId : dpIds) {
1203                 addGwMacIntoTx(mdsalManager, srcMacAddress, writeTx, addOrRemove, vpnId, dpId);
1204             }
1205         } else {
1206             addGwMacIntoTx(mdsalManager, srcMacAddress, writeTx, addOrRemove, vpnId, dpnId);
1207         }
1208     }
1209
1210     static void addGwMacIntoTx(IMdsalApiManager mdsalManager, String srcMacAddress, WriteTransaction writeTx,
1211             int addOrRemove, long vpnId, BigInteger dpId) {
1212         FlowEntity flowEntity = buildL3vpnGatewayFlow(dpId, srcMacAddress, vpnId);
1213         if (addOrRemove == NwConstants.ADD_FLOW) {
1214             mdsalManager.addFlowToTx(flowEntity, writeTx);
1215         } else {
1216             mdsalManager.removeFlowToTx(flowEntity, writeTx);
1217         }
1218     }
1219
1220     public static FlowEntity buildL3vpnGatewayFlow(BigInteger dpId, String gwMacAddress, long vpnId) {
1221         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
1222         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
1223                 MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID }));
1224         mkMatches.add(new MatchInfo(MatchFieldType.eth_dst, new String[] { gwMacAddress }));
1225         List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
1226         mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.L3_FIB_TABLE }));
1227         String flowId = getL3VpnGatewayFlowRef(NwConstants.L3_GW_MAC_TABLE, dpId, vpnId, gwMacAddress);
1228         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_GW_MAC_TABLE,
1229                 flowId, 20, flowId, 0, 0, NwConstants.COOKIE_L3_GW_MAC_TABLE, mkMatches, mkInstructions);
1230         return flowEntity;
1231     }
1232
1233     private static String getL3VpnGatewayFlowRef(short l3GwMacTable, BigInteger dpId, long vpnId, String gwMacAddress) {
1234         return gwMacAddress+NwConstants.FLOWID_SEPARATOR+vpnId+NwConstants.FLOWID_SEPARATOR+dpId+NwConstants.FLOWID_SEPARATOR+l3GwMacTable;
1235     }
1236
1237     public static void lockSubnet(LockManagerService lockManager, String subnetId) {
1238         TryLockInput input = new TryLockInputBuilder().setLockName(subnetId).setTime(3000L).setTimeUnit(TimeUnits.Milliseconds).build();
1239         Future<RpcResult<Void>> result = lockManager.tryLock(input);
1240         String errMsg = "Unable to getLock for subnet " + subnetId;
1241         try {
1242             if ((result != null) && (result.get().isSuccessful())) {
1243                     LOG.debug("Acquired lock for {}", subnetId);
1244             } else {
1245                 throw new RuntimeException(errMsg);
1246             }
1247         } catch (InterruptedException | ExecutionException e) {
1248             LOG.error(errMsg);
1249             throw new RuntimeException(errMsg, e.getCause());
1250         }
1251     }
1252
1253     public static void unlockSubnet(LockManagerService lockManager, String subnetId) {
1254         UnlockInput input = new UnlockInputBuilder().setLockName(subnetId).build();
1255         Future<RpcResult<Void>> result = lockManager.unlock(input);
1256         try {
1257             if ((result != null) && (result.get().isSuccessful())) {
1258                 LOG.debug("Unlocked {}", subnetId);
1259             } else {
1260                 LOG.debug("Unable to unlock subnet {}", subnetId);
1261             }
1262         } catch (InterruptedException | ExecutionException e) {
1263             LOG.error("Unable to unlock subnet {}", subnetId);
1264             throw new RuntimeException(String.format("Unable to unlock subnetId %s", subnetId), e.getCause());
1265         }
1266     }
1267
1268     static Optional<IpAddress> getGatewayIpAddressFromInterface(String srcInterface,
1269             INeutronVpnManager neutronVpnService, DataBroker dataBroker) {
1270         Optional <IpAddress> gatewayIp = Optional.absent();
1271         if (neutronVpnService != null) {
1272             //TODO(Gobinath): Need to fix this as assuming port will belong to only one Subnet would be incorrect"
1273             Port port = neutronVpnService.getNeutronPort(srcInterface);
1274             if (port != null && port.getFixedIps() != null && port.getFixedIps().get(0) != null && port.getFixedIps().get(0).getSubnetId() != null) {
1275                 gatewayIp = Optional.of(neutronVpnService.getNeutronSubnet(port.getFixedIps().get(0).getSubnetId()).getGatewayIp());
1276             }
1277         } else {
1278             LOG.debug("neutron vpn service is not configured");
1279         }
1280         return gatewayIp;
1281     }
1282
1283     static Optional<String> getGWMacAddressFromInterface(MacEntry macEntry, IpAddress gatewayIp,
1284             DataBroker dataBroker, OdlInterfaceRpcService interfaceRpc) {
1285         Optional <String> gatewayMac = Optional.absent();
1286         long vpnId = getVpnId(dataBroker, macEntry.getVpnName());
1287         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds>
1288         vpnIdsInstanceIdentifier = VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId);
1289         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds> vpnIdsOptional
1290         = VpnUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
1291         if (!vpnIdsOptional.isPresent()) {
1292             LOG.trace("VPN {} not configured", vpnId);
1293             return gatewayMac;
1294         }
1295         VpnPortipToPort vpnTargetIpToPort = VpnUtil.getNeutronPortFromVpnPortFixedIp(dataBroker,
1296                 macEntry.getVpnName(), gatewayIp.getIpv4Address().getValue());
1297         if (vpnTargetIpToPort != null && vpnTargetIpToPort.isSubnetIp()) {
1298             gatewayMac = Optional.of(vpnTargetIpToPort.getMacAddress());
1299         } else {
1300             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds vpnIds = vpnIdsOptional.get();
1301             if(vpnIds.isExternalVpn()) {
1302                 gatewayMac = InterfaceUtils.getMacAddressForInterface(dataBroker, macEntry.getInterfaceName());
1303             }
1304         }
1305         return gatewayMac;
1306
1307     }
1308
1309     public static boolean isVpnIntfPresentInVpnToDpnList(DataBroker broker, VpnInterface vpnInterface) {
1310         BigInteger dpnId = vpnInterface.getDpnId();
1311         String rd = VpnUtil.getVpnRd(broker, vpnInterface.getVpnInstanceName());
1312         VpnInstanceOpDataEntry vpnInstanceOpData = VpnUtil.getVpnInstanceOpDataFromCache(broker, rd);
1313         if (vpnInstanceOpData != null) {
1314             List<VpnToDpnList> dpnToVpns = vpnInstanceOpData.getVpnToDpnList();
1315             if (dpnToVpns!= null) {
1316                 for (VpnToDpnList dpn :dpnToVpns) {
1317                     if (dpn.getDpnId().equals(dpnId)) {
1318                         if (dpn.getVpnInterfaces().contains(vpnInterface.getName())) {
1319                             return true;
1320                         } else {
1321                             return false;
1322                         }
1323                     }
1324                 }
1325             }
1326         }
1327         return false;
1328     }
1329
1330     public static void setupGwMacIfExternalVpn(DataBroker dataBroker, IMdsalApiManager mdsalManager, BigInteger dpnId, String interfaceName, long vpnId,
1331             WriteTransaction writeInvTxn, int addOrRemove) {
1332         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds> vpnIdsInstanceIdentifier =
1333                 getVpnIdToVpnInstanceIdentifier(vpnId);
1334         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds> vpnIdsOptional = read(dataBroker,
1335                 LogicalDatastoreType.CONFIGURATION, vpnIdsInstanceIdentifier);
1336         if (vpnIdsOptional.isPresent() && vpnIdsOptional.get().isExternalVpn()) {
1337             Optional<String> gwMacAddressOptional = InterfaceUtils.getMacAddressForInterface(dataBroker, interfaceName);
1338             if (!gwMacAddressOptional.isPresent()) {
1339                 LOG.error("Failed to get gwMacAddress for interface {}", interfaceName);
1340                 return;
1341             }
1342             String gwMacAddress = gwMacAddressOptional.get();
1343             FlowEntity flowEntity = VpnUtil.buildL3vpnGatewayFlow(dpnId, gwMacAddress, vpnId);
1344             if (addOrRemove == NwConstants.ADD_FLOW) {
1345                 mdsalManager.addFlowToTx(flowEntity, writeInvTxn);
1346             } else if (addOrRemove == NwConstants.DEL_FLOW) {
1347                 mdsalManager.removeFlowToTx(flowEntity, writeInvTxn);
1348             }
1349         }
1350     }
1351
1352     public static Optional<VpnPortipToPort> getRouterInterfaceForVpnInterface(INeutronVpnManager neutronVpnService,
1353             DataBroker dataBroker, String interfaceName, String vpnName) {
1354         final Optional<String> gatewayIp = getVpnSubnetGatewayIp(dataBroker, neutronVpnService.getNeutronSubnet(
1355                 neutronVpnService.getNeutronPort(interfaceName)
1356                 .getFixedIps().get(0).getSubnetId()).getUuid());
1357         Optional<VpnPortipToPort> gwPortOptional = Optional.absent();
1358         if (gatewayIp.isPresent()) {
1359             String gwIp = gatewayIp.get();
1360             gwPortOptional = Optional.fromNullable(getNeutronPortFromVpnPortFixedIp(dataBroker, vpnName, gwIp));
1361         }
1362         return gwPortOptional;
1363     }
1364
1365     public static Optional<String> getVpnSubnetGatewayIp(DataBroker dataBroker, final Uuid subnetUuid) {
1366         Optional<String> gwIpAddress = Optional.absent();
1367         final SubnetKey subnetkey = new SubnetKey(subnetUuid);
1368         final InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class)
1369                 .child(Subnets.class)
1370                 .child(Subnet.class, subnetkey);
1371         final Optional<Subnet> subnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
1372         if (subnet.isPresent()) {
1373             Class<? extends IpVersionBase> ipVersionBase = subnet.get().getIpVersion();
1374             if (ipVersionBase.equals(IpVersionV4.class)) {
1375                 LOG.trace("Obtained subnet {} for vpn interface", subnet.get().getUuid().getValue());
1376                 gwIpAddress = Optional.of(subnet.get().getGatewayIp().getIpv4Address().getValue());
1377                 return gwIpAddress;
1378             }
1379         }
1380         return gwIpAddress;
1381     }
1382
1383     public static RouterToNaptSwitch getRouterToNaptSwitch(DataBroker dataBroker, String routerName) {
1384         InstanceIdentifier<RouterToNaptSwitch> id = InstanceIdentifier.builder(NaptSwitches.class)
1385                 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerName)).build();
1386         Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1387         return routerToNaptSwitchData.isPresent() ? routerToNaptSwitchData.get() : null;
1388     }
1389
1390     public static BigInteger getPrimarySwitchForRouter(DataBroker dataBroker, String routerName) {
1391         RouterToNaptSwitch routerToNaptSwitch = getRouterToNaptSwitch(dataBroker, routerName);
1392         return routerToNaptSwitch != null ? routerToNaptSwitch.getPrimarySwitchId() : null;
1393     }
1394
1395 }