Datastore txes: natservice, AbstractSnatService
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / NatUtil.java
1 /*
2  * Copyright © 2016, 2018 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 com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.CheckedFuture;
14 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
15 import java.math.BigInteger;
16 import java.net.InetAddress;
17 import java.net.UnknownHostException;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Objects;
26 import java.util.Set;
27 import java.util.concurrent.ExecutionException;
28 import java.util.concurrent.Future;
29 import java.util.stream.Collectors;
30 import javax.annotation.Nonnull;
31 import javax.annotation.Nullable;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
34 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
35 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
36 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
37 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
38 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
39 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
40 import org.opendaylight.genius.infra.Datastore.Configuration;
41 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
42 import org.opendaylight.genius.infra.TypedReadTransaction;
43 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
44 import org.opendaylight.genius.mdsalutil.ActionInfo;
45 import org.opendaylight.genius.mdsalutil.FlowEntity;
46 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
47 import org.opendaylight.genius.mdsalutil.InstructionInfo;
48 import org.opendaylight.genius.mdsalutil.MDSALUtil;
49 import org.opendaylight.genius.mdsalutil.MatchInfo;
50 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
51 import org.opendaylight.genius.mdsalutil.NwConstants;
52 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
53 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
54 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
55 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
56 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
57 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
58 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
59 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
60 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
61 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
62 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
63 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
64 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
65 import org.opendaylight.netvirt.elanmanager.api.IElanService;
66 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
67 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
68 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
69 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
70 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
71 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
72 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
73 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
74 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
75 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
76 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
77 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
78 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
79 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
80 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
81 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
82 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
194 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;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
233 import org.opendaylight.yangtools.yang.binding.DataObject;
234 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
235 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
236 import org.opendaylight.yangtools.yang.common.RpcResult;
237 import org.slf4j.Logger;
238 import org.slf4j.LoggerFactory;
239
240 public final class NatUtil {
241
242     private static String OF_URI_SEPARATOR = ":";
243     private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
244
245     private NatUtil() { }
246
247     /*
248      getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
249       reference value.
250      */
251     public static BigInteger getCookieSnatFlow(long routerId) {
252         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
253             BigInteger.valueOf(routerId));
254     }
255
256     /*
257       getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
258        reference value.
259     */
260     public static BigInteger getCookieNaptFlow(long routerId) {
261         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
262             BigInteger.valueOf(routerId));
263     }
264
265     /*
266         getVpnId() returns the VPN ID from the VPN name
267      */
268     public static long getVpnId(DataBroker broker, String vpnName) {
269         if (vpnName == null) {
270             return NatConstants.INVALID_ID;
271         }
272
273         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
274             .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
275         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
276                 .instance.to.vpn.id.VpnInstance> vpnInstance =
277                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
278                         LogicalDatastoreType.CONFIGURATION, id);
279
280         long vpnId = NatConstants.INVALID_ID;
281         if (vpnInstance.isPresent()) {
282             Long vpnIdAsLong = vpnInstance.get().getVpnId();
283             if (vpnIdAsLong != null) {
284                 vpnId = vpnIdAsLong;
285             }
286         }
287         return vpnId;
288     }
289
290     public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
291         if (vpnName == null) {
292             return NatConstants.INVALID_ID;
293         }
294
295         try {
296             return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
297                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
298                     .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
299         } catch (InterruptedException | ExecutionException e) {
300             LOG.error("Error retrieving VPN id for {}", vpnName, e);
301         }
302
303         return NatConstants.INVALID_ID;
304     }
305
306     public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
307         //Get the external network ID from the ExternalRouter model
308         Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
309         if (networkId == null) {
310             LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
311             return NatConstants.INVALID_ID;
312         }
313
314         //Get the VPN ID from the ExternalNetworks model
315         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
316         if (vpnUuid == null) {
317             LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
318             return NatConstants.INVALID_ID;
319         }
320         Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
321         return vpnId;
322     }
323
324     static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
325         return InstanceIdentifier.builder(FloatingIpInfo.class)
326             .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
327     }
328
329     static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
330         return InstanceIdentifier.builder(RouterToVpnMapping.class)
331             .child(Routermapping.class, new RoutermappingKey(routerId)).build();
332     }
333
334     static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
335         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
336             .child(Ports.class, new PortsKey(portName)).build();
337     }
338
339     static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
340                                                                                     String internalIp) {
341         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
342             .child(Ports.class, new PortsKey(portName))
343             .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
344     }
345
346     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
347         .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
348         return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
349             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
350                     .instance.to.vpn.id.VpnInstance.class,
351                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
352                     .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
353     }
354
355     static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
356         InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
357             .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
358         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
359                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
360     }
361
362     /*
363        getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
364     */
365     public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
366         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
367                 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
368     }
369
370     public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
371         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
372                 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
373     }
374
375     public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
376         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
377                 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
378                 + port;
379     }
380
381     static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
382         String routerName = getRouterName(broker, routerId);
383         if (routerName == null) {
384             LOG.error("getNetworkIdFromRouterId - empty routerName received");
385             return null;
386         }
387         return getNetworkIdFromRouterName(broker, routerName);
388     }
389
390     static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
391         if (routerName == null) {
392             LOG.error("getNetworkIdFromRouterName - empty routerName received");
393             return null;
394         }
395         InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
396         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
397                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
398     }
399
400     static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
401         InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
402             .child(Routers.class, new RoutersKey(routerId)).build();
403         return routerInstanceIndentifier;
404     }
405
406     private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
407         InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
408             .child(RouterIds.class, new RouterIdsKey(routerId)).build();
409         return routerIds;
410     }
411
412     /**
413      * Return if SNAT is enabled for the given router.
414      *
415      * @param broker   The DataBroker
416      * @param routerId The router
417      * @return boolean true if enabled, otherwise false
418      */
419     static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
420         InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
421         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
422                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
423     }
424
425     public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
426         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
427         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
428                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
429     }
430
431     public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
432         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
433         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
434                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
435     }
436
437     @Nullable
438     public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
439         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
440         try {
441             return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
442         } catch (InterruptedException | ExecutionException e) {
443             LOG.error("Error retrieving provider type for {}", networkId, e);
444             return null;
445         }
446     }
447
448     @Nonnull
449     public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
450         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
451         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
452                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse(
453                 Collections.emptyList());
454     }
455
456     static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
457         InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
458         Optional<Routers> routerData =
459                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
460                         LogicalDatastoreType.CONFIGURATION, id);
461         if (routerData.isPresent()) {
462             Uuid networkId = routerData.get().getNetworkId();
463             if (networkId != null) {
464                 return networkId.getValue();
465             }
466         }
467         LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
468         return null;
469     }
470
471     private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
472         return InstanceIdentifier.builder(ExternalNetworks.class)
473             .child(Networks.class, new NetworksKey(networkId)).build();
474     }
475
476     public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
477         // convert routerId to Name
478         String routerName = getRouterName(broker, routerId);
479         if (routerName == null) {
480             LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
481             return null;
482         }
483         return getPrimaryNaptfromRouterName(broker, routerName);
484     }
485
486     public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
487         if (routerName == null) {
488             LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
489             return null;
490         }
491         InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
492         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
493                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
494                 null);
495     }
496
497     public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
498         InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
499             .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
500         return rtrNaptSw;
501     }
502
503     public static String getRouterName(DataBroker broker, Long routerId) {
504         InstanceIdentifier<RouterIds> id = buildRouterIdentifier(routerId);
505         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
506                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterIds::getRouterName).orElse(null);
507     }
508
509     static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
510         return InstanceIdentifier.builder(VpnInstanceOpData.class)
511             .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
512     }
513
514     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
515         return new FlowEntityBuilder()
516                 .setDpnId(dpnId)
517                 .setTableId(tableId)
518                 .setCookie(cookie)
519                 .setFlowId(flowId)
520                 .build();
521     }
522
523     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
524         return new FlowEntityBuilder()
525                 .setDpnId(dpnId)
526                 .setTableId(tableId)
527                 .setFlowId(flowId)
528                 .build();
529     }
530
531     public static long getIpAddress(byte[] rawIpAddress) {
532         return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
533             + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
534     }
535
536     public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
537         String nextHopIp = null;
538         InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
539             InstanceIdentifier.builder(DpnEndpoints.class)
540                 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
541         Optional<DPNTEPsInfo> tunnelInfo =
542                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
543                         LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
544         if (tunnelInfo.isPresent()) {
545             List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
546             if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
547                 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
548             }
549         }
550         return nextHopIp;
551     }
552
553     public static String getVpnRd(DataBroker broker, String vpnName) {
554
555         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
556             .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
557         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
558                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
559                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
560                         .VpnInstance::getVrfId).orElse(null);
561     }
562
563     public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
564         try {
565             return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
566                 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
567                     .VpnInstance::getVrfId).orElse(null);
568         } catch (InterruptedException | ExecutionException e) {
569             LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
570             return null;
571         }
572     }
573
574     public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
575                                                       String internalPort, NAPTEntryEvent.Protocol protocol) {
576         ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
577         InstanceIdentifier<IpPortMap> ipPortMapId =
578             buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
579         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
580                 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
581                 null);
582     }
583
584     private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
585                                                                             String internalPort,
586                                                                             ProtocolTypes protocolType) {
587         return InstanceIdentifier.builder(IntextIpPortMap.class)
588             .child(IpPortMapping.class, new IpPortMappingKey(routerId))
589             .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
590             .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
591     }
592
593     static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
594         return InstanceIdentifier.builder(VpnInterfaces.class)
595             .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
596     }
597
598     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
599         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
600         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
601                 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
602     }
603
604     public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
605         /*
606          * NodeConnectorId is of form 'openflow:dpnid:portnum'
607          */
608         String[] split = portId.getValue().split(OF_URI_SEPARATOR);
609         if (split.length != 3) {
610             LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
611             return null;
612         }
613         return split[1];
614     }
615
616     public static BigInteger getDpIdFromInterface(
617         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
618             .state.Interface ifState) {
619         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
620         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
621         return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
622     }
623
624     public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
625         // returns only router, attached to IPv4 networks
626         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
627             .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
628         Optional<VpnMap> optionalVpnMap =
629                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
630                         LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
631         if (!optionalVpnMap.isPresent()) {
632             LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
633             return null;
634         }
635         List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
636         if (routerIdsList != null && !routerIdsList.isEmpty()) {
637             for (Uuid routerUuid : routerIdsList) {
638                 InstanceIdentifier<Router> routerIdentifier = buildNeutronRouterIdentifier(routerUuid);
639                 Optional<Router> optRouter = SingleTransactionDataBroker
640                     .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
641                             LogicalDatastoreType.CONFIGURATION, routerIdentifier);
642                 if (!optRouter.isPresent()) {
643                     continue;
644                 }
645                 List<Routes> routes = optRouter.get().getRoutes();
646                 if (routes == null || routes.isEmpty()) {
647                     continue;
648                 }
649                 for (Routes r : routes) {
650                     if (r.getDestination().getIpv4Prefix() != null) {
651                         return routerUuid.getValue();
652                     }
653                 }
654             }
655         }
656         LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
657         return null;
658     }
659
660     static Uuid getVpnForRouter(DataBroker broker, String routerId) {
661         Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
662         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
663         Optional<VpnMaps> optionalVpnMaps =
664                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
665                         LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
666         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
667             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
668             for (VpnMap vpnMap: allMaps) {
669                 if (routerId.equals(vpnMap.getVpnId().getValue())) {
670                     continue;
671                 }
672                 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
673                 if (routerIdsList == null || routerIdsList.isEmpty()) {
674                     return null;
675                 }
676                 if (routerIdsList.contains(new Uuid(routerId))) {
677                     return vpnMap.getVpnId();
678                 }
679             }
680         }
681         LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
682         return null;
683     }
684
685     static long getAssociatedVpn(DataBroker broker, String routerName) {
686         InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
687         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
688                 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
689                 NatConstants.INVALID_ID);
690     }
691
692     public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
693         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
694         if (vpnUuid == null) {
695             LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
696             return null;
697         }
698         return vpnUuid.getValue();
699     }
700
701     // TODO Clean up the exception handling
702     @SuppressWarnings("checkstyle:IllegalCatch")
703     public static void addPrefixToBGP(DataBroker broker,
704                                       IBgpManager bgpManager,
705                                       IFibManager fibManager,
706                                       String vpnName,
707                                       String rd,
708                                       Uuid subnetId,
709                                       String prefix,
710                                       String nextHopIp,
711                                       String parentVpnRd,
712                                       String macAddress,
713                                       long label,
714                                       long l3vni,
715                                       RouteOrigin origin,
716                                       BigInteger dpId) {
717         try {
718             LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
719                     prefix, nextHopIp, label);
720             if (nextHopIp == null) {
721                 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
722                         prefix, rd);
723                 return;
724             }
725
726             addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId,
727                     subnetId, Prefixes.PrefixCue.Nat);
728             fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
729                     Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
730                     null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
731             if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
732             /* Publish to Bgp only if its an INTERNET VPN */
733                 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
734                         VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
735                         null /*gatewayMac*/);
736             }
737             LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
738                     prefix, nextHopIp, label);
739         } catch (Exception e) {
740             LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
741                     prefix, nextHopIp, label, e);
742         }
743     }
744
745     static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
746                                      BigInteger dpId, Uuid subnetId, Prefixes.PrefixCue prefixCue) {
747         InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
748                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
749                         .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
750                         .to._interface.VpnIdsKey(vpnId))
751                 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
752         PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
753         prefixBuilder.setVpnInterfaceName(interfaceName).setSubnetId(subnetId).setPrefixCue(prefixCue);
754         try {
755             SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
756                     prefixBuilder.build());
757         } catch (TransactionCommitFailedException e) {
758             LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
759                     ipPrefix, vpnId, dpId, e);
760         }
761     }
762
763     public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
764         try {
765             SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
766                     InstanceIdentifier.builder(PrefixToInterface.class)
767                     .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
768                             .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
769                             .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
770                     .build());
771         } catch (TransactionCommitFailedException e) {
772             LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
773                     vpnId, e);
774         }
775     }
776
777     static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
778         InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
779             .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
780         return ipPortMapId;
781     }
782
783     static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
784         InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
785             .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
786         return routerInstanceIndentifier;
787     }
788
789     @Nonnull
790     public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
791                                                           String internalIpAddress, ProtocolTypes protocolType) {
792         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
793                 LogicalDatastoreType.CONFIGURATION,
794                 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
795                 IntIpProtoType::getPorts).orElse(Collections.emptyList());
796     }
797
798     public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
799                                                                                   String internalIpAddress,
800                                                                                   ProtocolTypes protocolType) {
801         InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
802             InstanceIdentifier.builder(SnatintIpPortMap.class)
803                 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
804                 .child(IpPort.class, new IpPortKey(internalIpAddress))
805                 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
806         return intIpProtocolTypeId;
807     }
808
809     public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
810             String internalIpAddress) {
811         InstanceIdentifier<IpPort> intIpProtocolTypeId =
812             InstanceIdentifier.builder(SnatintIpPortMap.class)
813                 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
814                 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
815         return intIpProtocolTypeId;
816     }
817
818     @Nullable
819     public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
820                                                           String internalIpAddress) {
821         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
822                 LogicalDatastoreType.CONFIGURATION,
823                 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
824     }
825
826     public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
827         ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
828             ? ProtocolTypes.TCP : ProtocolTypes.UDP;
829         return protocolType;
830     }
831
832     public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
833         return InstanceIdentifier.create(NaptSwitches.class);
834     }
835
836     public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
837         return InstanceIdentifier.create(NaptSwitches.class)
838             .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
839     }
840
841     public static String getGroupIdKey(String routerName) {
842         return "snatmiss." + routerName;
843     }
844
845     public static long createGroupId(String groupIdKey, IdManagerService idManager) {
846         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
847             .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
848             .build();
849         try {
850             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
851             RpcResult<AllocateIdOutput> rpcResult = result.get();
852             return rpcResult.getResult().getIdValue();
853         } catch (NullPointerException | InterruptedException | ExecutionException e) {
854             LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
855         }
856         return 0;
857     }
858
859     // TODO Clean up the exception handling
860     @SuppressWarnings("checkstyle:IllegalCatch")
861     public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
862                                            String rd, String prefix, String vpnName, Logger log) {
863         try {
864             LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
865             fibManager.removeFibEntry(rd, prefix, null);
866             if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
867                 bgpManager.withdrawPrefix(rd, prefix);
868             }
869             LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
870         } catch (Exception e) {
871             log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
872                     rd, prefix, vpnName, e);
873         }
874     }
875
876     public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
877         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
878                 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
879     }
880
881     public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
882         return InstanceIdentifier.builder(IntextIpPortMap.class)
883             .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
884     }
885
886     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
887         .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
888         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
889             .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
890             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
891                 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
892                 .intext.ip.map.IpMappingKey(routerId)).build();
893         return idBuilder;
894     }
895
896     @Nonnull
897     public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
898         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
899             .ip.map.IpMapping> ipMappingOptional =
900                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
901                         LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
902         // Ensure there are no duplicates
903         Collection<String> externalIps = new HashSet<>();
904         if (ipMappingOptional.isPresent()) {
905             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
906             for (IpMap ipMap : ipMaps) {
907                 externalIps.add(ipMap.getExternalIp());
908             }
909         }
910         return externalIps;
911     }
912
913     @Nonnull
914     public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
915         Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
916         if (routerData != null) {
917             return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
918         }
919
920         return Collections.emptyList();
921     }
922
923     @Nonnull
924     public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
925         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
926             .ip.map.IpMapping> ipMappingOptional =
927                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
928                         LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
929         Map<String, Long> externalIpsLabel = new HashMap<>();
930         if (ipMappingOptional.isPresent()) {
931             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
932             for (IpMap ipMap : ipMaps) {
933                 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
934             }
935         }
936         return externalIpsLabel;
937     }
938
939     public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
940         String leastLoadedExternalIp = null;
941         InstanceIdentifier<ExternalCounters> id =
942             InstanceIdentifier.builder(ExternalIpsCounter.class)
943                 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
944         Optional<ExternalCounters> externalCountersData =
945             MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
946         if (externalCountersData.isPresent()) {
947             ExternalCounters externalCounter = externalCountersData.get();
948             List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
949             short countOfLstLoadExtIp = 32767;
950             for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
951                 String curExternalIp = externalIpCounter.getExternalIp();
952                 short countOfCurExtIp = externalIpCounter.getCounter();
953                 if (countOfCurExtIp < countOfLstLoadExtIp) {
954                     countOfLstLoadExtIp = countOfCurExtIp;
955                     leastLoadedExternalIp = curExternalIp;
956                 }
957             }
958         }
959         return leastLoadedExternalIp;
960     }
961
962     @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
963     public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
964         String subnetIP = getSubnetIp(dataBroker, subnetId);
965         if (subnetIP != null) {
966             return getSubnetIpAndPrefix(subnetIP);
967         }
968         LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
969         return null;
970     }
971
972     public static String[] getSubnetIpAndPrefix(String subnetString) {
973         String[] subnetSplit = subnetString.split("/");
974         String subnetIp = subnetSplit[0];
975         String subnetPrefix = "0";
976         if (subnetSplit.length == 2) {
977             subnetPrefix = subnetSplit[1];
978         }
979         return new String[] {subnetIp, subnetPrefix};
980     }
981
982     public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
983         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
984             .builder(Subnetmaps.class)
985             .child(Subnetmap.class, new SubnetmapKey(subnetId))
986             .build();
987         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
988                 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
989
990     }
991
992     public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
993         String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
994         String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
995         String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
996         if (leastLoadedExtIpAddrSplit.length == 2) {
997             leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
998         }
999         return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1000     }
1001
1002     @Nonnull
1003     public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1004         InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1005             .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1006         Optional<RouterDpnList> routerDpnListData =
1007                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1008                         LogicalDatastoreType.OPERATIONAL, id);
1009         List<BigInteger> dpns = new ArrayList<>();
1010         if (routerDpnListData.isPresent()) {
1011             List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
1012             for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
1013                 dpns.add(dpnVpnInterface.getDpnId());
1014             }
1015         }
1016         return dpns;
1017     }
1018
1019     public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1020         long bgpVpnId = NatConstants.INVALID_ID;
1021         Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1022         if (bgpVpnUuid != null) {
1023             bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1024         }
1025         return bgpVpnId;
1026     }
1027
1028     static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1029         .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1030         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1031                 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1032     }
1033
1034     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1035         .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1036         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1037             .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1038             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1039                     .RouterInterface.class,
1040                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1041                     .RouterInterfaceKey(interfaceName)).build();
1042     }
1043
1044     public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1045             BigInteger dpId , WriteTransaction writeOperTxn) {
1046
1047         if (dpId.equals(BigInteger.ZERO)) {
1048             LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1049                     + "to handle router {} association model", interfaceName, routerName);
1050             return;
1051         }
1052
1053         LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1054                 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1055         InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1056
1057         Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList =
1058                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1059                         LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier);
1060         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1061             .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1062             new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1063             .setInterface(interfaceName).build();
1064         if (optionalDpnVpninterfacesList.isPresent()) {
1065             LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1066                     + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1067             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
1068                     .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1069                             .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1070                             new RouterInterfacesKey(interfaceName)), routerInterface, true);
1071         } else {
1072             LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1073                     + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1074             RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1075             routerDpnListBuilder.setRouterId(routerName);
1076             DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1077             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1078                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1079             routerInterfaces.add(routerInterface);
1080             dpnVpnList.setRouterInterfaces(routerInterfaces);
1081             routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1082             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1083                     getRouterId(routerName),
1084                     routerDpnListBuilder.build(), true);
1085         }
1086     }
1087
1088     public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1089             BigInteger dpId, WriteTransaction writeOperTxn) {
1090         if (dpId.equals(BigInteger.ZERO)) {
1091             LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1092                     + "association model", interfaceName, routerName);
1093             return;
1094         }
1095
1096         LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1097                 + "DPNRouters map", dpId, routerName, interfaceName);
1098         InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1099
1100         Optional<DpnRoutersList> optionalDpnRoutersList =
1101                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1102                         LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1103
1104         if (optionalDpnRoutersList.isPresent()) {
1105             RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1106                     .setRouter(routerName).build();
1107             List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1108             if (!routersListFromDs.contains(routersList)) {
1109                 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1110                         + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1111                 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1112                         dpnRoutersListIdentifier
1113                         .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1114             } else {
1115                 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1116                         + "DPNRouters map", routerName, dpId);
1117             }
1118         } else {
1119             LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1120                     + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1121             DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1122             dpnRoutersListBuilder.setDpnId(dpId);
1123             RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1124             routersListBuilder.setRouter(routerName);
1125             dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1126             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1127                     getDpnRoutersId(dpId),
1128                     dpnRoutersListBuilder.build(), true);
1129         }
1130     }
1131
1132
1133     public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1134                                                BigInteger dpId, WriteTransaction writeOperTxn) {
1135         if (dpId.equals(BigInteger.ZERO)) {
1136             LOG.error("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {} "
1137                     + "dissociation model", interfaceName, routerName);
1138             return;
1139         }
1140         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1141         Optional<DpnVpninterfacesList> optionalRouterDpnList =
1142                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1143                         LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1144         if (optionalRouterDpnList.isPresent()) {
1145             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1146                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1147                 optionalRouterDpnList.get().getRouterInterfaces();
1148             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1149                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1150                 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1151                     .setInterface(interfaceName).build();
1152             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1153                 if (routerInterfaces.isEmpty()) {
1154                     writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1155                 } else {
1156                     writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1157                         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1158                             .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1159                         new RouterInterfacesKey(interfaceName)));
1160                 }
1161             }
1162         }
1163     }
1164
1165     public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1166                                                BigInteger dpId, WriteTransaction writeOperTxn) {
1167         if (dpId.equals(BigInteger.ZERO)) {
1168             LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1169             return;
1170         }
1171
1172         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1173         Optional<DpnVpninterfacesList> optionalRouterDpnList =
1174                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1175                         LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1176         if (optionalRouterDpnList.isPresent()) {
1177             LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1178                     + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1179             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1180         } else {
1181             LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1182                     + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1183         }
1184     }
1185
1186     public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1187                                                OdlInterfaceRpcService ifaceMgrRpcService,
1188                                                WriteTransaction writeOperTxn) {
1189         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1190         if (dpId.equals(BigInteger.ZERO)) {
1191             LOG.debug("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {}"
1192                     + " dissociation model", vpnInterfaceName, routerName);
1193             return;
1194         }
1195         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1196         Optional<DpnVpninterfacesList> optionalRouterDpnList =
1197                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1198                         LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1199         if (optionalRouterDpnList.isPresent()) {
1200             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1201                 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1202                 optionalRouterDpnList.get().getRouterInterfaces();
1203             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1204                 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1205                 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1206                     .setInterface(vpnInterfaceName).build();
1207
1208             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1209                 if (routerInterfaces.isEmpty()) {
1210                     if (writeOperTxn != null) {
1211                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1212                     } else {
1213                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1214                     }
1215                 } else {
1216                     if (writeOperTxn != null) {
1217                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1218                             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1219                                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1220                             new RouterInterfacesKey(vpnInterfaceName)));
1221                     } else {
1222                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1223                             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1224                                 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1225                             new RouterInterfacesKey(vpnInterfaceName)));
1226                     }
1227                 }
1228             }
1229         }
1230     }
1231
1232     public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1233                                         OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1234         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1235         if (dpId.equals(BigInteger.ZERO)) {
1236             LOG.debug("removeFromDpnRoutersMap : removeFromDpnRoutersMap() : "
1237                 + "Could not retrieve DPN ID for interface {} to handle router {} dissociation model",
1238                 vpnInterfaceName, routerName);
1239             return;
1240         }
1241         removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1242     }
1243
1244     static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1245                                         BigInteger curDpnId,
1246                                         OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1247         /*
1248             1) Get the DpnRoutersList for the DPN.
1249             2) Get the RoutersList identifier for the DPN and router.
1250             3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1251             4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1252              then remove RouterList.
1253          */
1254
1255         LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1256             + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1257
1258         //Get the dpn-routers-list instance for the current DPN.
1259         InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1260         Optional<DpnRoutersList> dpnRoutersListData =
1261                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1262                         LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1263
1264         if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1265             LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1266                     + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1267             return;
1268         }
1269
1270         //Get the routers-list instance for the router on the current DPN only
1271         InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1272         Optional<RoutersList> routersListData =
1273                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1274                         LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1275
1276         if (routersListData == null || !routersListData.isPresent()) {
1277             LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1278                     + "in the ODL-L3VPN:dpn-routers model",
1279                 curDpnId);
1280             return;
1281         }
1282
1283         LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1284                 + "from the NeutronVPN - router-interfaces-map", routerName);
1285         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1286             .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1287         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1288                 .RouterInterfaces> routerInterfacesData =
1289                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1290                         LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1291
1292         if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1293             LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1294                     + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1295                 curDpnId, routerName, routerName);
1296             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1297             return;
1298         }
1299
1300         //Get the VM interfaces for the router on the current DPN only.
1301         List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1302             .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1303         if (vmInterfaces == null) {
1304             LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1305                 + "NeutronVPN - router-interfaces-map", routerName);
1306             return;
1307         }
1308
1309         // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1310         // then remove RouterList.
1311         for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1312                  .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1313             String vmInterfaceName = vmInterface.getInterfaceId();
1314             BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1315             if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1316                 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1317                         + "the DPN ID {} for the checked interface {}",
1318                     curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1319                 continue;
1320             }
1321             if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1322                 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1323                     + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1324                 return;
1325             }
1326         }
1327         LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1328             + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1329             + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1330         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1331     }
1332
1333     private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1334         .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1335         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1336             .rev150602.RouterInterfacesMap.class)
1337             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1338                     .interfaces.map.RouterInterfaces.class,
1339                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1340                     .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1341     }
1342
1343     private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1344         return InstanceIdentifier.builder(DpnRouters.class)
1345             .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1346             .child(RoutersList.class, new RoutersListKey(routerName)).build();
1347     }
1348
1349     public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1350         BigInteger nodeId = BigInteger.ZERO;
1351         try {
1352             GetDpidFromInterfaceInput
1353                 dpIdInput =
1354                 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1355             Future<RpcResult<GetDpidFromInterfaceOutput>>
1356                 dpIdOutput =
1357                 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1358             RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1359             if (dpIdResult.isSuccessful()) {
1360                 nodeId = dpIdResult.getResult().getDpid();
1361             } else {
1362                 LOG.debug("removeFromDpnRoutersMap : Could not retrieve DPN Id for interface {}", ifName);
1363             }
1364         } catch (NullPointerException | InterruptedException | ExecutionException e) {
1365             LOG.error("removeFromDpnRoutersMap : Exception when getting dpn for interface {}", ifName, e);
1366         }
1367         return nodeId;
1368     }
1369
1370     @Nonnull
1371     public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1372                                                                 ItmRpcService itmRpcService,
1373                                                                 IInterfaceManager interfaceManager, String ifName,
1374                                                                 Long tunnelKey, boolean internalTunnelInterface) {
1375         return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1376                 ifName, tunnelKey, 0, internalTunnelInterface);
1377     }
1378
1379     @Nonnull
1380     public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1381                                                                 ItmRpcService itmRpcService,
1382                                                                 IInterfaceManager interfaceManager,
1383                                                                 String ifName, Long tunnelKey, int pos,
1384                                                                 boolean internalTunnelInterface) {
1385         LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1386         GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1387                 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1388         GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1389                 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1390         if (tunnelKey != null) {
1391             egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1392             egressActionsItmBuilder.setTunnelKey(tunnelKey);
1393         } //init builders, ITM/IFM rpc can be called based on type of interface
1394
1395         try {
1396             List<Action> actions = Collections.emptyList();
1397             if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1398                 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1399                         itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1400                 if (!rpcResult.isSuccessful()) {
1401                     LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1402                             + "returned with Errors {}", ifName, rpcResult.getErrors());
1403                 } else {
1404                     actions = rpcResult.getResult().getAction();
1405                 }
1406             } else {
1407                 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1408                         odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1409                 if (!rpcResult.isSuccessful()) {
1410                     LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1411                             + "returned with Errors {}", ifName, rpcResult.getErrors());
1412                 } else {
1413                     actions = rpcResult.getResult().getAction();
1414                 }
1415             }
1416             List<ActionInfo> listActionInfo = new ArrayList<>();
1417             for (Action action : actions) {
1418                 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1419                     actionClass = action.getAction();
1420                 if (actionClass instanceof OutputActionCase) {
1421                     listActionInfo.add(new ActionOutput(pos++,
1422                         ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1423                 } else if (actionClass instanceof PushVlanActionCase) {
1424                     listActionInfo.add(new ActionPushVlan(pos++));
1425                 } else if (actionClass instanceof SetFieldCase) {
1426                     if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1427                         int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1428                             .getVlanId().getValue();
1429                         listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1430                     }
1431                 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1432                     Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1433                     listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1434                 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1435                     NxRegLoad nxRegLoad =
1436                         ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1437                     listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1438                         nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1439                 }
1440             }
1441             return listActionInfo;
1442         } catch (InterruptedException | ExecutionException e) {
1443             LOG.error("Exception when egress actions for interface {}", ifName, e);
1444         }
1445         LOG.error("Error when getting egress actions for interface {}", ifName);
1446         return Collections.emptyList();
1447     }
1448
1449     public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1450         return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1451     }
1452
1453     @Nonnull
1454     public static List<Port> getNeutronPorts(DataBroker broker) {
1455         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1456             portsIdentifier = InstanceIdentifier.create(Neutron.class)
1457             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1458         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1459                 portsOptional =
1460                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1461                         LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1462
1463         if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1464             LOG.error("getNeutronPorts : No neutron ports found");
1465             return Collections.emptyList();
1466         }
1467
1468         return portsOptional.get().getPort();
1469     }
1470
1471     public static Port getNeutronPortForIp(DataBroker broker,
1472                                            IpAddress targetIP, String deviceType) {
1473         List<Port> ports = getNeutronPorts(
1474             broker);
1475
1476         for (Port port : ports) {
1477             if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1478                 for (FixedIps ip : port.getFixedIps()) {
1479                     if (Objects.equals(ip.getIpAddress(), targetIP)) {
1480                         return port;
1481                     }
1482                 }
1483             }
1484         }
1485         LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1486         return null;
1487     }
1488
1489     public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1490         if (port == null) {
1491             LOG.error("getSubnetIdForFloatingIp : port is null");
1492             return null;
1493         }
1494         for (FixedIps ip : port.getFixedIps()) {
1495             if (Objects.equals(ip.getIpAddress(), targetIP)) {
1496                 return ip.getSubnetId();
1497             }
1498         }
1499         LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1500         return null;
1501     }
1502
1503     public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1504         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1505             .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1506         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1507                 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1508     }
1509
1510     @Nonnull
1511     public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1512         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1513             .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1514         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1515                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1516                 Collections.emptyList());
1517     }
1518
1519     public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1520         if (subnetId == null) {
1521             LOG.error("getSubnetGwMac : subnetID is null");
1522             return null;
1523         }
1524
1525         InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1526             .child(Subnet.class, new SubnetKey(subnetId));
1527         Optional<Subnet> subnetOpt =
1528                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1529                         LogicalDatastoreType.CONFIGURATION, subnetInst);
1530         if (!subnetOpt.isPresent()) {
1531             LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1532             return null;
1533         }
1534
1535         IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1536         if (gatewayIp == null) {
1537             LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1538             return null;
1539         }
1540
1541         if (null != gatewayIp.getIpv6Address()) {
1542             return null;
1543         }
1544
1545         InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1546             .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1547             .build();
1548         Optional<VpnPortipToPort> portIpToPortOpt =
1549                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1550                         LogicalDatastoreType.CONFIGURATION, portIpInst);
1551         if (portIpToPortOpt.isPresent()) {
1552             return portIpToPortOpt.get().getMacAddress();
1553         }
1554
1555         InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1556             .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1557             .build();
1558         Optional<LearntVpnVipToPort> learntIpToPortOpt =
1559                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1560                         LogicalDatastoreType.OPERATIONAL, learntIpInst);
1561         if (learntIpToPortOpt.isPresent()) {
1562             return learntIpToPortOpt.get().getMacAddress();
1563         }
1564
1565         LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1566         return null;
1567     }
1568
1569     public static boolean isIPv6Subnet(String prefix) {
1570         return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1571     }
1572
1573     static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1574         return InstanceIdentifier.builder(DpnRouters.class)
1575             .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1576     }
1577
1578     static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1579         return InstanceIdentifier.builder(NeutronRouterDpns.class)
1580             .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1581             .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1582     }
1583
1584     static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1585         return InstanceIdentifier.builder(NeutronRouterDpns.class)
1586             .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1587     }
1588
1589     protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1590         InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1591         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1592                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1593                 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1594     }
1595
1596     protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1597         InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1598         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1599                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1600                 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1601     }
1602
1603     static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1604         return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1605             FloatingIpIdToPortMappingKey(floatingIpId)).build();
1606     }
1607
1608     static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1609         InstanceIdentifier<Interface> ifStateId =
1610             buildStateInterfaceId(interfaceName);
1611         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1612                 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1613     }
1614
1615     static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1616         InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1617             InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1618                 .interfaces.rev140508.InterfacesState.class)
1619                 .child(Interface.class,
1620                     new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1621                         .interfaces.state.InterfaceKey(interfaceName));
1622         InstanceIdentifier<Interface> id = idBuilder.build();
1623         return id;
1624     }
1625
1626     public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1627         InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1628         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1629                 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1630     }
1631
1632     @Nullable
1633     public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1634         try {
1635             return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1636         } catch (InterruptedException | ExecutionException e) {
1637             LOG.error("Error reading router {}", routerName, e);
1638             return null;
1639         }
1640     }
1641
1642     static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1643         if (routerId == NatConstants.INVALID_ID) {
1644             LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1645             return;
1646         }
1647         RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1648             .setRouterId(routerId).setRouterName(routerName).build();
1649         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1650     }
1651
1652     static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1653             IdManagerService idManager) {
1654         InetAddress defaultIP = null;
1655         try {
1656             defaultIP = InetAddress.getByName("0.0.0.0");
1657         } catch (UnknownHostException e) {
1658             LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1659                     + "Default Route to NAT.", e);
1660             return null;
1661         }
1662
1663         List<MatchInfo> matches = new ArrayList<>();
1664         matches.add(MatchEthernetType.IPV4);
1665         //add match for vrfid
1666         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1667
1668         List<InstructionInfo> instructions = new ArrayList<>();
1669         List<ActionInfo> actionsInfo = new ArrayList<>();
1670         long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1671         actionsInfo.add(new ActionGroup(groupId));
1672         String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1673         instructions.add(new InstructionApplyActions(actionsInfo));
1674         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1675                 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1676                 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1677         return flowEntity;
1678     }
1679
1680     static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1681         String routerName = getRouterName(broker, routerId);
1682         if (routerName == null) {
1683             LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1684             return null;
1685         }
1686         return getExtGwMacAddFromRouterName(broker, routerName);
1687     }
1688
1689     static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1690         InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1691         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1692                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1693     }
1694
1695     @Nullable
1696     static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1697         try {
1698             return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1699                 Routers::getExtGwMacAddress).orElse(null);
1700         } catch (InterruptedException | ExecutionException e) {
1701             LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1702             return null;
1703         }
1704     }
1705
1706     static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1707         InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1708              .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1709              .child(Router.class, new RouterKey(routerUuid));
1710         return routerInstanceIdentifier;
1711     }
1712
1713     public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1714         InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1715         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1716                 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1717                 null);
1718     }
1719
1720     @Nonnull
1721     public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1722         InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1723         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1724                 LogicalDatastoreType.CONFIGURATION,
1725                 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(Collections.emptyList());
1726     }
1727
1728     @Nonnull
1729     public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1730         InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1731         Optional<ExternalNetworks> externalNwData =
1732                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1733                         LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1734         if (externalNwData.isPresent()) {
1735             for (Networks externalNw : externalNwData.get().getNetworks()) {
1736                 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1737                     return externalNw.getRouterIds();
1738                 }
1739             }
1740         }
1741         return Collections.emptyList();
1742     }
1743
1744     public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1745
1746         try {
1747             long ipLo = ipToLong(InetAddress.getByName(start));
1748             long ipHi = ipToLong(InetAddress.getByName(end));
1749             long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1750             return ipToTest >= ipLo && ipToTest <= ipHi;
1751         } catch (UnknownHostException e) {
1752             LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1753             return false;
1754         }
1755     }
1756
1757     @Nonnull
1758     public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1759         if (externalIps == null) {
1760             return Collections.emptySet();
1761         }
1762
1763         return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1764     }
1765
1766     @Nonnull
1767     public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1768         if (routerName == null) {
1769             LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1770             return Collections.emptySet();
1771         }
1772
1773         InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1774         Optional<Routers> routerData =
1775                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1776                         LogicalDatastoreType.CONFIGURATION, id);
1777         if (routerData.isPresent()) {
1778             return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1779         } else {
1780             LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1781             return Collections.emptySet();
1782         }
1783     }
1784
1785     @Nonnull
1786     protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1787         .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1788         if (subnetId == null) {
1789             LOG.warn("getOptionalExternalSubnets : subnetId is null");
1790             return Optional.absent();
1791         }
1792
1793         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1794             .rev160111.external.subnets.Subnets> subnetsIdentifier =
1795                 InstanceIdentifier.builder(ExternalSubnets.class)
1796                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1797                         .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1798         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1799                 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1800     }
1801
1802     @Nonnull
1803     protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1804         .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1805         if (subnetId == null) {
1806             LOG.warn("getOptionalExternalSubnets : subnetId is null");
1807             return Optional.absent();
1808         }
1809
1810         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1811             .rev160111.external.subnets.Subnets> subnetsIdentifier =
1812             InstanceIdentifier.builder(ExternalSubnets.class)
1813                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1814                     .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1815         try {
1816             return tx.read(subnetsIdentifier).get();
1817         } catch (InterruptedException | ExecutionException e) {
1818             LOG.error("Error retrieving external subnets on {}", subnetId, e);
1819             return Optional.absent();
1820         }
1821     }
1822
1823     protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1824         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1825             .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1826                    subnetId);
1827         if (optionalExternalSubnets.isPresent()) {
1828             return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1829         }
1830
1831         return NatConstants.INVALID_ID;
1832     }
1833
1834     protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1835         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1836             .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1837             subnetId);
1838         if (optionalExternalSubnets.isPresent()) {
1839             return NatUtil.getVpnId(tx, subnetId.getValue());
1840         }
1841
1842         return NatConstants.INVALID_ID;
1843     }
1844
1845     protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1846             Routers router) {
1847         Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1848         if (externalSubnetId != null) {
1849             return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1850         }
1851
1852         return NatConstants.INVALID_ID;
1853     }
1854
1855     protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1856         externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1857         List<ExternalIps> externalIps = router.getExternalIps();
1858         for (ExternalIps extIp : externalIps) {
1859             String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1860             if (extIpString.equals(externalIpAddress)) {
1861                 return extIp.getSubnetId();
1862             }
1863         }
1864         LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1865         return null;
1866     }
1867
1868     private static long ipToLong(InetAddress ip) {
1869         byte[] octets = ip.getAddress();
1870         long result = 0;
1871         for (byte octet : octets) {
1872             result <<= 8;
1873             result |= octet & 0xff;
1874         }
1875         return result;
1876     }
1877
1878     @Nonnull
1879     static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1880         if (externalIps == null) {
1881             return Collections.emptyList();
1882         }
1883
1884         return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1885     }
1886
1887     // elan-instances config container
1888     public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1889         InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1890         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1891                 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1892     }
1893
1894     @Nullable
1895     public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1896         try {
1897             return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1898         } catch (InterruptedException | ExecutionException e) {
1899             LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1900             return null;
1901         }
1902     }
1903
1904     public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1905         return InstanceIdentifier.builder(ElanInstances.class)
1906                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1907     }
1908
1909     public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1910             IdManagerService idManager, long routerId, String routerName) {
1911         if (elanManager.isOpenStackVniSemanticsEnforced()) {
1912             // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1913             return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1914         } else {
1915             return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1916         }
1917     }
1918
1919     public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1920             short tableId, WriteTransaction writeFlowTx) {
1921         LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1922                 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1923
1924         List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1925         preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1926         List<MatchInfo> matches = new ArrayList<>();
1927         matches.add(MatchEthernetType.IPV4);
1928         String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1929         Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1930                 5, flowRef, 0, 0,  NwConstants.COOKIE_DNAT_TABLE,
1931                 matches, preDnatToSnatInstructions);
1932
1933         mdsalManager.addFlowToTx(naptDpnId, preDnatToSnatTableFlowEntity, writeFlowTx);
1934         LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1935                 preDnatToSnatTableFlowEntity,  naptDpnId);
1936     }
1937
1938     public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1939                                                      WriteTransaction removeFlowInvTx) {
1940         LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1941                 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1942         String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1943         Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1944                 5, flowRef, 0, 0,  NwConstants.COOKIE_DNAT_TABLE, null, null);
1945         mdsalManager.removeFlowToTx(naptDpnId, preDnatToSnatTableFlowEntity, removeFlowInvTx);
1946         LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1947                 preDnatToSnatTableFlowEntity, naptDpnId);
1948     }
1949
1950     private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1951         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1952                 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1953     }
1954
1955     public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1956                                                     String vpnName, String externalIp,
1957                                                     Boolean isMoreThanOneFipCheckOnDpn) {
1958         InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1959         Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1960         if (dpnInVpn.isPresent()) {
1961             LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1962                     + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
1963             try {
1964                 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1965                 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1966                     int floatingIpPresentCount = 0;
1967                     for (IpAddresses ipAddress: ipAddressList) {
1968                         if (!ipAddress.getIpAddress().equals(externalIp)
1969                                 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1970                             floatingIpPresentCount++;
1971                             //Add tunnel table check
1972                             if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1973                                 return Boolean.TRUE;
1974                             }
1975                             //Remove tunnel table check
1976                             if (!isMoreThanOneFipCheckOnDpn) {
1977                                 return Boolean.TRUE;
1978                             }
1979                         }
1980                     }
1981                 } else {
1982                     LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
1983                            dpnId);
1984                     return Boolean.FALSE;
1985                 }
1986             } catch (NullPointerException e) {
1987                 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
1988                         + "vpn-to-dpn-list on Dpn {}", dpnId, e);
1989                 return Boolean.FALSE;
1990             }
1991         }
1992         return Boolean.FALSE;
1993     }
1994
1995     private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1996         return InstanceIdentifier.builder(VpnInstanceOpData.class)
1997                 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1998                 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1999     }
2000
2001     @Nullable
2002     public static String getPrimaryRd(String vpnName, ReadTransaction tx) throws ReadFailedException {
2003         return tx.read(LogicalDatastoreType.CONFIGURATION,
2004                 getVpnInstanceIdentifier(vpnName)).checkedGet().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2005     }
2006
2007     public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
2008         InstanceIdentifier<VpnInstance> id  = getVpnInstanceIdentifier(vpnName);
2009         Optional<VpnInstance> vpnInstance =
2010                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2011                         LogicalDatastoreType.CONFIGURATION, id);
2012         if (vpnInstance.isPresent()) {
2013             return getPrimaryRd(vpnInstance.get());
2014         }
2015         return vpnName;
2016     }
2017
2018     public static String getPrimaryRd(VpnInstance vpnInstance) {
2019         List<String> rds = null;
2020         if (vpnInstance != null) {
2021             rds = getListOfRdsFromVpnInstance(vpnInstance);
2022         }
2023         return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2024     }
2025
2026     public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2027         return InstanceIdentifier.builder(VpnInstances.class)
2028             .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2029     }
2030
2031     @Nonnull
2032     public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2033         VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2034         return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2035                 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2036     }
2037
2038     public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
2039         if (routerName != null) {
2040             Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
2041             if (extRouter != null) {
2042                 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
2043             }
2044         }
2045
2046         return NatConstants.INVALID_ID;
2047     }
2048
2049     public static String validateAndAddNetworkMask(String ipAddress) {
2050         return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2051     }
2052
2053     public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2054             String vpnInterfaceName, String vpnName) {
2055         return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2056         new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2057     }
2058
2059     public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
2060         InstanceIdentifier<VpnInstanceOpDataEntry> id = NatUtil.getVpnInstanceOpDataIdentifier(rd);
2061         return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2062                  broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
2063     }
2064
2065     public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2066                                                                      String routerName, BigInteger dpnId) {
2067         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2068         Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2069
2070         if (networkData != null && networkData.isPresent()) {
2071             List<Uuid> routerUuidList = networkData.get().getRouterIds();
2072             if (routerUuidList != null && !routerUuidList.isEmpty()) {
2073                 for (Uuid routerUuid : routerUuidList) {
2074                     String sharedRouterName = routerUuid.getValue();
2075                     if (!routerName.equals(sharedRouterName)) {
2076                         BigInteger swtichDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2077                         if (swtichDpnId == null) {
2078                             continue;
2079                         } else if (swtichDpnId.equals(dpnId)) {
2080                             LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2081                                     + "associated with other active router {} on NAPT switch {}", networkId,
2082                                     sharedRouterName, swtichDpnId);
2083                             return true;
2084                         }
2085                     }
2086                 }
2087             }
2088         }
2089         return false;
2090     }
2091
2092     public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2093             Routers router, BigInteger primarySwitchId, int addOrRemove) {
2094         ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
2095             List<ExternalIps> externalIps = router.getExternalIps();
2096             List<String> externalIpsSting = new ArrayList<>();
2097
2098             if (externalIps.isEmpty()) {
2099                 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2100                 return;
2101             }
2102             for (ExternalIps externalIp : externalIps) {
2103                 externalIpsSting.add(externalIp.getIpAddress());
2104             }
2105             Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2106             if (addOrRemove == NwConstants.ADD_FLOW) {
2107                 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2108                         router.getNetworkId(), subnetVpnName.getValue(), tx);
2109                 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2110                         router.getExtGwMacAddress(), primarySwitchId,
2111                         router.getNetworkId(), tx);
2112             } else {
2113                 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2114                         router.getNetworkId(), subnetVpnName.getValue(), tx);
2115                 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2116                         router.getExtGwMacAddress(), primarySwitchId,
2117                         router.getNetworkId());
2118             }
2119         }), LOG, "Error installing router gateway flows");
2120     }
2121
2122     public static CheckedFuture<Void, TransactionCommitFailedException> waitForTransactionToComplete(
2123             WriteTransaction tx) {
2124         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
2125         try {
2126             futures.get();
2127         } catch (InterruptedException | ExecutionException e) {
2128             LOG.error("Error writing to datastore {}", e);
2129         }
2130         return futures;
2131     }
2132
2133     public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2134                                                                         ProviderTypes extNwProvType) {
2135         if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2136                 || extNwProvType == ProviderTypes.VXLAN)) {
2137             return true;
2138         }
2139         return false;
2140     }
2141
2142     public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2143             BigInteger dpnId, DataBroker dataBroker) {
2144         InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2145                 elanInstanceName,dpnId);
2146         try {
2147             synchronized (elanInstanceName.intern()) {
2148                 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2149                         LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2150                 List<String> elanInterfaceList;
2151                 DpnInterfaces dpnInterface;
2152                 if (!dpnInElanInterfaces.isPresent()) {
2153                     elanInterfaceList = new ArrayList<>();
2154                 } else {
2155                     dpnInterface = dpnInElanInterfaces.get();
2156                     elanInterfaceList = dpnInterface.getInterfaces();
2157                 }
2158                 if (!elanInterfaceList.contains(pseudoPortId)) {
2159                     elanInterfaceList.add(pseudoPortId);
2160                     dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2161                             .withKey(new DpnInterfacesKey(dpnId)).build();
2162                     SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2163                             elanDpnInterfaceId, dpnInterface);
2164                 }
2165             }
2166         } catch (ReadFailedException e) {
2167             LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2168         } catch (TransactionCommitFailedException e) {
2169             LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2170         }
2171     }
2172
2173     public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2174             BigInteger dpnId, DataBroker dataBroker) {
2175         InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2176                 elanInstanceName,dpnId);
2177         try {
2178             synchronized (elanInstanceName.intern()) {
2179                 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2180                         LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2181                 List<String> elanInterfaceList;
2182                 DpnInterfaces dpnInterface;
2183                 if (!dpnInElanInterfaces.isPresent()) {
2184                     LOG.info("No interface in any dpn for {}", elanInstanceName);
2185                     return;
2186                 } else {
2187                     dpnInterface = dpnInElanInterfaces.get();
2188                     elanInterfaceList = dpnInterface.getInterfaces();
2189                 }
2190                 if (!elanInterfaceList.contains(pseudoPortId)) {
2191                     LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2192                     return;
2193                 }
2194                 elanInterfaceList.remove(pseudoPortId);
2195                 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2196                         .withKey(new DpnInterfacesKey(dpnId)).build();
2197                 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2198                         elanDpnInterfaceId, dpnInterface);
2199             }
2200         } catch (ReadFailedException e) {
2201             LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2202         } catch (TransactionCommitFailedException e) {
2203             LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2204         }
2205
2206     }
2207
2208     public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId,
2209             DataBroker broker) {
2210         InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId =
2211                 getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
2212         DpnInterfaces dpnInterfaces = null;
2213         try {
2214             dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL,
2215                     elanDpnInterfacesId);
2216         }
2217         catch (ReadFailedException e) {
2218             LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
2219         }
2220         return dpnInterfaces;
2221     }
2222
2223     public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
2224             InstanceIdentifier<T> path) {
2225         try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
2226             return tx.read(datastoreType, path).get();
2227         } catch (InterruptedException | ExecutionException e) {
2228             throw new RuntimeException(e);
2229         }
2230     }
2231
2232     public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2233         Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2234         for (Map.Entry<String,Routers> router : extRouter) {
2235             if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2236                     .equals(networkid)) {
2237                 return false;
2238             }
2239         }
2240         return true;
2241     }
2242
2243     public static InstanceIdentifier<ExtRouters> buildExtRouters() {
2244         InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
2245                 .build();
2246         return extRouterInstanceIndentifier;
2247     }
2248
2249     public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2250         InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = getLearntVpnVipToPortDataId();
2251         LearntVpnVipToPortData learntVpnVipToPortData = null;
2252         try {
2253             learntVpnVipToPortData = SingleTransactionDataBroker.syncRead(dataBroker,
2254                     LogicalDatastoreType.OPERATIONAL, learntVpnVipToPortDataId);
2255         }
2256         catch (ReadFailedException e) {
2257             LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2258         }
2259         return learntVpnVipToPortData;
2260     }
2261
2262     public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2263         InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2264                 .builder(LearntVpnVipToPortData.class).build();
2265         return learntVpnVipToPortDataId;
2266     }
2267
2268     public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2269             BigInteger dpId) {
2270         return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2271                 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2272                 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2273     }
2274
2275     public static void createGroupIdPool(IdManagerService idManager) {
2276         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2277                 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2278                 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2279                 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2280                 .build();
2281         try {
2282             Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2283             if (result != null && result.get().isSuccessful()) {
2284                 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2285             } else {
2286                 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2287             }
2288         } catch (InterruptedException | ExecutionException e) {
2289             LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2290         }
2291     }
2292 }