49ad793cf86bd3ad741c36aa50211c993b5a77c2
[netvirt.git] / vpnservice / natservice / natservice-impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatUtil.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.natservice.internal;
10
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.HashMap;
15 import java.util.List;
16
17 import com.google.common.collect.Lists;
18 import com.google.common.collect.Sets;
19
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.genius.mdsalutil.NwConstants;
23 import org.opendaylight.genius.mdsalutil.FlowEntity;
24 import org.opendaylight.genius.mdsalutil.MatchInfo;
25 import org.opendaylight.netvirt.bgpmanager.api.RouteOrigin;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.*;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
70 import org.opendaylight.yangtools.yang.binding.DataObject;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
73 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
74
75 import com.google.common.base.Optional;
76
77 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
78 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
100 import org.opendaylight.yangtools.yang.common.RpcResult;
101 import org.slf4j.Logger;
102 import org.slf4j.LoggerFactory;
103
104 import java.net.InetAddress;
105 import java.net.UnknownHostException;
106 import java.util.Set;
107 import java.util.concurrent.ExecutionException;
108 import java.util.concurrent.Future;
109
110
111
112 public class NatUtil {
113
114     private static String OF_URI_SEPARATOR = ":";
115     private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
116
117     /*
118         getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the reference value.
119      */
120     public static BigInteger getCookieSnatFlow(long routerId) {
121         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
122                 BigInteger.valueOf(routerId));
123     }
124
125     /*
126         getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the reference value.
127     */
128     public static BigInteger getCookieNaptFlow(long routerId) {
129         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
130                 BigInteger.valueOf(routerId));
131     }
132
133     /*
134         getVpnId() returns the VPN ID from the VPN name
135      */
136     public static long getVpnId(DataBroker broker, String vpnName) {
137         if(vpnName == null) {
138             return NatConstants.INVALID_ID;
139         }
140
141         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
142                 = getVpnInstanceToVpnIdIdentifier(vpnName);
143         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
144                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
145
146
147         long vpnId = NatConstants.INVALID_ID;
148         if(vpnInstance.isPresent()) {
149             Long vpnIdAsLong = vpnInstance.get().getVpnId();
150             if(vpnIdAsLong != null){
151                 vpnId = vpnIdAsLong;
152             }
153         }
154         return vpnId;
155     }
156
157     public static Long getVpnId(DataBroker broker, long routerId){
158         //Get the external network ID from the ExternalRouter model
159         Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
160         if(networkId == null ){
161             LOG.error("NAT Service : networkId is null");
162             return null;
163         }
164
165         //Get the VPN ID from the ExternalNetworks model
166         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
167         if(vpnUuid == null ){
168             LOG.error("NAT Service : vpnUuid is null");
169             return null;
170         }
171         Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
172         return vpnId;
173     }
174
175     static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
176         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)).build();
177     }
178
179     static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
180         return InstanceIdentifier.builder(RouterToVpnMapping.class).child(Routermapping.class, new RoutermappingKey(routerId)).build();
181     }
182
183     static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
184         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
185                 .child(Ports.class, new PortsKey(portName)).build();
186     }
187
188     static InstanceIdentifier<IpMapping> getIpMappingIdentifier(String routerId, String portName, String internalIp) {
189         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
190                 .child(Ports.class, new PortsKey(portName))
191                 .child(IpMapping.class, new IpMappingKey(internalIp)).build();
192     }
193
194     /*
195         getVpnInstanceToVpnIdIdentifier() returns the VPN instance from the below model using the VPN name as the key.
196             list vpn-instance {
197                 key "vpn-instance-name"
198                 leaf vpn-instance-name {
199                     type string;
200                 }
201                 leaf vpn-id {
202                     type uint32;
203                 }
204                 leaf vrf-id {
205                     type string;
206                 }
207             }
208     */
209
210     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
211     getVpnInstanceToVpnIdIdentifier(String vpnName) {
212         return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
213                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
214                         new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
215     }
216
217     /*
218        getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
219     */
220     public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
221         return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
222                 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID)
223                 .append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
224     }
225
226     public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
227         return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
228                 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).
229                 append(NatConstants.FLOWID_SEPARATOR).append(port).toString();
230     }
231
232     /*
233         getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key
234                container ext-routers {
235                    list routers {
236                        key router-name;
237                        leaf router-name { type string; }
238                        leaf network-id { type yang:uuid; }
239                        leaf enable-snat { type boolean; }
240                        leaf-list external-ips {
241                             type string; //format - ipaddress\prefixlength
242                        }
243                        leaf-list subnet-ids { type yang:uuid; }
244                    }
245                }
246
247     */
248     static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
249         String routerName = getRouterName(broker, routerId);
250         InstanceIdentifier id = buildRouterIdentifier(routerName);
251         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
252         if (routerData.isPresent()) {
253             return routerData.get().getNetworkId();
254         }
255         return null;
256     }
257
258     static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
259         InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class).child
260                 (Routers.class, new RoutersKey(routerId)).build();
261         return routerInstanceIndentifier;
262     }
263
264     /*
265      * getEnableSnatFromRouterId() returns IsSnatEnabled true is routerID is present in external n/w otherwise returns false
266      */
267     static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId){
268         InstanceIdentifier id = buildRouterIdentifier(routerId);
269         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
270         if (routerData.isPresent()) {
271             return routerData.get().isEnableSnat();
272         }
273         return false;
274     }
275     /*
276         getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key.
277             container external-networks {
278                 list networks  {
279                     key id;
280                     leaf id {
281                         type yang:uuid;
282                     }
283                     leaf vpnid { type yang:uuid; }
284                     leaf-list router-ids { type yang:uuid; }
285                     leaf-list subnet-ids{ type yang:uuid; }
286                 }
287             }
288     */
289     public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
290         InstanceIdentifier id = buildNetworkIdentifier(networkId);
291         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
292         if (networkData.isPresent()) {
293             return networkData.get().getVpnid();
294         }
295         return null;
296     }
297
298     static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
299         InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
300         Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
301         if (routerData.isPresent()) {
302             Uuid networkId = routerData.get().getNetworkId();
303             if(networkId != null) {
304                 return networkId.getValue();
305             }
306         }
307         return null;
308     }
309
310     private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
311         InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class).child
312                 (Networks.class, new NetworksKey(networkId)).build();
313         return network;
314     }
315
316
317
318
319     /*
320         getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id in a array using the router-id; as the key.
321             container napt-switches {
322                 list router-to-napt-switch {
323                     key router-id;
324                     leaf router-id { type uint32; }
325                     leaf primary-switch-id { type uint64; }
326                     leaf secondary-switch-id { type uint64; }
327                 }
328             }
329     */
330     public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
331         // convert routerId to Name
332         String routerName = getRouterName(broker, routerId);
333         InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
334         Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
335         if (routerToNaptSwitchData.isPresent()) {
336             RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
337             return routerToNaptSwitchInstance.getPrimarySwitchId();
338         }
339         return null;
340     }
341
342     private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
343         InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class).child
344                 (RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
345         return rtrNaptSw;
346     }
347
348     public static String getRouterName(DataBroker broker, Long routerId) {
349         InstanceIdentifier id = buildRouterIdentifier(routerId);
350         Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
351         if (routerIdsData.isPresent()) {
352             RouterIds routerIdsInstance = routerIdsData.get();
353             return routerIdsInstance.getRouterName();
354         }
355         return null;
356     }
357
358     private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
359         InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class).child
360                 (RouterIds.class, new RouterIdsKey(routerId)).build();
361         return routerIds;
362     }
363
364     public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
365                                                           InstanceIdentifier<T> path) {
366
367         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
368
369         Optional<T> result = Optional.absent();
370         try {
371             result = tx.read(datastoreType, path).get();
372         } catch (Exception e) {
373             throw new RuntimeException(e);
374         }
375
376         return result;
377     }
378
379     static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
380         return InstanceIdentifier.builder(VpnInstanceOpData.class)
381                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
382     }
383
384     public static long readVpnId(DataBroker broker, String vpnName) {
385
386         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
387                 = getVpnInstanceToVpnIdIdentifier(vpnName);
388         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
389                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
390
391         long vpnId = NatConstants.INVALID_ID;
392         if(vpnInstance.isPresent()) {
393             vpnId = vpnInstance.get().getVpnId();
394         }
395         return vpnId;
396     }
397
398     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
399         FlowEntity flowEntity = new FlowEntity(dpnId);
400         flowEntity.setTableId(tableId);
401         flowEntity.setCookie(cookie);
402         return flowEntity;
403     }
404
405     public static long getIpAddress(byte[] rawIpAddress) {
406         return (((rawIpAddress[0] & 0xFF) << (3 * 8)) + ((rawIpAddress[1] & 0xFF) << (2 * 8))
407                 + ((rawIpAddress[2] & 0xFF) << (1 * 8)) + (rawIpAddress[3] & 0xFF)) & 0xffffffffL;
408     }
409
410     public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix) {
411         return new StringBuilder(64).append(NatConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
412                 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
413                 .append(destPrefix.getHostAddress()).toString();
414     }
415
416     public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
417         String nextHopIp = null;
418         InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
419                 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
420         Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
421         if (tunnelInfo.isPresent()) {
422             List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
423             if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
424                 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
425             }
426         }
427         return nextHopIp;
428     }
429
430     /*
431         getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName
432             list vpn-instance {
433                 key "vpn-instance-name"
434                 leaf vpn-instance-name {
435                     type string;
436                 }
437                 leaf vpn-id {
438                     type uint32;
439                 }
440                 leaf vrf-id {
441                     type string;
442                 }
443             }
444     */
445     public static String getVpnRd(DataBroker broker, String vpnName) {
446
447         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
448                 = getVpnInstanceToVpnIdIdentifier(vpnName);
449         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
450                 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
451
452         String rd = null;
453         if(vpnInstance.isPresent()) {
454             rd = vpnInstance.get().getVrfId();
455         }
456         return rd;
457     }
458
459     /*  getExternalIPPortMap() returns the internal IP and the port for the querried router ID, external IP and the port.
460         container intext-ip-port-map {
461         config true;
462         list ip-port-mapping {
463             key router-id;
464             leaf router-id { type uint32; }
465             list intext-ip-protocol-type {
466                 key protocol;
467                 leaf protocol { type protocol-types; }
468                 list ip-port-map {
469                     key ip-port-internal;
470                     description "internal to external ip-port mapping";
471                     leaf ip-port-internal { type string; }
472                     container ip-port-external {
473                        uses ip-port-entity;
474                     }
475                 }
476             }
477          }
478        }
479     */
480     public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) {
481         ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
482         InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
483         Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
484         if (ipPortMapData.isPresent()) {
485             IpPortMap ipPortMapInstance = ipPortMapData.get();
486             return ipPortMapInstance.getIpPortExternal();
487         }
488         return null;
489     }
490
491     private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, String internalPort , ProtocolTypes protocolType) {
492         InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class).child
493                 (IpPortMapping.class, new IpPortMappingKey(routerId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
494                 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
495         return ipPortMapId;
496     }
497
498     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
499                                              BigInteger cookie, List<MatchInfo> listMatchInfo) {
500
501         FlowEntity flowEntity = new FlowEntity(dpnId);
502         flowEntity.setTableId(tableId);
503         flowEntity.setFlowId(flowId);
504         flowEntity.setPriority(priority);
505         flowEntity.setFlowName(flowName);
506         flowEntity.setCookie(cookie);
507         flowEntity.setMatchInfoList(listMatchInfo);
508         return flowEntity;
509     }
510
511     static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName)
512     {
513         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
514         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
515
516         if (configuredVpnInterface.isPresent()) {
517             return true;
518         }
519         return false;
520     }
521
522     static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
523         return InstanceIdentifier.builder(VpnInterfaces.class)
524                 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
525     }
526
527     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
528         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
529         Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
530
531         if (configuredVpnInterface.isPresent()) {
532             return configuredVpnInterface.get();
533         }
534         return null;
535     }
536
537     public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
538         /*
539          * NodeConnectorId is of form 'openflow:dpnid:portnum'
540          */
541         String[] split = portId.getValue().split(OF_URI_SEPARATOR);
542         return split[1];
543     }
544
545     public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
546         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
547         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
548         return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
549     }
550
551
552     /*
553     container vpnMaps {
554         list vpnMap {
555             key vpn-id;
556             leaf vpn-id {
557                 type    yang:uuid;
558                 description "vpn-id";
559             }
560             leaf name {
561                 type  string;
562                 description "vpn name";
563             }
564             leaf tenant-id {
565                 type    yang:uuid;
566                 description "The UUID of the tenant that will own the subnet.";
567             }
568
569             leaf router-id {
570               type    yang:uuid;
571               description "UUID of router ";
572             }
573             leaf-list network_ids {
574               type    yang:uuid;
575               description "UUID representing the network ";
576             }
577         }
578     }
579     Method returns router Id associated to a VPN
580      */
581
582     public static String getRouterIdfromVpnId(DataBroker broker,String vpnName){
583         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
584                 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
585         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
586                 vpnMapIdentifier);
587         if (optionalVpnMap.isPresent()) {
588             return optionalVpnMap.get().getRouterId().getValue();
589         }
590         return null;
591     }
592
593     static Uuid getVpnForRouter(DataBroker broker, String routerId) {
594         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
595         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
596                 vpnMapsIdentifier);
597         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
598             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
599             if (routerId != null) {
600                 for (VpnMap vpnMap : allMaps) {
601                     if (vpnMap.getRouterId() != null &&
602                             routerId.equals(vpnMap.getRouterId().getValue()) &&
603                             !routerId.equals(vpnMap.getVpnId().getValue())) {
604                         return vpnMap.getVpnId();
605                     }
606                 }
607             }
608         }
609         return null;
610     }
611
612     static long getAssociatedVpn(DataBroker broker, String routerName) {
613         InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
614         Optional<Routermapping> optRouterMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
615         if(optRouterMapping.isPresent()) {
616             Routermapping routerMapping = optRouterMapping.get();
617             return routerMapping.getVpnId();
618         }
619         return NatConstants.INVALID_ID;
620     }
621
622
623     public static List<VpnToDpnList> getVpnToDpnList(DataBroker dataBroker, String vrfId )
624     {
625         List<VpnToDpnList> vpnDpnList = null;
626
627         InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier
628                 .builder(VpnInstanceOpData.class)
629                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId))
630                 .build();
631
632         Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
633
634         if(vpnInstanceOpData.isPresent())
635         {
636             VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnInstanceOpData.get();
637             vpnDpnList = vpnInstanceOpDataEntry.getVpnToDpnList();
638         }
639
640         return vpnDpnList;
641     }
642
643     public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
644         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
645         if(vpnUuid == null ){
646             log.error("No VPN instance associated with ext network {}", networkId);
647             return null;
648         }
649         return vpnUuid.getValue();
650     }
651
652     public static void addPrefixToBGP(IBgpManager bgpManager, String rd, String prefix, List<String> nextHopIpList,
653                                           long label, Logger log, RouteOrigin origin) {
654         try {
655             LOG.info("ADD: Adding Fib Entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHopIpList, label);
656             bgpManager.addPrefix(rd, prefix, nextHopIpList, (int)label, origin);
657             LOG.info("ADD: Added Fib Entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHopIpList, label);
658         } catch(Exception e) {
659             log.error("Add prefix failed", e);
660         }
661     }
662
663     static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
664         InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class).child
665                 (RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
666         return ipPortMapId;
667     }
668
669     static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
670         InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class).child
671                 (RouterPorts.class, new RouterPortsKey(routerId)).build();
672         return routerInstanceIndentifier;
673     }
674
675     /* container snatint-ip-port-map {
676         list intip-port-map {
677             key router-id;
678             leaf router-id { type uint32; }
679             list ip-port {
680                 key internal-ip;
681                 leaf internal-ip { type string; }
682                 list int-ip-proto-type {
683                     key protocol;
684                     leaf protocol { type protocol-types; }
685                     leaf-list ports { type uint16; }
686                 }
687             }
688         }
689     }
690     Method returns InternalIp port List
691     */
692
693     public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker,Long routerId, String internalIpAddress, ProtocolTypes protocolType){
694         Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
695         if (optionalIpProtoType.isPresent()) {
696             return optionalIpProtoType.get().getPorts();
697         }
698         return null;
699     }
700
701     public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId, String internalIpAddress, ProtocolTypes protocolType) {
702         InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId = InstanceIdentifier.builder(SnatintIpPortMap.class).child
703                 (IntipPortMap.class, new IntipPortMapKey(routerId)).child(IpPort.class, new IpPortKey(internalIpAddress)).child
704                 (IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
705         return intIpProtocolTypeId;
706     }
707
708     public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
709         ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString()) ? ProtocolTypes.TCP : ProtocolTypes.UDP;
710         return protocolType;
711     }
712
713     public static NaptSwitches getNaptSwitch(DataBroker broker) {
714         Optional<NaptSwitches> switchesOptional = read(broker, LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
715         if(switchesOptional.isPresent()) {
716             return switchesOptional.get();
717         }
718         return null;
719     }
720
721     public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
722         return InstanceIdentifier.create(NaptSwitches.class);
723     }
724
725     public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
726         return InstanceIdentifier.create(NaptSwitches.class).child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
727     }
728
729     public static String toStringIpAddress(byte[] ipAddress, Logger log)
730     {
731         String ip = "";
732         if (ipAddress == null) {
733             return ip;
734         }
735
736         try {
737             ip = InetAddress.getByAddress(ipAddress).getHostAddress();
738         } catch(UnknownHostException e) {
739             log.error("NAT Service : Caught exception during toStringIpAddress()");
740         }
741
742         return ip;
743     }
744
745     public static String getGroupIdKey(String routerName){
746         String groupIdKey = new String("snatmiss." + routerName);
747         return groupIdKey;
748     }
749
750     public static long createGroupId(String groupIdKey,IdManagerService idManager) {
751         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
752                 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
753                 .build();
754         try {
755             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
756             RpcResult<AllocateIdOutput> rpcResult = result.get();
757             return rpcResult.getResult().getIdValue();
758         } catch (NullPointerException | InterruptedException | ExecutionException e) {
759             LOG.trace("", e);
760         }
761         return 0;
762     }
763
764     public static void removePrefixFromBGP(IBgpManager bgpManager, String rd, String prefix, Logger log) {
765         try {
766             LOG.info("REMOVE: Removing Fib Entry rd {} prefix {}", rd, prefix);
767             bgpManager.deletePrefix(rd, prefix);
768             LOG.info("REMOVE: Removed Fib Entry rd {} prefix {}", rd, prefix);
769         } catch(Exception e) {
770             log.error("Delete prefix failed", e);
771         }
772     }
773
774     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
775         FlowEntity flowEntity = new FlowEntity(dpnId);
776         flowEntity.setTableId(tableId);
777         flowEntity.setCookie(cookie);
778         flowEntity.setFlowId(flowId);
779         return flowEntity;
780     }
781
782     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
783         FlowEntity flowEntity = new FlowEntity(dpnId);
784         flowEntity.setTableId(tableId);
785         flowEntity.setFlowId(flowId);
786         return flowEntity;
787     }
788
789     public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
790         Optional<IpPortMapping> getIportMappingData = read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId));
791         if(getIportMappingData.isPresent()) {
792             return getIportMappingData.get();
793         }
794         return null;
795     }
796
797     public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
798         return InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
799     }
800
801     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
802         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
803                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMappingKey(routerId)).build();
804         return idBuilder;
805     }
806
807     public static List<String> getExternalIpsForRouter(DataBroker dataBroker,Long routerId) {
808         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
809                 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
810         List<String> externalIps = new ArrayList<>();
811         if (ipMappingOptional.isPresent()) {
812             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
813             for (IpMap ipMap : ipMaps) {
814                 externalIps.add(ipMap.getExternalIp());
815             }
816             //remove duplicates
817             Set<String> uniqueExternalIps = Sets.newHashSet(externalIps);
818             externalIps = Lists.newArrayList(uniqueExternalIps);
819             return externalIps;
820         }
821         return null;
822     }
823
824     public static HashMap<String,Long> getExternalIpsLabelForRouter(DataBroker dataBroker,Long routerId) {
825         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
826                 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
827         HashMap<String,Long> externalIpsLabel = new HashMap<>();
828         if (ipMappingOptional.isPresent()) {
829             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
830             for (IpMap ipMap : ipMaps) {
831                 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
832             }
833             return externalIpsLabel;
834         }
835         return null;
836     }
837     /*
838     container external-ips-counter {
839         config false;
840         list external-counters{
841             key segment-id;
842             leaf segment-id { type uint32; }
843             list external-ip-counter {
844                 key external-ip;
845                 leaf external-ip { type string; }
846                 leaf counter { type uint8; }
847             }
848         }
849     }
850     */
851
852     public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId){
853         String leastLoadedExternalIp =  null;
854         InstanceIdentifier<ExternalCounters> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
855         Optional <ExternalCounters> externalCountersData = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
856         if (externalCountersData.isPresent()) {
857             ExternalCounters externalCounter = externalCountersData.get();
858             List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
859             short countOfLstLoadExtIp = 32767;
860             for(ExternalIpCounter externalIpCounter : externalIpCounterList){
861                 String curExternalIp = externalIpCounter.getExternalIp();
862                 short countOfCurExtIp  = externalIpCounter.getCounter();
863                 if( countOfCurExtIp < countOfLstLoadExtIp ){
864                     countOfLstLoadExtIp = countOfCurExtIp;
865                     leastLoadedExternalIp = curExternalIp;
866                 }
867             }
868         }
869         return leastLoadedExternalIp;
870     }
871
872     public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId){
873         String subnetIP = getSubnetIp(dataBroker, subnetId);
874         if(subnetId != null){
875             return getSubnetIpAndPrefix(subnetIP);
876         }
877         return null;
878     }
879
880     public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId){
881         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
882                 .builder(Subnetmaps.class)
883                 .child(Subnetmap.class, new SubnetmapKey(subnetId))
884                 .build();
885         Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
886         if(removedSubnet.isPresent()) {
887             Subnetmap subnetMapEntry = removedSubnet.get();
888             return subnetMapEntry.getSubnetIp();
889         }
890         return null;
891
892     }
893     public static String[] getSubnetIpAndPrefix(String subnetString){
894         String[] subnetSplit = subnetString.split("/");
895         String subnetIp = subnetSplit[0];
896         String subnetPrefix = "0";
897         if (subnetSplit.length == 2) {
898             subnetPrefix = subnetSplit[1];
899         }
900         return new String[] {subnetIp, subnetPrefix};
901     }
902
903     public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr){
904         String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
905         String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
906         String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
907         if (leastLoadedExtIpAddrSplit.length == 2) {
908             leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
909         }
910         return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
911     }
912
913     public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid){
914         InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class).child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
915         Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
916         List<BigInteger> dpns = new ArrayList<>();
917         if (routerDpnListData.isPresent()) {
918             List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
919             for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
920                 dpns.add(dpnVpnInterface.getDpnId());
921             }
922             return dpns;
923         }
924         return null;
925     }
926
927     public static long getBgpVpnId(DataBroker dataBroker, String routerName){
928         long bgpVpnId = NatConstants.INVALID_ID;
929         Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
930         if(bgpVpnUuid != null){
931             bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
932         }
933         return bgpVpnId;
934     }
935 }