d167eda578dbf24807b5b1d290bded5f56731adc
[netvirt.git] /
1 /*
2  * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.natservice.internal;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import java.math.BigInteger;
15 import java.net.InetAddress;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Objects;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.Future;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
26 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.genius.mdsalutil.ActionInfo;
29 import org.opendaylight.genius.mdsalutil.FlowEntity;
30 import org.opendaylight.genius.mdsalutil.MDSALUtil;
31 import org.opendaylight.genius.mdsalutil.MatchInfo;
32 import org.opendaylight.genius.mdsalutil.NwConstants;
33 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
34 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
35 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
36 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
37 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
38 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
39 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
40 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
41 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
42 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
43 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
44 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
131 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;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
165 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;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
167 import org.opendaylight.yangtools.yang.binding.DataObject;
168 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
169 import org.opendaylight.yangtools.yang.common.RpcResult;
170 import org.slf4j.Logger;
171 import org.slf4j.LoggerFactory;
172
173 public class NatUtil {
174
175     private static String OF_URI_SEPARATOR = ":";
176     private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
177
178     /*
179      getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
180       reference value.
181      */
182     public static BigInteger getCookieSnatFlow(long routerId) {
183         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
184             BigInteger.valueOf(routerId));
185     }
186
187     /*
188       getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
189        reference value.
190     */
191     public static BigInteger getCookieNaptFlow(long routerId) {
192         return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
193             BigInteger.valueOf(routerId));
194     }
195
196     /*
197         getVpnId() returns the VPN ID from the VPN name
198      */
199     public static long getVpnId(DataBroker broker, String vpnName) {
200         if (vpnName == null) {
201             return NatConstants.INVALID_ID;
202         }
203
204         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
205             .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
206         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
207             .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
208
209         long vpnId = NatConstants.INVALID_ID;
210         if (vpnInstance.isPresent()) {
211             Long vpnIdAsLong = vpnInstance.get().getVpnId();
212             if (vpnIdAsLong != null) {
213                 vpnId = vpnIdAsLong;
214             }
215         }
216         return vpnId;
217     }
218
219     public static Long getVpnId(DataBroker broker, long routerId) {
220         //Get the external network ID from the ExternalRouter model
221         Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
222         if (networkId == null) {
223             LOG.error("NAT Service : networkId is null");
224             return null;
225         }
226
227         //Get the VPN ID from the ExternalNetworks model
228         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
229         if (vpnUuid == null) {
230             LOG.error("NAT Service : vpnUuid is null");
231             return null;
232         }
233         Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
234         return vpnId;
235     }
236
237     static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
238         return InstanceIdentifier.builder(FloatingIpInfo.class)
239             .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
240     }
241
242     static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
243         return InstanceIdentifier.builder(RouterToVpnMapping.class)
244             .child(Routermapping.class, new RoutermappingKey(routerId)).build();
245     }
246
247     static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
248         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
249             .child(Ports.class, new PortsKey(portName)).build();
250     }
251
252     static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
253                                                                                     String internalIp) {
254         return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
255             .child(Ports.class, new PortsKey(portName))
256             .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
257     }
258
259     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
260         .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
261         return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
262             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
263                     .instance.to.vpn.id.VpnInstance.class,
264                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
265                     .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
266     }
267
268     static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
269         InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
270             .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
271         Optional<VpnIds> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
272         return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : null;
273     }
274
275     /*
276        getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
277     */
278     public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
279         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
280                 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
281     }
282
283     public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix) {
284         return NatConstants.FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants
285                 .FLOWID_SEPARATOR + destPrefix.getHostAddress();
286     }
287
288     public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
289         return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
290                 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
291                 + port;
292     }
293
294     /*
295         getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key
296                container ext-routers {
297                    list routers {
298                        key router-name;
299                        leaf router-name { type string; }
300                        leaf network-id { type yang:uuid; }
301                        leaf enable-snat { type boolean; }
302                        leaf-list external-ips {
303                             type string; //format - ipaddress\prefixlength
304                        }
305                        leaf-list subnet-ids { type yang:uuid; }
306                    }
307                }
308
309     */
310     static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
311         String routerName = getRouterName(broker, routerId);
312         return getNetworkIdFromRouterName(broker, routerName);
313     }
314
315     static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
316         if (routerName == null) {
317             LOG.error("getNetworkIdFromRouterName - empty routerName received");
318             return null;
319         }
320         InstanceIdentifier id = buildRouterIdentifier(routerName);
321         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
322         if (routerData.isPresent()) {
323             return routerData.get().getNetworkId();
324         }
325         return null;
326     }
327
328     static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
329         InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
330             .child(Routers.class, new RoutersKey(routerId)).build();
331         return routerInstanceIndentifier;
332     }
333
334     private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
335         InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
336             .child(RouterIds.class, new RouterIdsKey(routerId)).build();
337         return routerIds;
338     }
339
340     /**
341      * Return if SNAT is enabled for the given router.
342      *
343      * @param broker   The DataBroker
344      * @param routerId The router
345      * @return boolean true if enabled, otherwise false
346      */
347     static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
348         InstanceIdentifier id = buildRouterIdentifier(routerId);
349         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
350         if (routerData.isPresent()) {
351             return routerData.get().isEnableSnat();
352         }
353         return false;
354     }
355
356     /*
357         getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key.
358             container external-networks {
359                 list networks  {
360                     key id;
361                     leaf id {
362                         type yang:uuid;
363                     }
364                     leaf vpnid { type yang:uuid; }
365                     leaf-list router-ids { type yang:uuid; }
366                     leaf-list subnet-ids{ type yang:uuid; }
367                 }
368             }
369     */
370
371     public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
372         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
373         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
374         if (networkData.isPresent()) {
375             return networkData.get().getVpnid();
376         }
377         return null;
378     }
379
380     public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
381         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
382         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
383         if ((networkData.isPresent()) && (networkData.get() != null)) {
384             return networkData.get().getProviderNetworkType();
385         }
386         return null;
387     }
388
389     public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
390         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
391         Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
392         return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList();
393     }
394
395     static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
396         InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
397         Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
398         if (routerData.isPresent()) {
399             Uuid networkId = routerData.get().getNetworkId();
400             if (networkId != null) {
401                 return networkId.getValue();
402             }
403         }
404         return null;
405     }
406
407     private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
408         InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class)
409             .child(Networks.class, new NetworksKey(networkId)).build();
410         return network;
411     }
412
413     /*
414         getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id
415          in a array using the router-id; as the key.
416             container napt-switches {
417                 list router-to-napt-switch {
418                     key router-id;
419                     leaf router-id { type uint32; }
420                     leaf primary-switch-id { type uint64; }
421                     leaf secondary-switch-id { type uint64; }
422                 }
423             }
424     */
425
426     public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
427         // convert routerId to Name
428         String routerName = getRouterName(broker, routerId);
429         return getPrimaryNaptfromRouterName(broker, routerName);
430     }
431
432     public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
433         if (routerName == null) {
434             LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
435             return null;
436         }
437         InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
438         Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
439         if (routerToNaptSwitchData.isPresent()) {
440             RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
441             return routerToNaptSwitchInstance.getPrimarySwitchId();
442         }
443         return null;
444     }
445
446     private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
447         InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
448             .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
449         return rtrNaptSw;
450     }
451
452     public static String getRouterName(DataBroker broker, Long routerId) {
453         InstanceIdentifier id = buildRouterIdentifier(routerId);
454         Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
455         if (routerIdsData.isPresent()) {
456             RouterIds routerIdsInstance = routerIdsData.get();
457             return routerIdsInstance.getRouterName();
458         }
459         return null;
460     }
461
462     // TODO Clean up the exception handling
463     @SuppressWarnings("checkstyle:IllegalCatch")
464     public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
465                                                           InstanceIdentifier<T> path) {
466
467         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
468
469         try {
470             return tx.read(datastoreType, path).get();
471         } catch (Exception e) {
472             throw new RuntimeException(e);
473         }
474     }
475
476     static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
477         return InstanceIdentifier.builder(VpnInstanceOpData.class)
478             .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
479     }
480
481     public static long readVpnId(DataBroker broker, String vpnName) {
482
483         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
484             .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
485         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
486             .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
487
488         long vpnId = NatConstants.INVALID_ID;
489         if (vpnInstance.isPresent()) {
490             vpnId = vpnInstance.get().getVpnId();
491         }
492         return vpnId;
493     }
494
495     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
496         FlowEntity flowEntity = new FlowEntity(dpnId);
497         flowEntity.setTableId(tableId);
498         flowEntity.setCookie(cookie);
499         return flowEntity;
500     }
501
502     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId,
503                                              int priority, String flowName,
504                                              BigInteger cookie, List<MatchInfo> listMatchInfo) {
505
506         FlowEntity flowEntity = new FlowEntity(dpnId);
507         flowEntity.setTableId(tableId);
508         flowEntity.setFlowId(flowId);
509         flowEntity.setPriority(priority);
510         flowEntity.setFlowName(flowName);
511         flowEntity.setCookie(cookie);
512         flowEntity.setMatchInfoList(listMatchInfo);
513         return flowEntity;
514     }
515
516     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
517         FlowEntity flowEntity = new FlowEntity(dpnId);
518         flowEntity.setTableId(tableId);
519         flowEntity.setCookie(cookie);
520         flowEntity.setFlowId(flowId);
521         return flowEntity;
522     }
523
524     public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
525         FlowEntity flowEntity = new FlowEntity(dpnId);
526         flowEntity.setTableId(tableId);
527         flowEntity.setFlowId(flowId);
528         return flowEntity;
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 = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
542         if (tunnelInfo.isPresent()) {
543             List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
544             if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
545                 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
546             }
547         }
548         return nextHopIp;
549     }
550
551     /*
552         getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName
553             list vpn-instance {
554                 key "vpn-instance-name"
555                 leaf vpn-instance-name {
556                     type string;
557                 }
558                 leaf vpn-id {
559                     type uint32;
560                 }
561                 leaf vrf-id {
562                     type string;
563                 }
564             }
565     */
566     public static String getVpnRd(DataBroker broker, String vpnName) {
567
568         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
569             .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
570         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
571             .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
572
573         String rd = null;
574         if (vpnInstance.isPresent()) {
575             rd = vpnInstance.get().getVrfId();
576         }
577         return rd;
578     }
579
580     /*  getExternalIPPortMap() returns the internal IP and the port for the querried router ID,
581      external IP and the port.
582         container intext-ip-port-map {
583         config true;
584         list ip-port-mapping {
585             key router-id;
586             leaf router-id { type uint32; }
587             list intext-ip-protocol-type {
588                 key protocol;
589                 leaf protocol { type protocol-types; }
590                 list ip-port-map {
591                     key ip-port-internal;
592                     description "internal to external ip-port mapping";
593                     leaf ip-port-internal { type string; }
594                     container ip-port-external {
595                        uses ip-port-entity;
596                     }
597                 }
598             }
599          }
600        }
601     */
602
603     public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
604                                                       String internalPort, NAPTEntryEvent.Protocol protocol) {
605         ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
606         InstanceIdentifier ipPortMapId =
607             buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
608         Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
609         if (ipPortMapData.isPresent()) {
610             IpPortMap ipPortMapInstance = ipPortMapData.get();
611             return ipPortMapInstance.getIpPortExternal();
612         }
613         return null;
614     }
615
616     private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
617                                                                             String internalPort,
618                                                                             ProtocolTypes protocolType) {
619         InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class)
620             .child(IpPortMapping.class, new IpPortMappingKey(routerId))
621             .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
622             .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
623         return ipPortMapId;
624     }
625
626     static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
627         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
628         return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
629     }
630
631     static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
632         return InstanceIdentifier.builder(VpnInterfaces.class)
633             .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
634     }
635
636     static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
637         InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
638         return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
639     }
640
641     public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
642         /*
643          * NodeConnectorId is of form 'openflow:dpnid:portnum'
644          */
645         String[] split = portId.getValue().split(OF_URI_SEPARATOR);
646         if (split == null || split.length != 3) {
647             return null;
648         }
649         return split[1];
650     }
651
652     public static BigInteger getDpIdFromInterface(
653         org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
654             .state.Interface ifState) {
655         String lowerLayerIf = ifState.getLowerLayerIf().get(0);
656         NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
657         return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
658     }
659
660     /*
661     container vpnMaps {
662         list vpnMap {
663             key vpn-id;
664             leaf vpn-id {
665                 type    yang:uuid;
666                 description "vpn-id";
667             }
668             leaf name {
669                 type  string;
670                 description "vpn name";
671             }
672             leaf tenant-id {
673                 type    yang:uuid;
674                 description "The UUID of the tenant that will own the subnet.";
675             }
676
677             leaf router-id {
678               type    yang:uuid;
679               description "UUID of router ";
680             }
681             leaf-list network_ids {
682               type    yang:uuid;
683               description "UUID representing the network ";
684             }
685         }
686     }
687     Method returns router Id associated to a VPN
688      */
689
690     public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
691         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
692             .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
693         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
694             vpnMapIdentifier);
695         if (optionalVpnMap.isPresent()) {
696             Uuid routerId = optionalVpnMap.get().getRouterId();
697             if (routerId != null) {
698                 return routerId.getValue();
699             }
700         }
701         return null;
702     }
703
704     static Uuid getVpnForRouter(DataBroker broker, String routerId) {
705         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
706         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
707             vpnMapsIdentifier);
708         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
709             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
710             if (routerId != null) {
711                 for (VpnMap vpnMap : allMaps) {
712                     if (vpnMap.getRouterId() != null
713                         && routerId.equals(vpnMap.getRouterId().getValue())
714                         && !routerId.equals(vpnMap.getVpnId().getValue())) {
715                         return vpnMap.getVpnId();
716                     }
717                 }
718             }
719         }
720         return null;
721     }
722
723     static long getAssociatedVpn(DataBroker broker, String routerName) {
724         InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
725         Optional<Routermapping> optRouterMapping =
726             NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
727         if (optRouterMapping.isPresent()) {
728             Routermapping routerMapping = optRouterMapping.get();
729             return routerMapping.getVpnId();
730         }
731         return NatConstants.INVALID_ID;
732     }
733
734     public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
735         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
736         if (vpnUuid == null) {
737             log.error("No VPN instance associated with ext network {}", networkId);
738             return null;
739         }
740         return vpnUuid.getValue();
741     }
742
743     // TODO Clean up the exception handling
744     @SuppressWarnings("checkstyle:IllegalCatch")
745     public static void addPrefixToBGP(DataBroker broker,
746                                       IBgpManager bgpManager,
747                                       IFibManager fibManager,
748                                       String rd,
749                                       String prefix,
750                                       String nextHopIp,
751                                       long label,
752                                       Logger log,
753                                       RouteOrigin origin) {
754         try {
755             LOG.info("ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label);
756             if (nextHopIp == null) {
757                 log.error("addPrefix failed since nextHopIp cannot be null.");
758                 return;
759             }
760             fibManager.addOrUpdateFibEntry(broker, rd, prefix, Collections.singletonList(nextHopIp), (int) label,
761                     origin, null);
762             bgpManager.advertisePrefix(rd, prefix, Collections.singletonList(nextHopIp), (int) label);
763             LOG.info("ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label);
764         } catch (Exception e) {
765             log.error("Add prefix failed", e);
766         }
767     }
768
769     static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
770         InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
771             .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
772         return ipPortMapId;
773     }
774
775     static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
776         InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
777             .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
778         return routerInstanceIndentifier;
779     }
780
781     /* container snatint-ip-port-map {
782         list intip-port-map {
783             key router-id;
784             leaf router-id { type uint32; }
785             list ip-port {
786                 key internal-ip;
787                 leaf internal-ip { type string; }
788                 list int-ip-proto-type {
789                     key protocol;
790                     leaf protocol { type protocol-types; }
791                     leaf-list ports { type uint16; }
792                 }
793             }
794         }
795     }
796     Method returns InternalIp port List
797     */
798
799     public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
800                                                           String internalIpAddress, ProtocolTypes protocolType) {
801         Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION,
802             buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
803         if (optionalIpProtoType.isPresent()) {
804             return optionalIpProtoType.get().getPorts();
805         }
806         return null;
807     }
808
809     public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
810                                                                                   String internalIpAddress,
811                                                                                   ProtocolTypes protocolType) {
812         InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
813             InstanceIdentifier.builder(SnatintIpPortMap.class)
814                 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
815                 .child(IpPort.class, new IpPortKey(internalIpAddress))
816                 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
817         return intIpProtocolTypeId;
818     }
819
820     public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
821         ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
822             ? ProtocolTypes.TCP : ProtocolTypes.UDP;
823         return protocolType;
824     }
825
826     public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
827         return InstanceIdentifier.create(NaptSwitches.class);
828     }
829
830     public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
831         return InstanceIdentifier.create(NaptSwitches.class)
832             .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
833     }
834
835     public static String getGroupIdKey(String routerName) {
836         return "snatmiss." + routerName;
837     }
838
839     public static long createGroupId(String groupIdKey, IdManagerService idManager) {
840         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
841             .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
842             .build();
843         try {
844             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
845             RpcResult<AllocateIdOutput> rpcResult = result.get();
846             return rpcResult.getResult().getIdValue();
847         } catch (NullPointerException | InterruptedException | ExecutionException e) {
848             LOG.trace("", e);
849         }
850         return 0;
851     }
852
853     // TODO Clean up the exception handling
854     @SuppressWarnings("checkstyle:IllegalCatch")
855     public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager,
856                                            String rd, String prefix, Logger log) {
857         try {
858             LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
859             fibManager.removeFibEntry(broker, rd, prefix, null);
860             bgpManager.withdrawPrefix(rd, prefix);
861             LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
862         } catch (Exception e) {
863             log.error("Delete prefix failed", e);
864         }
865     }
866
867     public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
868         return read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
869     }
870
871     public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
872         return InstanceIdentifier.builder(IntextIpPortMap.class)
873             .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
874     }
875
876     public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
877         .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
878         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
879             .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
880             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
881                 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
882                 .intext.ip.map.IpMappingKey(routerId)).build();
883         return idBuilder;
884     }
885
886     public static List<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
887         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
888             .ip.map.IpMapping> ipMappingOptional =
889             read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
890         List<String> externalIps = new ArrayList<>();
891         if (ipMappingOptional.isPresent()) {
892             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
893             for (IpMap ipMap : ipMaps) {
894                 externalIps.add(ipMap.getExternalIp());
895             }
896             //remove duplicates
897             return new ArrayList<>(new HashSet<>(externalIps));
898         }
899         return null;
900     }
901
902     public static List<String> getExternalIpsFromRouter(DataBroker dataBroker, String routerName) {
903         Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
904         return (routerData != null) ? routerData.getExternalIps() : Collections.emptyList();
905     }
906
907     public static HashMap<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
908         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
909             .ip.map.IpMapping> ipMappingOptional =
910             read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
911         HashMap<String, Long> externalIpsLabel = new HashMap<>();
912         if (ipMappingOptional.isPresent()) {
913             List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
914             for (IpMap ipMap : ipMaps) {
915                 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
916             }
917             return externalIpsLabel;
918         }
919         return null;
920     }
921     /*
922     container external-ips-counter {
923         config false;
924         list external-counters{
925             key segment-id;
926             leaf segment-id { type uint32; }
927             list external-ip-counter {
928                 key external-ip;
929                 leaf external-ip { type string; }
930                 leaf counter { type uint8; }
931             }
932         }
933     }
934     */
935
936     public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
937         String leastLoadedExternalIp = null;
938         InstanceIdentifier<ExternalCounters> id =
939             InstanceIdentifier.builder(ExternalIpsCounter.class)
940                 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
941         Optional<ExternalCounters> externalCountersData =
942             MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
943         if (externalCountersData.isPresent()) {
944             ExternalCounters externalCounter = externalCountersData.get();
945             List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
946             short countOfLstLoadExtIp = 32767;
947             for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
948                 String curExternalIp = externalIpCounter.getExternalIp();
949                 short countOfCurExtIp = externalIpCounter.getCounter();
950                 if (countOfCurExtIp < countOfLstLoadExtIp) {
951                     countOfLstLoadExtIp = countOfCurExtIp;
952                     leastLoadedExternalIp = curExternalIp;
953                 }
954             }
955         }
956         return leastLoadedExternalIp;
957     }
958
959     public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
960         String subnetIP = getSubnetIp(dataBroker, subnetId);
961         if (subnetIP != null) {
962             return getSubnetIpAndPrefix(subnetIP);
963         }
964         return null;
965     }
966
967     public static String[] getSubnetIpAndPrefix(String subnetString) {
968         String[] subnetSplit = subnetString.split("/");
969         String subnetIp = subnetSplit[0];
970         String subnetPrefix = "0";
971         if (subnetSplit.length == 2) {
972             subnetPrefix = subnetSplit[1];
973         }
974         return new String[] {subnetIp, subnetPrefix};
975     }
976
977     public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
978         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
979             .builder(Subnetmaps.class)
980             .child(Subnetmap.class, new SubnetmapKey(subnetId))
981             .build();
982         Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
983         if (removedSubnet.isPresent()) {
984             Subnetmap subnetMapEntry = removedSubnet.get();
985             return subnetMapEntry.getSubnetIp();
986         }
987         return null;
988
989     }
990
991     public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
992         String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
993         String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
994         String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
995         if (leastLoadedExtIpAddrSplit.length == 2) {
996             leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
997         }
998         return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
999     }
1000
1001     public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1002         InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1003             .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1004         Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1005         List<BigInteger> dpns = new ArrayList<>();
1006         if (routerDpnListData.isPresent()) {
1007             List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
1008             for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
1009                 dpns.add(dpnVpnInterface.getDpnId());
1010             }
1011             return dpns;
1012         }
1013         return null;
1014     }
1015
1016     public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1017         long bgpVpnId = NatConstants.INVALID_ID;
1018         Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1019         if (bgpVpnUuid != null) {
1020             bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1021         }
1022         return bgpVpnId;
1023     }
1024
1025     static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1026         .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1027         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router
1028             .interfaces.RouterInterface> optRouterInterface =
1029             read(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName));
1030         if (optRouterInterface.isPresent()) {
1031             return optRouterInterface.get();
1032         }
1033         return null;
1034     }
1035
1036     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1037         .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1038         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1039             .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1040             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1041                     .RouterInterface.class,
1042                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1043                     .RouterInterfaceKey(interfaceName)).build();
1044     }
1045
1046     static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1047                                           OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1048         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1049         if (dpId.equals(BigInteger.ZERO)) {
1050             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
1051                 interfaceName, routerName);
1052             return;
1053         }
1054
1055         LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the "
1056                 + "ODL-L3VPN : NeutronRouterDpn map",
1057             routerName, dpId, interfaceName);
1058         InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1059
1060         Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = read(broker, LogicalDatastoreType
1061             .OPERATIONAL, dpnVpnInterfacesListIdentifier);
1062         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1063             .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1064             new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1065                 .setInterface(interfaceName).build();
1066         if (optionalDpnVpninterfacesList.isPresent()) {
1067             LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the "
1068                 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1069             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
1070                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1071                         .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1072                     new RouterInterfacesKey(interfaceName)), routerInterface, true);
1073         } else {
1074             LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the "
1075                 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1076             RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1077             routerDpnListBuilder.setRouterId(routerName);
1078             DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1079             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1080                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1081             routerInterfaces.add(routerInterface);
1082             dpnVpnList.setRouterInterfaces(routerInterfaces);
1083             routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1084             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1085                 getRouterId(routerName),
1086                 routerDpnListBuilder.build(), true);
1087         }
1088     }
1089
1090     static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1091                                    OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1092         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1093         if (dpId.equals(BigInteger.ZERO)) {
1094             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
1095                 interfaceName, routerName);
1096             return;
1097         }
1098
1099         LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1100                 + "DPNRouters map",
1101             dpId, routerName, interfaceName);
1102         InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1103
1104         Optional<DpnRoutersList> optionalDpnRoutersList = read(broker, LogicalDatastoreType.OPERATIONAL,
1105             dpnRoutersListIdentifier);
1106
1107         if (optionalDpnRoutersList.isPresent()) {
1108             RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
1109                 .setRouter(routerName).build();
1110             List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1111             if (!routersListFromDs.contains(routersList)) {
1112                 LOG.debug("NAT Service : Router {} not present for the DPN {}"
1113                     + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1114                 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1115                     dpnRoutersListIdentifier
1116                         .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1117             } else {
1118                 LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map",
1119                     routerName, dpId);
1120             }
1121         } else {
1122             LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} "
1123                 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1124             DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1125             dpnRoutersListBuilder.setDpnId(dpId);
1126             RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1127             routersListBuilder.setRouter(routerName);
1128             dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1129             writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1130                 getDpnRoutersId(dpId),
1131                 dpnRoutersListBuilder.build(), true);
1132         }
1133     }
1134
1135     static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1136                                                BigInteger dpId, WriteTransaction writeOperTxn) {
1137         if (dpId.equals(BigInteger.ZERO)) {
1138             LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1139                 interfaceName, routerName);
1140             return;
1141         }
1142         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1143         Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1144             .OPERATIONAL, routerDpnListIdentifier);
1145         if (optionalRouterDpnList.isPresent()) {
1146             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1147                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1148                 optionalRouterDpnList.get().getRouterInterfaces();
1149             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1150                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1151                 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1152                     .setInterface(interfaceName).build();
1153             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1154                 if (routerInterfaces.isEmpty()) {
1155                     writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1156                 } else {
1157                     writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1158                         org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1159                             .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1160                         new RouterInterfacesKey(interfaceName)));
1161                 }
1162             }
1163         }
1164     }
1165
1166     static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1167                                                BigInteger dpId, WriteTransaction writeOperTxn) {
1168         if (dpId.equals(BigInteger.ZERO)) {
1169             LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName);
1170             return;
1171         }
1172
1173         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1174         Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1175             .OPERATIONAL, routerDpnListIdentifier);
1176         if (optionalRouterDpnList.isPresent()) {
1177             LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model "
1178                 + "for the router {}", routerName);
1179             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1180         } else {
1181             LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model "
1182                 + "for the router {}", routerName);
1183         }
1184     }
1185
1186     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.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1192                 vpnInterfaceName, routerName);
1193             return;
1194         }
1195         InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1196         Optional<DpnVpninterfacesList> optionalRouterDpnList = read(broker, LogicalDatastoreType
1197             .OPERATIONAL, routerDpnListIdentifier);
1198         if (optionalRouterDpnList.isPresent()) {
1199             List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1200                 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1201                 optionalRouterDpnList.get().getRouterInterfaces();
1202             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1203                 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1204                 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1205                     .setInterface(vpnInterfaceName).build();
1206
1207             if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1208                 if (routerInterfaces.isEmpty()) {
1209                     if (writeOperTxn != null) {
1210                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1211                     } else {
1212                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1213                     }
1214                 } else {
1215                     if (writeOperTxn != null) {
1216                         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1217                             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1218                                 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1219                             new RouterInterfacesKey(vpnInterfaceName)));
1220                     } else {
1221                         MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1222                             org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1223                                 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1224                             new RouterInterfacesKey(vpnInterfaceName)));
1225                     }
1226                 }
1227             }
1228         }
1229     }
1230
1231     static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1232                                         OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1233         BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1234         if (dpId.equals(BigInteger.ZERO)) {
1235             LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} "
1236                     + "to handle router {} dissociation model",
1237                 vpnInterfaceName, routerName);
1238             return;
1239         }
1240         removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1241     }
1242
1243     static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1244                                         BigInteger curDpnId,
1245                                         OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1246         /*
1247             1) Get the DpnRoutersList for the DPN.
1248             2) Get the RoutersList identifier for the DPN and router.
1249             3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1250             4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1251              then remove RouterList.
1252          */
1253
1254         LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1255             + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1256
1257         //Get the dpn-routers-list instance for the current DPN.
1258         InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1259         Optional<DpnRoutersList> dpnRoutersListData = read(broker, LogicalDatastoreType.OPERATIONAL,
1260             dpnRoutersListIdentifier);
1261
1262         if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1263             LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model",
1264                 curDpnId);
1265             return;
1266         }
1267
1268         //Get the routers-list instance for the router on the current DPN only
1269         InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1270         Optional<RoutersList> routersListData = read(broker, LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1271
1272         if (routersListData == null || !routersListData.isPresent()) {
1273             LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model",
1274                 curDpnId);
1275             return;
1276         }
1277
1278         LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map",
1279             routerName);
1280         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1281             .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1282         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1283             .RouterInterfaces> routerInterfacesData = read(broker, LogicalDatastoreType.CONFIGURATION,
1284             routerInterfacesId);
1285
1286         if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1287             LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed"
1288                     + " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1289                 curDpnId, routerName, routerName);
1290             writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1291             return;
1292         }
1293
1294         //Get the VM interfaces for the router on the current DPN only.
1295         List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1296             .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1297         if (vmInterfaces == null) {
1298             LOG.debug("NAT Service : VM interfaces are not present for the router {} in the "
1299                 + "NeutronVPN - router-interfaces-map", routerName);
1300             return;
1301         }
1302
1303         // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1304         // then remove RouterList.
1305         for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1306                  .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1307             String vmInterfaceName = vmInterface.getInterfaceId();
1308             BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1309             if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1310                 LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of "
1311                         + "the DPN ID for the checked interface {} ",
1312                     curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1313                 continue;
1314             }
1315             if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1316                 LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} "
1317                     + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1318                 return;
1319             }
1320         }
1321         LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} "
1322             + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1323             + "deleted in the DPN", routerName, curDpnId);
1324         writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1325     }
1326
1327     private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1328         .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1329         return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1330             .rev150602.RouterInterfacesMap.class)
1331             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1332                     .interfaces.map.RouterInterfaces.class,
1333                 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1334                     .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1335     }
1336
1337     private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1338         return InstanceIdentifier.builder(DpnRouters.class)
1339             .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1340             .child(RoutersList.class, new RoutersListKey(routerName)).build();
1341     }
1342
1343     public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1344         BigInteger nodeId = BigInteger.ZERO;
1345         try {
1346             GetDpidFromInterfaceInput
1347                 dpIdInput =
1348                 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1349             Future<RpcResult<GetDpidFromInterfaceOutput>>
1350                 dpIdOutput =
1351                 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1352             RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1353             if (dpIdResult.isSuccessful()) {
1354                 nodeId = dpIdResult.getResult().getDpid();
1355             } else {
1356                 LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName);
1357             }
1358         } catch (NullPointerException | InterruptedException | ExecutionException e) {
1359             LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName, e);
1360         }
1361         return nodeId;
1362     }
1363
1364     public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1365                                                                 Long tunnelKey) {
1366         return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1367     }
1368
1369     public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1370                                                                 Long tunnelKey, int pos) {
1371         LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1372         GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1373             .setIntfName(ifName);
1374         if (tunnelKey != null) {
1375             egressActionsBuilder.setTunnelKey(tunnelKey);
1376         }
1377
1378         List<ActionInfo> listActionInfo = new ArrayList<>();
1379         try {
1380             Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1381                 .getEgressActionsForInterface(egressActionsBuilder.build());
1382             RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1383             if (!rpcResult.isSuccessful()) {
1384                 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1385                     rpcResult.getErrors());
1386             } else {
1387                 List<Action> actions = rpcResult.getResult().getAction();
1388                 for (Action action : actions) {
1389                     org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1390                         actionClass = action.getAction();
1391                     if (actionClass instanceof OutputActionCase) {
1392                         listActionInfo.add(new ActionOutput(pos++,
1393                             ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1394                     } else if (actionClass instanceof PushVlanActionCase) {
1395                         listActionInfo.add(new ActionPushVlan(pos++));
1396                     } else if (actionClass instanceof SetFieldCase) {
1397                         if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1398                             int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1399                                 .getVlanId().getValue();
1400                             listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1401                         }
1402                     } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1403                         Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1404                         listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1405                     } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1406                         NxRegLoad nxRegLoad =
1407                             ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1408                         listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1409                             nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1410                     }
1411                 }
1412             }
1413         } catch (InterruptedException | ExecutionException e) {
1414             LOG.warn("Exception when egress actions for interface {}", ifName, e);
1415         }
1416         return listActionInfo;
1417     }
1418
1419     public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1420         return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1421     }
1422
1423     public static List<Port> getNeutronPorts(DataBroker broker) {
1424         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1425             portsIdentifier = InstanceIdentifier.create(Neutron.class)
1426             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1427         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1428             portsOptional = read(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1429
1430         if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1431             LOG.trace("No neutron ports found");
1432             return Collections.EMPTY_LIST;
1433         }
1434
1435         return portsOptional.get().getPort();
1436     }
1437
1438     public static Port getNeutronPortForIp(DataBroker broker,
1439                                            IpAddress targetIP, String deviceType) {
1440         List<Port> ports = getNeutronPorts(
1441             broker);
1442
1443         for (Port port : ports) {
1444             if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1445                 for (FixedIps ip : port.getFixedIps()) {
1446                     if (Objects.equals(ip.getIpAddress(), targetIP)) {
1447                         return port;
1448                     }
1449                 }
1450             }
1451         }
1452
1453         return null;
1454     }
1455
1456     public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1457         if (port == null) {
1458             return null;
1459         }
1460         for (FixedIps ip : port.getFixedIps()) {
1461             if (Objects.equals(ip.getIpAddress(), targetIP)) {
1462                 return ip.getSubnetId();
1463             }
1464         }
1465
1466         return null;
1467     }
1468
1469     public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1470         InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1471             .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1472         return read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1473     }
1474
1475     public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1476         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1477             .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1478         Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1479         return optionalNetworkMap.isPresent() ? optionalNetworkMap.get().getSubnetIdList() : null;
1480     }
1481
1482     public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1483         if (subnetId == null) {
1484             return null;
1485         }
1486
1487         InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1488             .child(Subnet.class, new SubnetKey(subnetId));
1489         Optional<Subnet> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst);
1490         if (!subnetOpt.isPresent()) {
1491             return null;
1492         }
1493
1494         IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1495         if (gatewayIp == null) {
1496             LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1497             return null;
1498         }
1499
1500         InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1501             .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1502             .build();
1503         Optional<VpnPortipToPort> portIpToPortOpt = read(broker, LogicalDatastoreType.CONFIGURATION, portIpInst);
1504         if (portIpToPortOpt.isPresent()) {
1505             return portIpToPortOpt.get().getMacAddress();
1506         }
1507
1508         InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1509             .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1510             .build();
1511         Optional<LearntVpnVipToPort> learntIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, learntIpInst);
1512         if (learntIpToPortOpt.isPresent()) {
1513             return learntIpToPortOpt.get().getMacAddress();
1514         }
1515
1516         LOG.error("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1517         return null;
1518     }
1519
1520     public static boolean isIPv6Subnet(String prefix) {
1521         return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1522     }
1523
1524     static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1525         return InstanceIdentifier.builder(DpnRouters.class)
1526             .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1527     }
1528
1529     static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1530         return InstanceIdentifier.builder(NeutronRouterDpns.class)
1531             .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1532             .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1533     }
1534
1535     static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
1536         .Interface getInterface(DataBroker broker, String interfaceName) {
1537         Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
1538             .Interface> optInterface =
1539             read(broker, LogicalDatastoreType.CONFIGURATION, getInterfaceIdentifier(interfaceName));
1540         if (optInterface.isPresent()) {
1541             return optInterface.get();
1542         }
1543         return null;
1544     }
1545
1546     static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1547         return InstanceIdentifier.builder(NeutronRouterDpns.class)
1548             .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1549     }
1550
1551     protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1552         InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1553         Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1554             .CONFIGURATION, id);
1555         if (optFloatingIpIdToPortMapping.isPresent()) {
1556             return optFloatingIpIdToPortMapping.get().getFloatingIpPortMacAddress();
1557         }
1558         return null;
1559     }
1560
1561     protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1562         InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1563         Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1564             .CONFIGURATION, id);
1565         if (optFloatingIpIdToPortMapping.isPresent()) {
1566             return optFloatingIpIdToPortMapping.get().getFloatingIpPortSubnetId();
1567         }
1568         return null;
1569     }
1570
1571     static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1572         return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1573             FloatingIpIdToPortMappingKey(floatingIpId)).build();
1574     }
1575
1576     static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1577         .interfaces.rev140508.interfaces.Interface> getInterfaceIdentifier(String interfaceName) {
1578         return InstanceIdentifier.builder(Interfaces.class)
1579             .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1580                 .interfaces.Interface.class, new InterfaceKey(interfaceName)).build();
1581     }
1582
1583     static final FutureCallback<Void> DEFAULT_CALLBACK =
1584         new FutureCallback<Void>() {
1585             @Override
1586             public void onSuccess(Void result) {
1587                 LOG.debug("NAT Service : Success in Datastore operation");
1588             }
1589
1590             @Override
1591             public void onFailure(Throwable error) {
1592                 LOG.error("NAT Service : Error in Datastore operation", error);
1593             }
1594
1595             ;
1596         };
1597
1598     static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1599                                               InstanceIdentifier<T> path) {
1600         delete(broker, datastoreType, path, DEFAULT_CALLBACK);
1601     }
1602
1603     static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1604                                               InstanceIdentifier<T> path, FutureCallback<Void> callback) {
1605         WriteTransaction tx = broker.newWriteOnlyTransaction();
1606         tx.delete(datastoreType, path);
1607         Futures.addCallback(tx.submit(), callback);
1608     }
1609
1610     static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1611         InstanceIdentifier<Interface> ifStateId =
1612             buildStateInterfaceId(interfaceName);
1613         Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
1614         if (ifStateOptional.isPresent()) {
1615             return ifStateOptional.get();
1616         }
1617
1618         return null;
1619     }
1620
1621     static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1622         InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1623             InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1624                 .interfaces.rev140508.InterfacesState.class)
1625                 .child(Interface.class,
1626                     new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1627                         .interfaces.state.InterfaceKey(interfaceName));
1628         InstanceIdentifier<Interface> id = idBuilder.build();
1629         return id;
1630     }
1631
1632     public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1633         InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1634         Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerIdentifier);
1635         if (routerData.isPresent()) {
1636             return routerData.get();
1637         }
1638         return null;
1639     }
1640
1641     static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) {
1642         long routerId = NatUtil.getVpnId(dataBroker, routerName);
1643         if (routerId == NatConstants.INVALID_ID) {
1644             LOG.error("NAT Service : createRouterIdsConfigDS - invalid routerId for routerName {}", routerName);
1645             return;
1646         }
1647         RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1648             .setRouterId(routerId).setRouterName(routerName).build();
1649         MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1650     }
1651
1652     static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1653
1654         String routerName = getRouterName(broker, routerId);
1655         InstanceIdentifier id = buildRouterIdentifier(routerName);
1656         Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1657         if (routerData.isPresent()) {
1658             return routerData.get().getExtGwMacAddress();
1659         }
1660         return null;
1661     }
1662 }