2 * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
9 package org.opendaylight.netvirt.natservice.internal;
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.net.UnknownHostException;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Objects;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26 import java.util.stream.Collectors;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
30 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
33 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
34 import org.opendaylight.genius.mdsalutil.ActionInfo;
35 import org.opendaylight.genius.mdsalutil.FlowEntity;
36 import org.opendaylight.genius.mdsalutil.InstructionInfo;
37 import org.opendaylight.genius.mdsalutil.MDSALUtil;
38 import org.opendaylight.genius.mdsalutil.MatchInfo;
39 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
40 import org.opendaylight.genius.mdsalutil.NwConstants;
41 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
42 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
43 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
44 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
45 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
46 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
47 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
48 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
49 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
50 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
51 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
52 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
53 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
54 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
55 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
56 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
57 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
58 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
59 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
60 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
61 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
62 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
63 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
157 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;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
193 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;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
195 import org.opendaylight.yangtools.yang.binding.DataObject;
196 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
197 import org.opendaylight.yangtools.yang.common.RpcResult;
198 import org.slf4j.Logger;
199 import org.slf4j.LoggerFactory;
201 public class NatUtil {
203 private static String OF_URI_SEPARATOR = ":";
204 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
207 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
210 public static BigInteger getCookieSnatFlow(long routerId) {
211 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
212 BigInteger.valueOf(routerId));
216 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
219 public static BigInteger getCookieNaptFlow(long routerId) {
220 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
221 BigInteger.valueOf(routerId));
225 getVpnId() returns the VPN ID from the VPN name
227 public static long getVpnId(DataBroker broker, String vpnName) {
228 if (vpnName == null) {
229 return NatConstants.INVALID_ID;
232 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
233 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
234 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
235 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
237 long vpnId = NatConstants.INVALID_ID;
238 if (vpnInstance.isPresent()) {
239 Long vpnIdAsLong = vpnInstance.get().getVpnId();
240 if (vpnIdAsLong != null) {
247 public static Long getVpnId(DataBroker broker, long routerId) {
248 //Get the external network ID from the ExternalRouter model
249 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
250 if (networkId == null) {
251 LOG.error("NAT Service : networkId is null");
255 //Get the VPN ID from the ExternalNetworks model
256 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
257 if (vpnUuid == null) {
258 LOG.error("NAT Service : vpnUuid is null");
261 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
265 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
266 return InstanceIdentifier.builder(FloatingIpInfo.class)
267 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
270 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
271 return InstanceIdentifier.builder(RouterToVpnMapping.class)
272 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
275 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
276 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
277 .child(Ports.class, new PortsKey(portName)).build();
280 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
282 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
283 .child(Ports.class, new PortsKey(portName))
284 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
287 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
288 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
289 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
290 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
291 .instance.to.vpn.id.VpnInstance.class,
292 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
293 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
296 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
297 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
298 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
299 Optional<VpnIds> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
300 return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : null;
304 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
306 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
307 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
308 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
311 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
312 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
313 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
316 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
317 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
318 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
322 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
323 String routerName = getRouterName(broker, routerId);
324 return getNetworkIdFromRouterName(broker, routerName);
327 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
328 if (routerName == null) {
329 LOG.error("getNetworkIdFromRouterName - empty routerName received");
332 InstanceIdentifier id = buildRouterIdentifier(routerName);
333 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
334 if (routerData.isPresent()) {
335 return routerData.get().getNetworkId();
340 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
341 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
342 .child(Routers.class, new RoutersKey(routerId)).build();
343 return routerInstanceIndentifier;
346 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
347 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
348 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
353 * Return if SNAT is enabled for the given router.
355 * @param broker The DataBroker
356 * @param routerId The router
357 * @return boolean true if enabled, otherwise false
359 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
360 InstanceIdentifier id = buildRouterIdentifier(routerId);
361 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
362 if (routerData.isPresent()) {
363 return routerData.get().isEnableSnat();
368 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
369 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
370 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
371 if (networkData.isPresent()) {
372 return networkData.get().getVpnid();
377 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
378 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
379 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
380 if ((networkData.isPresent()) && (networkData.get() != null)) {
381 return networkData.get().getProviderNetworkType();
386 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
387 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
388 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
389 return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList();
392 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
393 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
394 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
395 if (routerData.isPresent()) {
396 Uuid networkId = routerData.get().getNetworkId();
397 if (networkId != null) {
398 return networkId.getValue();
404 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
405 InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class)
406 .child(Networks.class, new NetworksKey(networkId)).build();
410 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
411 // convert routerId to Name
412 String routerName = getRouterName(broker, routerId);
413 return getPrimaryNaptfromRouterName(broker, routerName);
416 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
417 if (routerName == null) {
418 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
421 InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
422 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
423 if (routerToNaptSwitchData.isPresent()) {
424 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
425 return routerToNaptSwitchInstance.getPrimarySwitchId();
430 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
431 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
432 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
436 public static String getRouterName(DataBroker broker, Long routerId) {
437 InstanceIdentifier id = buildRouterIdentifier(routerId);
438 Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
439 if (routerIdsData.isPresent()) {
440 RouterIds routerIdsInstance = routerIdsData.get();
441 return routerIdsInstance.getRouterName();
446 // TODO Clean up the exception handling
447 @SuppressWarnings("checkstyle:IllegalCatch")
448 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
449 InstanceIdentifier<T> path) {
451 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
454 return tx.read(datastoreType, path).get();
455 } catch (Exception e) {
456 throw new RuntimeException(e);
460 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
461 return InstanceIdentifier.builder(VpnInstanceOpData.class)
462 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
465 public static long readVpnId(DataBroker broker, String vpnName) {
466 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
467 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
468 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
469 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
471 long vpnId = NatConstants.INVALID_ID;
472 if (vpnInstance.isPresent()) {
473 vpnId = vpnInstance.get().getVpnId();
479 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
480 FlowEntity flowEntity = new FlowEntity(dpnId);
481 flowEntity.setTableId(tableId);
482 flowEntity.setCookie(cookie);
486 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId,
487 int priority, String flowName,
488 BigInteger cookie, List<MatchInfo> listMatchInfo) {
490 FlowEntity flowEntity = new FlowEntity(dpnId);
491 flowEntity.setTableId(tableId);
492 flowEntity.setFlowId(flowId);
493 flowEntity.setPriority(priority);
494 flowEntity.setFlowName(flowName);
495 flowEntity.setCookie(cookie);
496 flowEntity.setMatchInfoList(listMatchInfo);
500 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
501 FlowEntity flowEntity = new FlowEntity(dpnId);
502 flowEntity.setTableId(tableId);
503 flowEntity.setCookie(cookie);
504 flowEntity.setFlowId(flowId);
508 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
509 FlowEntity flowEntity = new FlowEntity(dpnId);
510 flowEntity.setTableId(tableId);
511 flowEntity.setFlowId(flowId);
515 public static long getIpAddress(byte[] rawIpAddress) {
516 return (((rawIpAddress[0] & 0xFF) << (3 * 8)) + ((rawIpAddress[1] & 0xFF) << (2 * 8))
517 + ((rawIpAddress[2] & 0xFF) << (1 * 8)) + (rawIpAddress[3] & 0xFF)) & 0xffffffffL;
520 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
521 String nextHopIp = null;
522 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
523 InstanceIdentifier.builder(DpnEndpoints.class)
524 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
525 Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
526 if (tunnelInfo.isPresent()) {
527 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
528 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
529 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
535 public static String getVpnRd(DataBroker broker, String vpnName) {
537 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
538 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
539 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
540 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
543 if (vpnInstance.isPresent()) {
544 rd = vpnInstance.get().getVrfId();
549 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
550 String internalPort, NAPTEntryEvent.Protocol protocol) {
551 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
552 InstanceIdentifier ipPortMapId =
553 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
554 Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
555 if (ipPortMapData.isPresent()) {
556 IpPortMap ipPortMapInstance = ipPortMapData.get();
557 return ipPortMapInstance.getIpPortExternal();
562 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
564 ProtocolTypes protocolType) {
565 InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class)
566 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
567 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
568 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
572 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
573 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
574 return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
577 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
578 return InstanceIdentifier.builder(VpnInterfaces.class)
579 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
582 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
583 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
584 return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
587 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
589 * NodeConnectorId is of form 'openflow:dpnid:portnum'
591 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
592 if (split == null || split.length != 3) {
598 public static BigInteger getDpIdFromInterface(
599 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
600 .state.Interface ifState) {
601 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
602 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
603 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
606 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
607 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
608 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
609 Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
611 if (optionalVpnMap.isPresent()) {
612 Uuid routerId = optionalVpnMap.get().getRouterId();
613 if (routerId != null) {
614 return routerId.getValue();
620 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
621 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
622 Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
624 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
625 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
626 if (routerId != null) {
627 for (VpnMap vpnMap : allMaps) {
628 if (vpnMap.getRouterId() != null
629 && routerId.equals(vpnMap.getRouterId().getValue())
630 && !routerId.equals(vpnMap.getVpnId().getValue())) {
631 return vpnMap.getVpnId();
639 static long getAssociatedVpn(DataBroker broker, String routerName) {
640 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
641 Optional<Routermapping> optRouterMapping =
642 NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
643 if (optRouterMapping.isPresent()) {
644 Routermapping routerMapping = optRouterMapping.get();
645 return routerMapping.getVpnId();
647 return NatConstants.INVALID_ID;
650 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
651 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
652 if (vpnUuid == null) {
653 log.error("No VPN instance associated with ext network {}", networkId);
656 return vpnUuid.getValue();
659 // TODO Clean up the exception handling
660 @SuppressWarnings("checkstyle:IllegalCatch")
661 public static void addPrefixToBGP(DataBroker broker,
662 IBgpManager bgpManager,
663 IFibManager fibManager,
673 Logger log, RouteOrigin origin, BigInteger dpId) {
675 LOG.info("NAT Service : ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
676 prefix, nextHopIp, label);
677 if (nextHopIp == null) {
678 LOG.error("NAT Service : addPrefix prefix {} rd {} failed since nextHopIp cannot be null.", prefix, rd);
682 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId, subnetId,
683 /*isNatPrefix*/ true);
684 fibManager.addOrUpdateFibEntry(broker, rd, macAddress, prefix,
685 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
686 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
687 if ((rd != null) && (!rd.equalsIgnoreCase(vpnName))) {
688 /* Publish to Bgp only if its an INTERNET VPN */
689 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
690 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/, null /*gatewayMac*/);
692 LOG.info("NAT Service : ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
693 prefix, nextHopIp, label);
694 } catch (Exception e) {
695 LOG.error("NAT Service : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
696 prefix, nextHopIp, label, e);
700 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
701 BigInteger dpId, Uuid subnetId, boolean isNatPrefix) {
702 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
703 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
704 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
705 .to._interface.VpnIdsKey(vpnId))
706 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
707 Prefixes prefix = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix).setVpnInterfaceName(interfaceName)
708 .setNatPrefix(isNatPrefix).setSubnetId(subnetId).build();
710 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId, prefix);
711 } catch (TransactionCommitFailedException e) {
712 LOG.error("Failed to write prefxi-to-interface for {} vpn-id {} DPN {}", ipPrefix, vpnId, dpId);
716 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
717 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
718 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
722 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
723 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
724 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
725 return routerInstanceIndentifier;
728 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
729 String internalIpAddress, ProtocolTypes protocolType) {
730 Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION,
731 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
732 if (optionalIpProtoType.isPresent()) {
733 return optionalIpProtoType.get().getPorts();
738 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
739 String internalIpAddress,
740 ProtocolTypes protocolType) {
741 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
742 InstanceIdentifier.builder(SnatintIpPortMap.class)
743 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
744 .child(IpPort.class, new IpPortKey(internalIpAddress))
745 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
746 return intIpProtocolTypeId;
749 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
750 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
751 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
755 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
756 return InstanceIdentifier.create(NaptSwitches.class);
759 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
760 return InstanceIdentifier.create(NaptSwitches.class)
761 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
764 public static String getGroupIdKey(String routerName) {
765 return "snatmiss." + routerName;
768 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
769 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
770 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
773 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
774 RpcResult<AllocateIdOutput> rpcResult = result.get();
775 return rpcResult.getResult().getIdValue();
776 } catch (NullPointerException | InterruptedException | ExecutionException e) {
782 // TODO Clean up the exception handling
783 @SuppressWarnings("checkstyle:IllegalCatch")
784 public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager,
785 String rd, String prefix, String vpnName, Logger log) {
787 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
788 fibManager.removeFibEntry(broker, rd, prefix, null);
789 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
790 bgpManager.withdrawPrefix(rd, prefix);
792 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
793 } catch (Exception e) {
794 log.error("Delete prefix for rd {} prefix {} vpnName {} failed", rd, prefix, vpnName, e);
798 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
799 return read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
802 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
803 return InstanceIdentifier.builder(IntextIpPortMap.class)
804 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
807 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
808 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
809 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
810 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
811 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
812 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
813 .intext.ip.map.IpMappingKey(routerId)).build();
817 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
818 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
819 .ip.map.IpMapping> ipMappingOptional =
820 read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
821 List<String> externalIps = new ArrayList<>();
822 if (ipMappingOptional.isPresent()) {
823 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
824 for (IpMap ipMap : ipMaps) {
825 externalIps.add(ipMap.getExternalIp());
828 return new ArrayList<>(new HashSet<>(externalIps));
833 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
834 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
835 if (routerData != null) {
836 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
839 return Collections.emptyList();
842 public static HashMap<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
843 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
844 .ip.map.IpMapping> ipMappingOptional =
845 read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
846 HashMap<String, Long> externalIpsLabel = new HashMap<>();
847 if (ipMappingOptional.isPresent()) {
848 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
849 for (IpMap ipMap : ipMaps) {
850 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
852 return externalIpsLabel;
857 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
858 String leastLoadedExternalIp = null;
859 InstanceIdentifier<ExternalCounters> id =
860 InstanceIdentifier.builder(ExternalIpsCounter.class)
861 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
862 Optional<ExternalCounters> externalCountersData =
863 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
864 if (externalCountersData.isPresent()) {
865 ExternalCounters externalCounter = externalCountersData.get();
866 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
867 short countOfLstLoadExtIp = 32767;
868 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
869 String curExternalIp = externalIpCounter.getExternalIp();
870 short countOfCurExtIp = externalIpCounter.getCounter();
871 if (countOfCurExtIp < countOfLstLoadExtIp) {
872 countOfLstLoadExtIp = countOfCurExtIp;
873 leastLoadedExternalIp = curExternalIp;
877 return leastLoadedExternalIp;
880 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
881 String subnetIP = getSubnetIp(dataBroker, subnetId);
882 if (subnetIP != null) {
883 return getSubnetIpAndPrefix(subnetIP);
888 public static String[] getSubnetIpAndPrefix(String subnetString) {
889 String[] subnetSplit = subnetString.split("/");
890 String subnetIp = subnetSplit[0];
891 String subnetPrefix = "0";
892 if (subnetSplit.length == 2) {
893 subnetPrefix = subnetSplit[1];
895 return new String[] {subnetIp, subnetPrefix};
898 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
899 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
900 .builder(Subnetmaps.class)
901 .child(Subnetmap.class, new SubnetmapKey(subnetId))
903 Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
904 if (removedSubnet.isPresent()) {
905 Subnetmap subnetMapEntry = removedSubnet.get();
906 return subnetMapEntry.getSubnetIp();
912 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
913 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
914 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
915 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
916 if (leastLoadedExtIpAddrSplit.length == 2) {
917 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
919 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
922 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
923 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
924 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
925 Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
926 List<BigInteger> dpns = new ArrayList<>();
927 if (routerDpnListData.isPresent()) {
928 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
929 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
930 dpns.add(dpnVpnInterface.getDpnId());
937 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
938 long bgpVpnId = NatConstants.INVALID_ID;
939 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
940 if (bgpVpnUuid != null) {
941 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
946 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
947 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
948 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router
949 .interfaces.RouterInterface> optRouterInterface =
950 read(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName));
951 if (optRouterInterface.isPresent()) {
952 return optRouterInterface.get();
957 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
958 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
959 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
960 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
961 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
962 .RouterInterface.class,
963 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
964 .RouterInterfaceKey(interfaceName)).build();
967 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
968 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
969 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
970 addToNeutronRouterDpnsMap(broker, routerName, interfaceName, dpId, writeOperTxn);
973 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
974 BigInteger dpId , WriteTransaction writeOperTxn) {
976 if (dpId.equals(BigInteger.ZERO)) {
977 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
978 interfaceName, routerName);
982 LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the "
983 + "ODL-L3VPN : NeutronRouterDpn map",
984 routerName, dpId, interfaceName);
985 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
987 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = read(broker, LogicalDatastoreType
988 .OPERATIONAL, dpnVpnInterfacesListIdentifier);
989 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
990 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
991 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
992 .setInterface(interfaceName).build();
993 if (optionalDpnVpninterfacesList.isPresent()) {
994 LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the "
995 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
996 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
997 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
998 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
999 new RouterInterfacesKey(interfaceName)), routerInterface, true);
1001 LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the "
1002 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1003 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1004 routerDpnListBuilder.setRouterId(routerName);
1005 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1006 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1007 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1008 routerInterfaces.add(routerInterface);
1009 dpnVpnList.setRouterInterfaces(routerInterfaces);
1010 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1011 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1012 getRouterId(routerName),
1013 routerDpnListBuilder.build(), true);
1018 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1019 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1020 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1021 addToDpnRoutersMap(broker, routerName, interfaceName, dpId, writeOperTxn);
1024 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1025 BigInteger dpId, WriteTransaction writeOperTxn) {
1026 if (dpId.equals(BigInteger.ZERO)) {
1027 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
1028 interfaceName, routerName);
1032 LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1034 dpId, routerName, interfaceName);
1035 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1037 Optional<DpnRoutersList> optionalDpnRoutersList = read(broker, LogicalDatastoreType.OPERATIONAL,
1038 dpnRoutersListIdentifier);
1040 if (optionalDpnRoutersList.isPresent()) {
1041 RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
1042 .setRouter(routerName).build();
1043 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1044 if (!routersListFromDs.contains(routersList)) {
1045 LOG.debug("NAT Service : Router {} not present for the DPN {}"
1046 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1047 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1048 dpnRoutersListIdentifier
1049 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1051 LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map",
1055 LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} "
1056 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1057 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1058 dpnRoutersListBuilder.setDpnId(dpId);
1059 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1060 routersListBuilder.setRouter(routerName);
1061 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1062 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1063 getDpnRoutersId(dpId),
1064 dpnRoutersListBuilder.build(), true);
1069 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1070 BigInteger dpId, WriteTransaction writeOperTxn) {
1071 if (dpId.equals(BigInteger.ZERO)) {
1072 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1073 interfaceName, routerName);
1076 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1077 Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1078 .OPERATIONAL, routerDpnListIdentifier);
1079 if (optionalRouterDpnList.isPresent()) {
1080 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1081 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1082 optionalRouterDpnList.get().getRouterInterfaces();
1083 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1084 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1085 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1086 .setInterface(interfaceName).build();
1087 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1088 if (routerInterfaces.isEmpty()) {
1089 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1091 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1092 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1093 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1094 new RouterInterfacesKey(interfaceName)));
1100 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1101 BigInteger dpId, WriteTransaction writeOperTxn) {
1102 if (dpId.equals(BigInteger.ZERO)) {
1103 LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName);
1107 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1108 Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1109 .OPERATIONAL, routerDpnListIdentifier);
1110 if (optionalRouterDpnList.isPresent()) {
1111 LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model "
1112 + "for the router {}", routerName);
1113 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1115 LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model "
1116 + "for the router {}", routerName);
1120 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1121 OdlInterfaceRpcService ifaceMgrRpcService,
1122 WriteTransaction writeOperTxn) {
1123 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1124 if (dpId.equals(BigInteger.ZERO)) {
1125 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1126 vpnInterfaceName, routerName);
1129 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1130 Optional<DpnVpninterfacesList> optionalRouterDpnList = read(broker, LogicalDatastoreType
1131 .OPERATIONAL, routerDpnListIdentifier);
1132 if (optionalRouterDpnList.isPresent()) {
1133 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1134 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1135 optionalRouterDpnList.get().getRouterInterfaces();
1136 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1137 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1138 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1139 .setInterface(vpnInterfaceName).build();
1141 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1142 if (routerInterfaces.isEmpty()) {
1143 if (writeOperTxn != null) {
1144 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1146 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1149 if (writeOperTxn != null) {
1150 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1151 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1152 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1153 new RouterInterfacesKey(vpnInterfaceName)));
1155 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1156 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1157 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1158 new RouterInterfacesKey(vpnInterfaceName)));
1165 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1166 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1167 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1168 if (dpId.equals(BigInteger.ZERO)) {
1169 LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} "
1170 + "to handle router {} dissociation model",
1171 vpnInterfaceName, routerName);
1174 removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1177 static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1178 BigInteger curDpnId,
1179 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1181 1) Get the DpnRoutersList for the DPN.
1182 2) Get the RoutersList identifier for the DPN and router.
1183 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1184 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1185 then remove RouterList.
1188 LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1189 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1191 //Get the dpn-routers-list instance for the current DPN.
1192 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1193 Optional<DpnRoutersList> dpnRoutersListData = read(broker, LogicalDatastoreType.OPERATIONAL,
1194 dpnRoutersListIdentifier);
1196 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1197 LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model",
1202 //Get the routers-list instance for the router on the current DPN only
1203 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1204 Optional<RoutersList> routersListData = read(broker, LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1206 if (routersListData == null || !routersListData.isPresent()) {
1207 LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model",
1212 LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map",
1214 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1215 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1216 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1217 .RouterInterfaces> routerInterfacesData = read(broker, LogicalDatastoreType.CONFIGURATION,
1218 routerInterfacesId);
1220 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1221 LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed"
1222 + " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1223 curDpnId, routerName, routerName);
1224 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1228 //Get the VM interfaces for the router on the current DPN only.
1229 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1230 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1231 if (vmInterfaces == null) {
1232 LOG.debug("NAT Service : VM interfaces are not present for the router {} in the "
1233 + "NeutronVPN - router-interfaces-map", routerName);
1237 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1238 // then remove RouterList.
1239 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1240 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1241 String vmInterfaceName = vmInterface.getInterfaceId();
1242 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1243 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1244 LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of "
1245 + "the DPN ID for the checked interface {} ",
1246 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1249 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1250 LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} "
1251 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1255 LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} "
1256 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1257 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1258 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1261 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1262 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1263 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1264 .rev150602.RouterInterfacesMap.class)
1265 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1266 .interfaces.map.RouterInterfaces.class,
1267 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1268 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1271 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1272 return InstanceIdentifier.builder(DpnRouters.class)
1273 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1274 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1277 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1278 BigInteger nodeId = BigInteger.ZERO;
1280 GetDpidFromInterfaceInput
1282 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1283 Future<RpcResult<GetDpidFromInterfaceOutput>>
1285 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1286 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1287 if (dpIdResult.isSuccessful()) {
1288 nodeId = dpIdResult.getResult().getDpid();
1290 LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName);
1292 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1293 LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName, e);
1298 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1300 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1303 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1304 Long tunnelKey, int pos) {
1305 LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1306 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1307 .setIntfName(ifName);
1308 if (tunnelKey != null) {
1309 egressActionsBuilder.setTunnelKey(tunnelKey);
1312 List<ActionInfo> listActionInfo = new ArrayList<>();
1314 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1315 .getEgressActionsForInterface(egressActionsBuilder.build());
1316 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1317 if (!rpcResult.isSuccessful()) {
1318 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1319 rpcResult.getErrors());
1321 List<Action> actions = rpcResult.getResult().getAction();
1322 for (Action action : actions) {
1323 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1324 actionClass = action.getAction();
1325 if (actionClass instanceof OutputActionCase) {
1326 listActionInfo.add(new ActionOutput(pos++,
1327 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1328 } else if (actionClass instanceof PushVlanActionCase) {
1329 listActionInfo.add(new ActionPushVlan(pos++));
1330 } else if (actionClass instanceof SetFieldCase) {
1331 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1332 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1333 .getVlanId().getValue();
1334 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1336 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1337 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1338 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1339 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1340 NxRegLoad nxRegLoad =
1341 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1342 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1343 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1347 } catch (InterruptedException | ExecutionException e) {
1348 LOG.warn("Exception when egress actions for interface {}", ifName, e);
1350 return listActionInfo;
1353 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1354 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1357 public static List<Port> getNeutronPorts(DataBroker broker) {
1358 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1359 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1360 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1361 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1362 portsOptional = read(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1364 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1365 LOG.trace("No neutron ports found");
1366 return Collections.EMPTY_LIST;
1369 return portsOptional.get().getPort();
1372 public static Port getNeutronPortForIp(DataBroker broker,
1373 IpAddress targetIP, String deviceType) {
1374 List<Port> ports = getNeutronPorts(
1377 for (Port port : ports) {
1378 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1379 for (FixedIps ip : port.getFixedIps()) {
1380 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1390 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1394 for (FixedIps ip : port.getFixedIps()) {
1395 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1396 return ip.getSubnetId();
1403 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1404 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1405 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1406 return read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1409 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1410 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1411 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1412 Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1413 return optionalNetworkMap.isPresent() ? optionalNetworkMap.get().getSubnetIdList() : null;
1416 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1417 if (subnetId == null) {
1421 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1422 .child(Subnet.class, new SubnetKey(subnetId));
1423 Optional<Subnet> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst);
1424 if (!subnetOpt.isPresent()) {
1428 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1429 if (gatewayIp == null) {
1430 LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1434 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1435 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1437 Optional<VpnPortipToPort> portIpToPortOpt = read(broker, LogicalDatastoreType.CONFIGURATION, portIpInst);
1438 if (portIpToPortOpt.isPresent()) {
1439 return portIpToPortOpt.get().getMacAddress();
1442 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1443 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1445 Optional<LearntVpnVipToPort> learntIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, learntIpInst);
1446 if (learntIpToPortOpt.isPresent()) {
1447 return learntIpToPortOpt.get().getMacAddress();
1450 LOG.error("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1454 public static boolean isIPv6Subnet(String prefix) {
1455 return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1458 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1459 return InstanceIdentifier.builder(DpnRouters.class)
1460 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1463 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1464 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1465 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1466 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1469 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1470 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1471 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1474 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1475 InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1476 Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1477 .CONFIGURATION, id);
1478 if (optFloatingIpIdToPortMapping.isPresent()) {
1479 return optFloatingIpIdToPortMapping.get().getFloatingIpPortMacAddress();
1484 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1485 InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1486 Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1487 .CONFIGURATION, id);
1488 if (optFloatingIpIdToPortMapping.isPresent()) {
1489 return optFloatingIpIdToPortMapping.get().getFloatingIpPortSubnetId();
1494 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1495 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1496 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1499 static final FutureCallback<Void> DEFAULT_CALLBACK =
1500 new FutureCallback<Void>() {
1502 public void onSuccess(Void result) {
1503 LOG.debug("NAT Service : Success in Datastore operation");
1507 public void onFailure(Throwable error) {
1508 LOG.error("NAT Service : Error in Datastore operation", error);
1514 static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1515 InstanceIdentifier<T> path) {
1516 delete(broker, datastoreType, path, DEFAULT_CALLBACK);
1519 static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1520 InstanceIdentifier<T> path, FutureCallback<Void> callback) {
1521 WriteTransaction tx = broker.newWriteOnlyTransaction();
1522 tx.delete(datastoreType, path);
1523 Futures.addCallback(tx.submit(), callback);
1526 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1527 InstanceIdentifier<Interface> ifStateId =
1528 buildStateInterfaceId(interfaceName);
1529 Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
1530 if (ifStateOptional.isPresent()) {
1531 return ifStateOptional.get();
1537 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1538 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1539 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1540 .interfaces.rev140508.InterfacesState.class)
1541 .child(Interface.class,
1542 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1543 .interfaces.state.InterfaceKey(interfaceName));
1544 InstanceIdentifier<Interface> id = idBuilder.build();
1548 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1549 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1550 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerIdentifier);
1551 if (routerData.isPresent()) {
1552 return routerData.get();
1557 static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) {
1558 long routerId = NatUtil.getVpnId(dataBroker, routerName);
1559 if (routerId == NatConstants.INVALID_ID) {
1560 LOG.error("NAT Service : createRouterIdsConfigDS - invalid routerId for routerName {}", routerName);
1563 RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1564 .setRouterId(routerId).setRouterName(routerName).build();
1565 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1568 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1569 IdManagerService idManager) {
1570 InetAddress defaultIP = null;
1572 defaultIP = InetAddress.getByName("0.0.0.0");
1573 } catch (UnknownHostException e) {
1574 LOG.error("NAT Service : UnknowHostException in buildDefNATFlowEntityForExternalSubnet. "
1575 + "Failed to build FIB Table Flow for Default Route to NAT.");
1579 List<MatchInfo> matches = new ArrayList<>();
1580 matches.add(MatchEthernetType.IPV4);
1581 //add match for vrfid
1582 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1584 List<InstructionInfo> instructions = new ArrayList<>();
1585 List<ActionInfo> actionsInfo = new ArrayList<>();
1586 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1587 actionsInfo.add(new ActionGroup(groupId));
1588 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1589 instructions.add(new InstructionApplyActions(actionsInfo));
1590 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1591 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1592 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1596 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1597 String routerName = getRouterName(broker, routerId);
1598 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1599 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1600 if (routerData.isPresent()) {
1601 return routerData.get().getExtGwMacAddress();
1606 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1607 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1608 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1609 .child(Router.class, new RouterKey(routerUuid));
1610 return routerInstanceIdentifier;
1613 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1614 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1615 Optional<Router> neutronRouterData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1616 neutronRouterIdentifier);
1617 if (neutronRouterData.isPresent()) {
1618 return neutronRouterData.get().getName();
1623 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1625 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1626 Optional<RouterPorts> routerPortsData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1627 routerPortsIdentifier);
1628 if (routerPortsData.isPresent()) {
1629 return routerPortsData.get().getPorts();
1634 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1635 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1636 Optional<ExternalNetworks> externalNwData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1637 externalNwIdentifier);
1638 if (externalNwData.isPresent()) {
1639 for (Networks externalNw : externalNwData.get().getNetworks()) {
1640 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1641 return externalNw.getRouterIds();
1648 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1651 long ipLo = ipToLong(InetAddress.getByName(start));
1652 long ipHi = ipToLong(InetAddress.getByName(end));
1653 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1654 return (ipToTest >= ipLo && ipToTest <= ipHi);
1655 } catch (UnknownHostException e) {
1656 LOG.error("NAT Service : isIpInSubnet failed for IP {}. Exception {}", ipAddress, e.getMessage());
1661 public static List<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1662 if (externalIps == null) {
1663 return Collections.emptyList();
1666 Set<Uuid> subnetsSet = externalIps.stream().map(externalIp -> externalIp.getSubnetId())
1667 .collect(Collectors.toSet());
1668 return new ArrayList<Uuid>(subnetsSet);
1671 public static List<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1672 if (routerName == null) {
1673 LOG.error("getExternalSubnetIdsForRouter - empty routerName received");
1677 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1678 Optional<Routers> routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1679 if (routerData.isPresent()) {
1680 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1682 LOG.warn("No external router data for router {}", routerName);
1683 return Collections.emptyList();
1687 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1688 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1689 if (subnetId == null) {
1690 LOG.warn("getOptionalExternalSubnets - null subnetId");
1694 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1695 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1696 InstanceIdentifier.builder(ExternalSubnets.class)
1697 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1698 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1699 return read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1702 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1703 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1704 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1706 if (optionalExternalSubnets.isPresent()) {
1707 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1710 return NatConstants.INVALID_ID;
1713 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1715 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(dataBroker, externalIpAddress, router);
1716 if (externalSubnetId != null) {
1717 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1720 return NatConstants.INVALID_ID;
1723 protected static Uuid getExternalSubnetForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1725 List<ExternalIps> externalIps = router.getExternalIps();
1726 for (ExternalIps extIp : externalIps) {
1727 String extIpString = extIp.getIpAddress().contains("/32") ? (extIp.getIpAddress() + "/32") :
1728 extIp.getIpAddress();
1729 if (extIpString.equals(externalIpAddress)) {
1730 return extIp.getSubnetId();
1737 private static long ipToLong(InetAddress ip) {
1738 byte[] octets = ip.getAddress();
1740 for (byte octet : octets) {
1742 result |= octet & 0xff;
1747 static List<String> getIpsListFromExternalIps(List<ExternalIps> externalIps) {
1748 if (externalIps == null) {
1749 return Collections.emptyList();
1752 return externalIps.stream().map(externalIp -> externalIp.getIpAddress()).collect(Collectors.toList());
1755 // elan-instances config container
1756 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1757 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1758 return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1761 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1762 return InstanceIdentifier.builder(ElanInstances.class)
1763 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1766 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, INeutronVpnManager nvpnManager,
1767 IdManagerService idManager, long routerId, String routerName) {
1768 if (nvpnManager.getEnforceOpenstackSemanticsConfig()) {
1769 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1770 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1772 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1776 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1778 LOG.debug("NAT Service : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1779 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1781 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1782 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1783 List<MatchInfo> matches = new ArrayList<>();
1784 matches.add(MatchEthernetType.IPV4);
1785 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1786 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1787 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1788 matches, preDnatToSnatInstructions);
1790 mdsalManager.installFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1791 LOG.debug("NAT Service : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1792 preDnatToSnatTableFlowEntity, naptDpnId);
1795 public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId) {
1796 LOG.debug("NAT Service : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1797 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1798 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1799 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1800 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null);
1801 mdsalManager.removeFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1802 LOG.debug("NAT Service : Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1803 preDnatToSnatTableFlowEntity, naptDpnId);
1806 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1807 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1808 + NwConstants.FLOWID_SEPARATOR + uniqueId;