2 * Copyright © 2016, 2018 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
8 package org.opendaylight.netvirt.natservice.internal;
10 import static java.util.Collections.emptyList;
11 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
12 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import com.google.common.base.Splitter;
17 import com.google.common.base.Strings;
18 import com.google.common.collect.Iterables;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import java.math.BigInteger;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Objects;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.locks.ReentrantLock;
35 import java.util.stream.Collectors;
36 import org.apache.commons.net.util.SubnetUtils;
37 import org.eclipse.jdt.annotation.NonNull;
38 import org.eclipse.jdt.annotation.Nullable;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
42 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
43 import org.opendaylight.controller.sal.common.util.Arguments;
44 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
45 import org.opendaylight.genius.infra.Datastore.Configuration;
46 import org.opendaylight.genius.infra.Datastore.Operational;
47 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
48 import org.opendaylight.genius.infra.TypedReadTransaction;
49 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
50 import org.opendaylight.genius.infra.TypedWriteTransaction;
51 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
52 import org.opendaylight.genius.mdsalutil.ActionInfo;
53 import org.opendaylight.genius.mdsalutil.BucketInfo;
54 import org.opendaylight.genius.mdsalutil.FlowEntity;
55 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
56 import org.opendaylight.genius.mdsalutil.GroupEntity;
57 import org.opendaylight.genius.mdsalutil.InstructionInfo;
58 import org.opendaylight.genius.mdsalutil.MDSALUtil;
59 import org.opendaylight.genius.mdsalutil.MatchInfo;
60 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
61 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
62 import org.opendaylight.genius.mdsalutil.NwConstants;
63 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
64 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
65 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
66 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
67 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
68 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
69 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
70 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
71 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
72 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
73 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
74 import org.opendaylight.genius.utils.JvmGlobalLocks;
75 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
76 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
77 import org.opendaylight.netvirt.elanmanager.api.IElanService;
78 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
79 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
80 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
81 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
82 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
83 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
84 import org.opendaylight.serviceutils.upgrade.UpgradeState;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
88 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
220 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;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
262 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
263 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
264 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
265 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
266 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;
267 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
268 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
269 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
270 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
271 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
272 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
273 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
274 import org.opendaylight.yangtools.yang.common.RpcResult;
275 import org.opendaylight.yangtools.yang.common.Uint16;
276 import org.opendaylight.yangtools.yang.common.Uint32;
277 import org.opendaylight.yangtools.yang.common.Uint64;
278 import org.slf4j.Logger;
279 import org.slf4j.LoggerFactory;
281 public final class NatUtil {
283 private static String OF_URI_SEPARATOR = ":";
284 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
285 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
286 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
287 private static final String PROVIDER_MAPPINGS = "provider_mappings";
294 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
297 public static Uint64 getCookieSnatFlow(long routerId) {
298 return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0110000", 16)).add(
299 BigInteger.valueOf(routerId)));
303 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
306 public static Uint64 getCookieNaptFlow(Uint32 routerId) {
307 return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0111000", 16)).add(
308 BigInteger.valueOf(routerId.longValue())));
312 getVpnId() returns the VPN ID from the VPN name
314 public static Uint32 getVpnId(DataBroker broker, @Nullable String vpnName) {
315 if (vpnName == null) {
316 return NatConstants.INVALID_ID;
319 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
320 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
321 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
322 .instance.to.vpn.id.VpnInstance> vpnInstance =
323 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
324 LogicalDatastoreType.CONFIGURATION, id);
326 Uint32 vpnId = NatConstants.INVALID_ID;
327 if (vpnInstance.isPresent()) {
328 Uint32 vpnIdAsLong = vpnInstance.get().getVpnId();
329 if (vpnIdAsLong != null) {
336 public static Uint32 getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
337 if (vpnName == null) {
338 return NatConstants.INVALID_ID;
342 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
343 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
344 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
345 } catch (InterruptedException | ExecutionException e) {
346 LOG.error("Error retrieving VPN id for {}", vpnName, e);
349 return NatConstants.INVALID_ID;
352 public static Uint32 getNetworkVpnIdFromRouterId(DataBroker broker, Uint32 routerId) {
353 //Get the external network ID from the ExternalRouter model
354 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
355 if (networkId == null) {
356 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
357 return NatConstants.INVALID_ID;
360 //Get the VPN ID from the ExternalNetworks model
361 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
362 if (vpnUuid == null) {
363 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
364 return NatConstants.INVALID_ID;
366 Uint32 vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
370 public static Boolean validateIsIntefacePartofRouter(DataBroker broker, String routerName, String interfaceName) {
371 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
372 .map.router.interfaces.Interfaces> vmInterfaceIdentifier = getRoutersInterfacesIdentifier(routerName,
375 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
376 .map.router.interfaces.Interfaces> routerInterfacesData;
378 routerInterfacesData = SingleTransactionDataBroker.syncReadOptional(broker,
379 LogicalDatastoreType.CONFIGURATION, vmInterfaceIdentifier);
380 } catch (ReadFailedException e) {
381 LOG.error("Read Failed Exception While read RouterInterface data for router {}", routerName, e);
382 routerInterfacesData = Optional.absent();
384 if (routerInterfacesData.isPresent()) {
387 return Boolean.FALSE;
391 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
392 .rev150602.router.interfaces
393 .map.router.interfaces.Interfaces> getRoutersInterfacesIdentifier(String routerName, String interfaceName) {
394 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
395 .rev150602.RouterInterfacesMap.class)
396 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
397 .interfaces.map.RouterInterfaces.class,
398 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
399 .interfaces.map.RouterInterfacesKey(new Uuid(routerName)))
400 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
401 .map.router.interfaces.Interfaces.class,
402 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
403 .map.router.interfaces.InterfacesKey(interfaceName)).build();
406 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
407 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
408 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
409 .rev150602.RouterInterfacesMap.class)
410 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
411 .interfaces.map.RouterInterfaces.class,
412 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
413 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
416 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
417 return InstanceIdentifier.builder(FloatingIpInfo.class)
418 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
421 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
422 return InstanceIdentifier.builder(RouterToVpnMapping.class)
423 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
426 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
427 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
428 .child(Ports.class, new PortsKey(portName)).build();
431 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
433 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
434 .child(Ports.class, new PortsKey(portName))
435 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
438 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
439 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
440 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
441 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
442 .instance.to.vpn.id.VpnInstance.class,
443 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
444 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
448 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, Uint32 vpnId) {
449 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
450 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
451 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
452 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
456 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
458 public static String getFlowRef(Uint64 dpnId, short tableId, Uint32 routerID, String ip) {
459 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
460 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
461 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
464 public static String getFlowRef(Uint64 dpnId, short tableId, InetAddress destPrefix, Uint32 vpnId) {
465 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
466 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
467 .append(destPrefix.getHostAddress()).append(NatConstants.FLOWID_SEPARATOR).append(vpnId).toString();
470 public static String getNaptFlowRef(Uint64 dpnId, short tableId, String routerID, String ip,
471 int port, String protocol) {
472 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
473 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
474 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).append(NatConstants.FLOWID_SEPARATOR)
475 .append(port).append(NatConstants.FLOWID_SEPARATOR).append(protocol).toString();
479 static Uuid getNetworkIdFromRouterId(DataBroker broker, Uint32 routerId) {
480 String routerName = getRouterName(broker, routerId);
481 if (routerName == null) {
482 LOG.error("getNetworkIdFromRouterId - empty routerName received");
485 return getNetworkIdFromRouterName(broker, routerName);
489 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
490 if (routerName == null) {
491 LOG.error("getNetworkIdFromRouterName - empty routerName received");
494 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
495 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
496 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
499 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
500 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
501 .child(Routers.class, new RoutersKey(routerId)).build();
502 return routerInstanceIndentifier;
505 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Uint32 routerId) {
506 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
507 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
512 * Return if SNAT is enabled for the given router.
514 * @param broker The DataBroker
515 * @param routerId The router
516 * @return boolean true if enabled, otherwise false
518 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
519 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
520 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
521 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
525 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
526 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
527 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
528 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
532 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
534 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
535 } catch (InterruptedException | ExecutionException e) {
536 LOG.error("Error reading network VPN id for {}", networkId, e);
542 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
543 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
544 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
545 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
549 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
550 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
552 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
553 } catch (InterruptedException | ExecutionException e) {
554 LOG.error("Error retrieving provider type for {}", networkId, e);
560 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
561 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
562 Optional<Routers> routerData =
563 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
564 LogicalDatastoreType.CONFIGURATION, id);
565 if (routerData.isPresent()) {
566 Uuid networkId = routerData.get().getNetworkId();
567 if (networkId != null) {
568 return networkId.getValue();
571 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
575 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
576 return InstanceIdentifier.builder(ExternalNetworks.class)
577 .child(Networks.class, new NetworksKey(networkId)).build();
581 public static Uint64 getPrimaryNaptfromRouterId(DataBroker broker, Uint32 routerId) {
582 // convert routerId to Name
583 String routerName = getRouterName(broker, routerId);
584 if (routerName == null) {
585 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
588 return getPrimaryNaptfromRouterName(broker, routerName);
592 public static Uint64 getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
593 if (routerName == null) {
594 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
597 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
598 return (SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
599 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
600 Uint64.valueOf(0L)));
603 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
604 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
605 new RouterToNaptSwitchKey(routerId)).build();
608 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
609 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
610 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
614 public static String getRouterName(DataBroker broker, Uint32 routerId) {
615 return getVpnInstanceFromVpnIdentifier(broker, routerId);
618 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
619 return InstanceIdentifier.builder(VpnInstanceOpData.class)
620 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
623 public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, Uint64 cookie, String flowId) {
624 return new FlowEntityBuilder()
632 public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, String flowId) {
633 return new FlowEntityBuilder()
641 public static String getEndpointIpAddressForDPN(DataBroker broker, Uint64 dpnId) {
642 String nextHopIp = null;
643 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
644 InstanceIdentifier.builder(DpnEndpoints.class)
645 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
646 Optional<DPNTEPsInfo> tunnelInfo =
647 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
648 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
649 if (tunnelInfo.isPresent()) {
650 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
651 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
652 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
659 public static String getVpnRd(DataBroker broker, String vpnName) {
660 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
661 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
662 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
663 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
664 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
665 .VpnInstance::getVrfId).orElse(null);
669 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
671 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
672 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
673 .VpnInstance::getVrfId).orElse(null);
674 } catch (InterruptedException | ExecutionException e) {
675 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
681 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Uint32 routerId, String internalIpAddress,
682 String internalPort, NAPTEntryEvent.Protocol protocol) {
683 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
684 InstanceIdentifier<IpPortMap> ipPortMapId =
685 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
686 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
687 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
691 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Uint32 routerId, String internalIpAddress,
693 ProtocolTypes protocolType) {
694 return InstanceIdentifier.builder(IntextIpPortMap.class)
695 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
696 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
697 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
700 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
701 return InstanceIdentifier.builder(VpnInterfaces.class)
702 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
706 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
708 * NodeConnectorId is of form 'openflow:dpnid:portnum'
710 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
711 if (split.length != 3) {
712 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
718 public static Uint64 getDpIdFromInterface(
719 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
720 .state.Interface ifState) {
721 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
722 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
723 return Uint64.valueOf(getDpnFromNodeConnectorId(nodeConnectorId));
728 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
729 // returns only router, attached to IPv4 networks
730 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
731 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
732 Optional<VpnMap> optionalVpnMap =
733 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
734 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
735 if (!optionalVpnMap.isPresent()) {
736 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
739 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
740 if (routerIdsList != null && !routerIdsList.isEmpty()) {
741 for (Uuid routerUuid : routerIdsList) {
742 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
743 Optional<Routers> routerData =
744 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
745 LogicalDatastoreType.CONFIGURATION, id);
746 if (routerData.isPresent()) {
747 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
748 for (Uuid subnetUuid : subnetIdsList) {
749 String subnetIp = getSubnetIp(broker, subnetUuid);
750 SubnetUtils subnet = new SubnetUtils(subnetIp);
751 if (subnet.getInfo().isInRange(ipAddress)) {
752 return routerUuid.getValue();
758 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
763 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
764 Preconditions.checkNotNull(routerId, "getVpnForRouter: routerId not found!");
765 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
766 Optional<VpnMaps> optionalVpnMaps =
767 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
768 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
769 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
770 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap()) {
771 if (routerId.equals(vpnMap.getVpnId().getValue())) {
774 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
775 if (routerIdsList.isEmpty()) {
778 // Skip router vpnId fetching from internet BGP-VPN
779 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
780 // We only need to check the first network; if it’s not an external network there’s no
781 // need to check the rest of the VPN’s network list
782 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
786 if (routerIdsList.contains(new Uuid(routerId))) {
787 return vpnMap.getVpnId();
791 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
795 static Uint32 getAssociatedVpn(DataBroker broker, String routerName) {
796 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
797 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
798 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
799 NatConstants.INVALID_ID);
803 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
804 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
805 if (vpnUuid == null) {
806 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
809 return vpnUuid.getValue();
813 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
814 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
815 if (vpnUuid == null) {
816 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
819 return vpnUuid.getValue();
822 // TODO Clean up the exception handling
823 @SuppressWarnings("checkstyle:IllegalCatch")
824 public static void addPrefixToBGP(DataBroker broker,
825 IBgpManager bgpManager,
826 IFibManager fibManager,
831 @Nullable String parentVpnRd,
832 @Nullable String macAddress,
838 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
839 prefix, nextHopIp, label);
840 if (nextHopIp == null) {
841 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
846 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
847 dpId, Prefixes.PrefixCue.Nat);
849 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
850 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, label, l3vni /*l3vni*/,
851 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
852 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
853 /* Publish to Bgp only if its an INTERNET VPN */
854 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
855 VrfEntry.EncapType.Mplsgre, label, Uint32.ZERO /*l3vni*/, Uint32.ZERO /*l2vni*/,
856 null /*gatewayMac*/);
858 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
859 prefix, nextHopIp, label);
860 } catch (Exception e) {
861 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
862 prefix, nextHopIp, label, e);
866 static void addPrefixToInterface(DataBroker broker, Uint32 vpnId, @Nullable String interfaceName, String ipPrefix,
867 String networkId, Uint64 dpId, Prefixes.PrefixCue prefixCue) {
868 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
869 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
870 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
871 .to._interface.VpnIdsKey(vpnId))
872 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
873 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
874 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
875 prefixBuilder.setNetworkId(new Uuid(networkId));
877 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
878 prefixBuilder.build());
879 } catch (TransactionCommitFailedException e) {
880 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
881 ipPrefix, vpnId, dpId, e);
885 public static void deletePrefixToInterface(DataBroker broker, Uint32 vpnId, String ipPrefix) {
887 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
888 InstanceIdentifier.builder(PrefixToInterface.class)
889 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
890 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
891 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
893 } catch (TransactionCommitFailedException e) {
894 LOG.error("deletePrefixToInterface : Failed to delete prefxi-to-interface for vpn-id {}",
899 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
900 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
901 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
905 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
906 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
907 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
908 return routerInstanceIndentifier;
912 public static List<Uint16> getInternalIpPortListInfo(DataBroker dataBroker, Uint32 routerId,
913 String internalIpAddress, ProtocolTypes protocolType) {
914 List<Uint16> portList = SingleTransactionDataBroker
915 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
916 LogicalDatastoreType.CONFIGURATION,
917 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
918 IntIpProtoType::getPorts).orElse(emptyList());
920 if (!portList.isEmpty()) {
921 portList = new ArrayList<>(portList);
926 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Uint32 routerId,
927 String internalIpAddress,
928 ProtocolTypes protocolType) {
929 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
930 InstanceIdentifier.builder(SnatintIpPortMap.class)
931 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
932 .child(IpPort.class, new IpPortKey(internalIpAddress))
933 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
934 return intIpProtocolTypeId;
937 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
938 String internalIpAddress) {
939 InstanceIdentifier<IpPort> intIpProtocolTypeId =
940 InstanceIdentifier.builder(SnatintIpPortMap.class)
941 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
942 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
943 return intIpProtocolTypeId;
947 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
948 String internalIpAddress) {
949 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
950 LogicalDatastoreType.CONFIGURATION,
951 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
954 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
955 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
956 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
960 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
961 return InstanceIdentifier.create(NaptSwitches.class);
964 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
965 return InstanceIdentifier.create(NaptSwitches.class)
966 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
969 public static String getGroupIdKey(String routerName) {
970 return "snatmiss." + routerName;
973 public static Uint32 getUniqueId(IdManagerService idManager, String poolName, String idKey) {
975 AllocateIdInput getIdInput = (new AllocateIdInputBuilder()).setPoolName(poolName).setIdKey(idKey).build();
977 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
978 RpcResult<AllocateIdOutput> rpcResult = (RpcResult)result.get();
979 return rpcResult.isSuccessful() ? rpcResult.getResult().getIdValue()
980 : NatConstants.INVALID_ID;
981 } catch (InterruptedException | ExecutionException e) {
982 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
984 return NatConstants.INVALID_ID;
987 public static Uint32 releaseId(IdManagerService idManager, String poolName, String idKey) {
988 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
990 Future<RpcResult<ReleaseIdOutput>> result = idManager.releaseId(idInput);
991 if (result == null || result.get() == null || !result.get().isSuccessful()) {
992 LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}",
994 (result != null && result.get() != null) ? result.get().getErrors() : "RpcResult is null");
998 } catch (InterruptedException | ExecutionException e) {
999 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
1001 return NatConstants.INVALID_ID;
1004 // TODO Clean up the exception handling
1005 @SuppressWarnings("checkstyle:IllegalCatch")
1006 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
1007 String rd, String prefix, String vpnName) {
1009 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
1010 fibManager.removeFibEntry(rd, prefix, null, null);
1011 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
1012 bgpManager.withdrawPrefix(rd, prefix);
1014 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
1015 } catch (Exception e) {
1016 LOG.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
1017 rd, prefix, vpnName, e);
1022 public static IpPortMapping getIportMapping(DataBroker broker, Uint32 routerId) {
1023 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1024 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
1027 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(Uint32 routerId) {
1028 return InstanceIdentifier.builder(IntextIpPortMap.class)
1029 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
1032 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1033 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Uint32 routerId) {
1034 return InstanceIdentifier.builder(IntextIpMap.class)
1035 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
1036 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
1037 .intext.ip.map.IpMappingKey(routerId))
1042 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Uint32 routerId) {
1043 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1044 .ip.map.IpMapping> ipMappingOptional =
1045 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1046 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1047 // Ensure there are no duplicates
1048 Collection<String> externalIps = new HashSet<>();
1049 if (ipMappingOptional.isPresent()) {
1050 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1051 externalIps.add(ipMap.getExternalIp());
1058 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
1059 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1060 if (routerData != null) {
1061 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
1068 public static Map<String, Uint32> getExternalIpsLabelForRouter(DataBroker dataBroker, Uint32 routerId) {
1069 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1070 .ip.map.IpMapping> ipMappingOptional =
1071 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1072 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1073 Map<String, Uint32> externalIpsLabel = new HashMap<>();
1074 if (ipMappingOptional.isPresent()) {
1075 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1076 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1079 return externalIpsLabel;
1083 public static String getLeastLoadedExternalIp(DataBroker dataBroker, Uint32 segmentId) {
1084 String leastLoadedExternalIp = null;
1085 InstanceIdentifier<ExternalCounters> id =
1086 InstanceIdentifier.builder(ExternalIpsCounter.class)
1087 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1088 Optional<ExternalCounters> externalCountersData =
1089 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1090 if (externalCountersData.isPresent()) {
1091 ExternalCounters externalCounter = externalCountersData.get();
1092 short countOfLstLoadExtIp = 32767;
1093 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1094 String curExternalIp = externalIpCounter.getExternalIp();
1095 short countOfCurExtIp = externalIpCounter.getCounter().toJava();
1096 if (countOfCurExtIp < countOfLstLoadExtIp) {
1097 countOfLstLoadExtIp = countOfCurExtIp;
1098 leastLoadedExternalIp = curExternalIp;
1102 return leastLoadedExternalIp;
1105 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1107 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1108 String subnetIP = getSubnetIp(dataBroker, subnetId);
1109 if (subnetIP != null) {
1110 return getSubnetIpAndPrefix(subnetIP);
1112 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1117 public static String[] getSubnetIpAndPrefix(String subnetString) {
1118 String[] subnetSplit = subnetString.split("/");
1119 String subnetIp = subnetSplit[0];
1120 String subnetPrefix = "0";
1121 if (subnetSplit.length == 2) {
1122 subnetPrefix = subnetSplit[1];
1124 return new String[] {subnetIp, subnetPrefix};
1128 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1129 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1130 .builder(Subnetmaps.class)
1131 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1133 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1134 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1137 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1138 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1139 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1140 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1141 if (leastLoadedExtIpAddrSplit.length == 2) {
1142 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1144 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1148 public static List<Uint64> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1149 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1150 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1151 Optional<RouterDpnList> routerDpnListData =
1152 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1153 LogicalDatastoreType.OPERATIONAL, id);
1154 List<Uint64> dpns = new ArrayList<>();
1155 if (routerDpnListData.isPresent()) {
1156 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1157 dpns.add(dpnVpnInterface.getDpnId());
1163 public static Uint32 getBgpVpnId(DataBroker dataBroker, String routerName) {
1164 Uint32 bgpVpnId = NatConstants.INVALID_ID;
1165 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1166 if (bgpVpnUuid != null) {
1167 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1172 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1173 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1174 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1175 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1178 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1179 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1180 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1181 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1182 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1183 .RouterInterface.class,
1184 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1185 .RouterInterfaceKey(interfaceName)).build();
1188 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, Uint64 dpId,
1189 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1191 if (dpId.equals(Uint64.ZERO)) {
1192 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1193 + "to handle router {} association model", interfaceName, routerName);
1197 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1198 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1199 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1201 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1202 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1203 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1204 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1205 .setInterface(interfaceName).build();
1206 if (optionalDpnVpninterfacesList.isPresent()) {
1207 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1208 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1209 operTx.merge(dpnVpnInterfacesListIdentifier
1210 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1211 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1212 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1214 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1215 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1216 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1217 routerDpnListBuilder.setRouterId(routerName);
1218 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1219 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1220 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1221 routerInterfaces.add(routerInterface);
1222 dpnVpnList.setRouterInterfaces(routerInterfaces);
1223 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1224 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1228 public static void addToDpnRoutersMap(String routerName, String interfaceName, Uint64 dpId,
1229 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1230 if (dpId.equals(Uint64.ZERO)) {
1231 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1232 + "association model", interfaceName, routerName);
1236 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1237 + "DPNRouters map", dpId, routerName, interfaceName);
1238 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1240 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1242 if (optionalDpnRoutersList.isPresent()) {
1243 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1244 .setRouter(routerName).build();
1245 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1246 if (!routersListFromDs.contains(routersList)) {
1247 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1248 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1249 operTx.merge(dpnRoutersListIdentifier
1250 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1252 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1253 + "DPNRouters map", routerName, dpId);
1256 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1257 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1258 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1259 dpnRoutersListBuilder.setDpnId(dpId);
1260 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1261 routersListBuilder.setRouter(routerName);
1262 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1263 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1267 public static void removeFromNeutronRouterDpnsMap(String routerName, Uint64 dpId,
1268 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1269 if (dpId.equals(Uint64.ZERO)) {
1270 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1274 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1275 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1276 if (optionalRouterDpnList.isPresent()) {
1277 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1278 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1279 operTx.delete(routerDpnListIdentifier);
1281 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1282 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1286 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1287 Uint64 dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1288 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1289 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1291 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1292 } catch (InterruptedException | ExecutionException e) {
1293 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1294 optionalRouterDpnList = Optional.absent();
1296 if (optionalRouterDpnList.isPresent()) {
1297 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1298 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1299 new ArrayList<>(optionalRouterDpnList.get().nonnullRouterInterfaces());
1300 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1301 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1302 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1303 .setInterface(vpnInterfaceName).build();
1305 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1306 if (routerInterfaces.isEmpty()) {
1307 operTx.delete(routerDpnListIdentifier);
1309 operTx.delete(routerDpnListIdentifier.child(
1310 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1311 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1312 new RouterInterfacesKey(vpnInterfaceName)));
1318 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1319 Uint64 curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1320 throws ExecutionException, InterruptedException {
1322 1) Get the DpnRoutersList for the DPN.
1323 2) Get the RoutersList identifier for the DPN and router.
1324 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1325 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1326 then remove RouterList.
1329 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1330 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1332 //Get the dpn-routers-list instance for the current DPN.
1333 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1334 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1336 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1337 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1338 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1342 //Get the routers-list instance for the router on the current DPN only
1343 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1344 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1346 if (routersListData == null || !routersListData.isPresent()) {
1347 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1348 + "in the ODL-L3VPN:dpn-routers model",
1353 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1354 + "from the NeutronVPN - router-interfaces-map", routerName);
1355 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1356 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1357 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1358 .RouterInterfaces> routerInterfacesData =
1359 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1360 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1362 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1363 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1364 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1365 curDpnId, routerName, routerName);
1366 operTx.delete(routersListIdentifier);
1370 //Get the VM interfaces for the router on the current DPN only.
1371 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1372 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1373 if (vmInterfaces == null) {
1374 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1375 + "NeutronVPN - router-interfaces-map", routerName);
1379 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1380 // then remove RouterList.
1381 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1382 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1383 String vmInterfaceName = vmInterface.getInterfaceId();
1384 Uint64 vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1385 if (vmDpnId.equals(Uint64.ZERO) || !vmDpnId.equals(curDpnId)) {
1386 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1387 + "the DPN ID {} for the checked interface {}",
1388 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1391 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1392 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1393 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1397 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1398 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1399 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1400 operTx.delete(routersListIdentifier);
1403 private static InstanceIdentifier<RoutersList> getRoutersList(Uint64 dpnId, String routerName) {
1404 return InstanceIdentifier.builder(DpnRouters.class)
1405 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1406 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1409 public static Uint64 getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1410 Uint64 nodeId = Uint64.ZERO;
1412 GetDpidFromInterfaceInput
1414 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1415 Future<RpcResult<GetDpidFromInterfaceOutput>>
1417 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1418 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1419 if (dpIdResult.isSuccessful()) {
1420 nodeId = dpIdResult.getResult().getDpid();
1422 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1424 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1425 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1431 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1432 ItmRpcService itmRpcService,
1433 IInterfaceManager interfaceManager, String ifName,
1434 Uint32 tunnelKey, boolean internalTunnelInterface) {
1435 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1436 ifName, tunnelKey, 0, internalTunnelInterface);
1440 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1441 ItmRpcService itmRpcService,
1442 IInterfaceManager interfaceManager,
1443 String ifName, @Nullable Uint32 tunnelKey, int pos,
1444 boolean internalTunnelInterface) {
1445 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1446 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1447 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1448 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1449 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1450 if (tunnelKey != null) {
1451 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1452 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1453 } //init builders, ITM/IFM rpc can be called based on type of interface
1456 List<Action> actions = emptyList();
1457 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1458 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1459 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1460 if (!rpcResult.isSuccessful()) {
1461 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1462 + "returned with Errors {}", ifName, rpcResult.getErrors());
1464 actions = rpcResult.getResult().nonnullAction();
1467 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1468 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1469 if (!rpcResult.isSuccessful()) {
1470 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1471 + "returned with Errors {}", ifName, rpcResult.getErrors());
1473 actions = rpcResult.getResult().nonnullAction();
1476 List<ActionInfo> listActionInfo = new ArrayList<>();
1477 for (Action action : actions) {
1478 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1479 actionClass = action.getAction();
1480 if (actionClass instanceof OutputActionCase) {
1481 listActionInfo.add(new ActionOutput(pos++,
1482 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1483 } else if (actionClass instanceof PushVlanActionCase) {
1484 listActionInfo.add(new ActionPushVlan(pos++));
1485 } else if (actionClass instanceof SetFieldCase) {
1486 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1487 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1488 .getVlanId().getValue().toJava();
1489 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1491 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1492 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable().toJava();
1493 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1494 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1495 NxRegLoad nxRegLoad =
1496 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1497 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart().toJava(),
1498 nxRegLoad.getDst().getEnd().toJava(), nxRegLoad.getValue().longValue()));
1501 return listActionInfo;
1502 } catch (InterruptedException | ExecutionException e) {
1503 LOG.error("Exception when egress actions for interface {}", ifName, e);
1505 LOG.error("Error when getting egress actions for interface {}", ifName);
1510 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1511 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1515 public static List<Port> getNeutronPorts(DataBroker broker) {
1516 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1517 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1518 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1519 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1521 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1522 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1524 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1525 LOG.error("getNeutronPorts : No neutron ports found");
1529 return portsOptional.get().getPort();
1533 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1534 List<Port> ports = getNeutronPorts(
1537 for (Port port : ports) {
1538 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1539 for (FixedIps ip : port.getFixedIps()) {
1540 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1546 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1551 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1553 LOG.error("getSubnetIdForFloatingIp : port is null");
1556 for (FixedIps ip : port.nonnullFixedIps()) {
1557 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1558 return ip.getSubnetId();
1561 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1566 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1567 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1568 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1569 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1570 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1574 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1575 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1576 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1577 List<Uuid> subnetIdList = SingleTransactionDataBroker
1578 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1579 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1581 if (!subnetIdList.isEmpty()) {
1582 subnetIdList = new ArrayList<>(subnetIdList);
1585 return subnetIdList;
1589 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1590 if (subnetId == null) {
1591 LOG.error("getSubnetGwMac : subnetID is null");
1595 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1596 .child(Subnet.class, new SubnetKey(subnetId));
1597 Optional<Subnet> subnetOpt =
1598 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1599 LogicalDatastoreType.CONFIGURATION, subnetInst);
1600 if (!subnetOpt.isPresent()) {
1601 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1605 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1606 if (gatewayIp == null) {
1607 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1611 if (null != gatewayIp.getIpv6Address()) {
1615 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1616 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1618 Optional<VpnPortipToPort> portIpToPortOpt =
1619 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1620 LogicalDatastoreType.CONFIGURATION, portIpInst);
1621 if (portIpToPortOpt.isPresent()) {
1622 return portIpToPortOpt.get().getMacAddress();
1625 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1626 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1628 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1629 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1630 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1631 if (learntIpToPortOpt.isPresent()) {
1632 return learntIpToPortOpt.get().getMacAddress();
1635 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1639 public static boolean isIPv6Subnet(String prefix) {
1640 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1643 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(Uint64 dpnId) {
1644 return InstanceIdentifier.builder(DpnRouters.class)
1645 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1648 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, Uint64 dpnId) {
1649 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1650 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1651 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1654 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1655 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1656 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1660 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1661 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1662 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1663 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1664 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1668 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1669 Uuid floatingIpId) {
1671 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1672 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1673 } catch (InterruptedException | ExecutionException e) {
1674 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1680 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1681 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1682 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1683 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1684 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1688 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1689 Uuid floatingIpId) {
1691 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1692 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1693 } catch (InterruptedException | ExecutionException e) {
1694 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1699 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1700 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1701 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1705 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1706 InstanceIdentifier<Interface> ifStateId =
1707 buildStateInterfaceId(interfaceName);
1708 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1709 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1712 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1713 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1714 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1715 .interfaces.rev140508.InterfacesState.class)
1716 .child(Interface.class,
1717 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1718 .interfaces.state.InterfaceKey(interfaceName));
1719 return idBuilder.build();
1723 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1724 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1725 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1726 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1730 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1732 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1733 } catch (InterruptedException | ExecutionException e) {
1734 LOG.error("Error reading router {}", routerName, e);
1739 static void createRouterIdsConfigDS(DataBroker dataBroker, Uint32 routerId, String routerName) {
1740 if (routerId == NatConstants.INVALID_ID) {
1741 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1744 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1745 .setRouterId(routerId).setRouterName(routerName).build();
1746 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1750 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(Uint64 dpId, Uint32 vpnId, String subnetId,
1751 IdManagerService idManager) {
1752 InetAddress defaultIP = null;
1754 defaultIP = InetAddress.getByName("0.0.0.0");
1755 } catch (UnknownHostException e) {
1756 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1757 + "Default Route to NAT.", e);
1761 List<MatchInfo> matches = new ArrayList<>();
1762 matches.add(MatchEthernetType.IPV4);
1763 //add match for vrfid
1764 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
1765 MetaDataUtil.METADATA_MASK_VRFID));
1767 List<InstructionInfo> instructions = new ArrayList<>();
1768 List<ActionInfo> actionsInfo = new ArrayList<>();
1769 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(subnetId));
1770 if (groupId == NatConstants.INVALID_ID) {
1771 LOG.error("Unable to get groupId for subnet {} while building defauly flow entity", subnetId);
1774 actionsInfo.add(new ActionGroup(groupId.longValue()));
1775 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1776 instructions.add(new InstructionApplyActions(actionsInfo));
1777 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1778 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1779 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1783 static String getExtGwMacAddFromRouterId(DataBroker broker, Uint32 routerId) {
1784 String routerName = getRouterName(broker, routerId);
1785 if (routerName == null) {
1786 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1789 return getExtGwMacAddFromRouterName(broker, routerName);
1793 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1794 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1795 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1796 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1800 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1802 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1803 Routers::getExtGwMacAddress).orElse(null);
1804 } catch (InterruptedException | ExecutionException e) {
1805 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1810 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1811 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1812 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1813 .child(Router.class, new RouterKey(routerUuid));
1814 return routerInstanceIdentifier;
1818 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1819 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1820 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1821 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1826 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1827 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1828 List<Ports> portsList = SingleTransactionDataBroker
1829 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION,
1830 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1831 if (!portsList.isEmpty()) {
1832 portsList = new ArrayList<>(portsList);
1838 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1839 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1840 Optional<ExternalNetworks> externalNwData =
1841 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1842 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1843 if (externalNwData.isPresent()) {
1844 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1845 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1846 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1847 return routerIds != null ? new ArrayList<>(routerIds) : emptyList();
1854 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1857 long ipLo = ipToLong(InetAddress.getByName(start));
1858 long ipHi = ipToLong(InetAddress.getByName(end));
1859 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1860 return ipToTest >= ipLo && ipToTest <= ipHi;
1861 } catch (UnknownHostException e) {
1862 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1868 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1869 if (externalIps == null) {
1870 return Collections.emptySet();
1873 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1877 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1878 if (routerName == null) {
1879 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1880 return Collections.emptySet();
1883 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1884 Optional<Routers> routerData =
1885 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1886 LogicalDatastoreType.CONFIGURATION, id);
1887 if (routerData.isPresent()) {
1888 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1890 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1891 return Collections.emptySet();
1896 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1897 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1898 if (subnetId == null) {
1899 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1900 return Optional.absent();
1903 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1904 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1905 InstanceIdentifier.builder(ExternalSubnets.class)
1906 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1907 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1908 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1909 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1913 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1914 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1915 if (subnetId == null) {
1916 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1917 return Optional.absent();
1920 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1921 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1922 InstanceIdentifier.builder(ExternalSubnets.class)
1923 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1924 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1926 return tx.read(subnetsIdentifier).get();
1927 } catch (InterruptedException | ExecutionException e) {
1928 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1929 return Optional.absent();
1933 protected static Uint32 getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1934 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1935 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1937 if (optionalExternalSubnets.isPresent()) {
1938 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1941 return NatConstants.INVALID_ID;
1944 protected static Uint32 getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1945 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1946 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1948 if (optionalExternalSubnets.isPresent()) {
1949 return NatUtil.getVpnId(tx, subnetId.getValue());
1952 return NatConstants.INVALID_ID;
1955 protected static Uint32 getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1957 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1958 if (externalSubnetId != null) {
1959 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1962 return NatConstants.INVALID_ID;
1966 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1967 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1968 for (ExternalIps extIp : router.nonnullExternalIps()) {
1969 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1970 if (extIpString.equals(externalIpAddress)) {
1971 return extIp.getSubnetId();
1974 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1978 private static long ipToLong(InetAddress ip) {
1979 byte[] octets = ip.getAddress();
1981 for (byte octet : octets) {
1983 result |= octet & 0xff;
1989 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1990 if (externalIps == null) {
1994 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1997 // elan-instances config container
1999 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
2000 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
2001 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2002 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
2006 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
2008 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
2009 } catch (InterruptedException | ExecutionException e) {
2010 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
2015 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
2016 return InstanceIdentifier.builder(ElanInstances.class)
2017 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
2020 public static Uint64 getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
2021 IElanService elanManager, IdManagerService idManager,
2022 Uint32 routerId, String routerName) {
2023 if (elanManager.isOpenStackVniSemanticsEnforced()) {
2024 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
2025 return natOverVxlanUtil.getRouterVni(routerName, routerId);
2027 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
2031 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, Uint64 naptDpnId,
2032 short tableId, TypedWriteTransaction<Configuration> confTx) {
2033 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2034 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
2036 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
2037 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
2038 List<MatchInfo> matches = new ArrayList<>();
2039 matches.add(MatchEthernetType.IPV4);
2040 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2041 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
2042 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
2043 matches, preDnatToSnatInstructions);
2045 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
2046 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
2047 preDnatToSnatTableFlowEntity, naptDpnId);
2050 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
2051 IMdsalApiManager mdsalManager, Uint64 naptDpnId) throws ExecutionException, InterruptedException {
2052 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2053 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
2054 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2055 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
2056 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
2057 flowRef, naptDpnId);
2060 private static String getFlowRefPreDnatToSnat(Uint64 dpnId, short tableId, String uniqueId) {
2061 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
2062 + NwConstants.FLOWID_SEPARATOR + uniqueId;
2065 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, Uint64 dpnId, String rd,
2066 String vpnName, String externalIp,
2067 Boolean isMoreThanOneFipCheckOnDpn) {
2068 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
2069 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
2070 if (dpnInVpn.isPresent()) {
2071 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2072 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2074 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2075 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2076 int floatingIpPresentCount = 0;
2077 for (IpAddresses ipAddress: ipAddressList) {
2078 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2079 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2080 floatingIpPresentCount++;
2081 //Add tunnel table check
2082 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2085 //Remove tunnel table check
2086 if (!isMoreThanOneFipCheckOnDpn) {
2092 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2096 } catch (NullPointerException e) {
2097 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2098 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2105 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, Uint64 dpnId) {
2106 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2107 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2108 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2112 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2113 throws ExecutionException, InterruptedException {
2114 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2118 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2119 if (vpnInstance == null) {
2122 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2123 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2126 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2127 return InstanceIdentifier.builder(VpnInstances.class)
2128 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2132 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2133 return vpnInstance.getRouteDistinguisher() != null ? new ArrayList<>(
2134 vpnInstance.getRouteDistinguisher()) : new ArrayList<>();
2137 public static String validateAndAddNetworkMask(String ipAddress) {
2138 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2141 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2142 String vpnInterfaceName, String vpnName) {
2143 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2144 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2147 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2148 String routerName, Uint64 dpnId) {
2149 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2150 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2152 if (networkData != null && networkData.isPresent()) {
2153 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2154 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2155 for (Uuid routerUuid : routerUuidList) {
2156 String sharedRouterName = routerUuid.getValue();
2157 if (!routerName.equals(sharedRouterName)) {
2158 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2159 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2160 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2161 + "associated with other active router {} on NAPT switch {}", networkId,
2162 sharedRouterName, switchDpnId);
2172 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2173 String routerName, Uint64 dpnId) {
2174 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2175 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2176 .subnets.Subnets::getRouterIds).orElse(emptyList());
2177 if (!routerUuidList.isEmpty()) {
2178 for (Uuid routerUuid : routerUuidList) {
2179 String sharedRouterName = routerUuid.getValue();
2180 if (!routerName.equals(sharedRouterName)) {
2181 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2182 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2183 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2184 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2185 sharedRouterName, switchDpnId);
2194 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2195 Routers router, Uint64 primarySwitchId, int addOrRemove) {
2196 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2197 List<ExternalIps> externalIps = router.getExternalIps();
2198 List<String> externalIpsSting = new ArrayList<>();
2200 if (externalIps == null || externalIps.isEmpty()) {
2201 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2204 for (ExternalIps externalIp : externalIps) {
2205 externalIpsSting.add(externalIp.getIpAddress());
2207 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2208 if (addOrRemove == NwConstants.ADD_FLOW) {
2209 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2210 router.getNetworkId(), subnetVpnName.getValue(), tx);
2211 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2212 router.getExtGwMacAddress(), primarySwitchId,
2213 router.getNetworkId());
2215 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2216 router.getNetworkId(), subnetVpnName.getValue(), tx);
2217 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2218 router.getExtGwMacAddress(), primarySwitchId,
2219 router.getNetworkId());
2221 }), LOG, "Error installing router gateway flows");
2224 @SuppressWarnings("checkstyle:IllegalCatch")
2225 public static void handleSNATForDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2226 IdManagerService idManager, NaptSwitchHA naptSwitchHA,
2227 Uint64 dpnId, Routers extRouters, Uint32 routerId, Uint32 routerVpnId,
2228 TypedReadWriteTransaction<Configuration> confTx,
2229 ProviderTypes extNwProvType, UpgradeState upgradeState) {
2230 //Check if primary and secondary switch are selected, If not select the role
2231 //Install select group to NAPT switch
2232 //Install default miss entry to NAPT switch
2234 String routerName = extRouters.getRouterName();
2235 Boolean upgradeInProgress = false;
2236 if (upgradeState != null) {
2237 upgradeInProgress = upgradeState.isUpgradeInProgress();
2239 Uint64 naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2240 if (naptId == null || naptId.equals(Uint64.ZERO)
2241 || (!NatUtil.getSwitchStatus(dataBroker, naptId) && (upgradeInProgress == false))) {
2242 LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}",
2243 routerName, naptId);
2245 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
2247 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
2248 naptSwitch, routerName);
2251 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
2253 String externalVpnName = null;
2254 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
2255 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
2256 Uuid extNwUuid = extRouters.getNetworkId();
2257 externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNwUuid);
2258 if (externalVpnName != null) {
2259 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, extNwUuid,
2260 externalVpnName, confTx);
2262 // Install miss entry (table 26) pointing to table 46
2263 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
2264 routerVpnId, NatConstants.ADD_FLOW);
2265 if (flowEntity == null) {
2266 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
2270 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
2271 mdsalManager.addFlow(confTx, flowEntity);
2272 //Removing primary flows from old napt switch
2273 if (naptId != null && !naptId.equals(Uint64.ZERO)) {
2274 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
2275 naptId, routerName);
2277 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouters, routerId, naptId, null,
2278 externalVpnName, confTx);
2279 } catch (Exception e) {
2280 LOG.error("Exception while removing SnatFlows form OldNaptSwitch {}", naptId, e);
2283 naptSwitchHA.updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
2284 } else if (naptId.equals(dpnId)) {
2285 LOG.error("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
2287 naptSwitch = naptId;
2288 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
2289 naptId, routerName);
2292 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
2293 routerName, routerId, naptSwitch);
2294 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
2296 // Install miss entry (table 26) pointing to group
2297 Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
2298 NatUtil.getGroupIdKey(routerName));
2299 if (groupId != NatConstants.INVALID_ID) {
2300 FlowEntity flowEntity =
2301 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId.longValue(),
2302 routerVpnId, NatConstants.ADD_FLOW);
2303 if (flowEntity == null) {
2304 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}"
2305 + " groupId {}", routerName, dpnId, groupId);
2308 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
2309 dpnId, routerName, groupId);
2310 mdsalManager.addFlow(confTx, flowEntity);
2312 LOG.error("handleSNATForDPN: Unable to get groupId for router:{}", routerName);
2317 @SuppressWarnings("checkstyle:IllegalCatch")
2318 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2319 IdManagerService idManager, NaptSwitchHA naptSwitchHA, Uint64 dpnId,
2320 Routers extRouter, Uint32 routerId, Uint32 routerVpnId, String externalVpnName,
2321 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2322 throws ExecutionException, InterruptedException {
2323 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2324 //remove miss entry to NAPT switch
2325 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2326 if (extNwProvType == null) {
2329 String routerName = extRouter.getRouterName();
2330 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2331 Map<String, Uint32> externalIpLabel;
2332 if (extNwProvType == ProviderTypes.VXLAN) {
2333 externalIpLabel = null;
2335 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2337 Uint64 naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2338 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2339 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2342 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2343 boolean naptStatus =
2344 naptSwitchHA.isNaptSwitchDown(extRouter, routerId, dpnId, naptSwitch, routerVpnId,
2345 externalIpCache, confTx);
2347 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2349 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
2350 FlowEntity flowEntity = null;
2352 if (groupId != NatConstants.INVALID_ID) {
2353 flowEntity = naptSwitchHA
2354 .buildSnatFlowEntity(dpnId, routerName, groupId.longValue(), routerVpnId,
2355 NatConstants.DEL_FLOW);
2356 if (flowEntity == null) {
2357 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2358 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2361 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}",
2363 mdsalManager.removeFlow(confTx, flowEntity);
2365 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2368 } catch (Exception ex) {
2369 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2373 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2377 GroupEntity groupEntity = null;
2379 if (groupId != NatConstants.INVALID_ID) {
2380 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId.longValue(), routerName,
2381 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2382 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2383 mdsalManager.removeGroup(groupEntity);
2385 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2387 } catch (Exception ex) {
2388 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2391 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2394 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouter, routerId, naptSwitch,
2395 externalIpLabel, externalVpnName, confTx);
2396 //remove table 26 flow ppointing to table46
2397 FlowEntity flowEntity = null;
2399 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2400 NatConstants.DEL_FLOW);
2401 if (flowEntity == null) {
2402 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2406 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2407 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2408 mdsalManager.removeFlow(confTx, flowEntity);
2410 } catch (Exception ex) {
2411 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2415 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2418 //best effort to check IntExt model
2419 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2423 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2424 ProviderTypes extNwProvType) {
2425 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2426 || extNwProvType == ProviderTypes.VXLAN)) {
2432 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2433 Uint64 dpnId, DataBroker dataBroker) {
2434 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2435 elanInstanceName, dpnId);
2436 // FIXME: separate this out?
2437 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2440 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2441 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2442 List<String> elanInterfaceList = new ArrayList<>();
2443 DpnInterfaces dpnInterface;
2444 if (dpnInElanInterfaces.isPresent()) {
2445 dpnInterface = dpnInElanInterfaces.get();
2447 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2448 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2450 if (!elanInterfaceList.contains(pseudoPortId)) {
2451 elanInterfaceList.add(pseudoPortId);
2452 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2453 .withKey(new DpnInterfacesKey(dpnId)).build();
2454 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2455 elanDpnInterfaceId, dpnInterface);
2457 } catch (ReadFailedException e) {
2458 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2459 } catch (TransactionCommitFailedException e) {
2460 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2466 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2467 Uint64 dpnId, DataBroker dataBroker) {
2468 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2469 elanInstanceName, dpnId);
2470 // FIXME: separate this out?
2471 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2474 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2475 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2476 List<String> elanInterfaceList = new ArrayList<>();
2477 DpnInterfaces dpnInterface;
2478 if (!dpnInElanInterfaces.isPresent()) {
2479 LOG.info("No interface in any dpn for {}", elanInstanceName);
2483 dpnInterface = dpnInElanInterfaces.get();
2484 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2485 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2486 if (!elanInterfaceList.contains(pseudoPortId)) {
2487 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2490 elanInterfaceList.remove(pseudoPortId);
2491 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2492 .withKey(new DpnInterfacesKey(dpnId)).build();
2493 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2494 elanDpnInterfaceId, dpnInterface);
2495 } catch (ReadFailedException e) {
2496 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2497 } catch (TransactionCommitFailedException e) {
2498 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2504 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2505 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2506 for (Map.Entry<String,Routers> router : extRouter) {
2507 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2508 .equals(networkid)) {
2516 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2518 return SingleTransactionDataBroker.syncRead(dataBroker,
2519 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2521 catch (ReadFailedException e) {
2522 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2527 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2528 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2529 .builder(LearntVpnVipToPortData.class).build();
2530 return learntVpnVipToPortDataId;
2533 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2535 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2536 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2537 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2540 public static InstanceIdentifier<Group> getGroupInstanceId(Uint64 dpnId, Uint32 groupId) {
2541 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2542 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2543 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2546 public static void createGroupIdPool(IdManagerService idManager) {
2547 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2548 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2549 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2550 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2553 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2554 if (result != null && result.get().isSuccessful()) {
2555 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2557 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2559 } catch (InterruptedException | ExecutionException e) {
2560 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2564 public static boolean getSwitchStatus(DataBroker broker, Uint64 switchId) {
2565 NodeId nodeId = new NodeId("openflow:" + switchId);
2566 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2567 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2568 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2569 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2570 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2571 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2572 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2573 if (nodeOptional.isPresent()) {
2574 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2577 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2581 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2582 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2583 Optional<Networks> networkData =
2584 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2585 broker, LogicalDatastoreType.CONFIGURATION, id);
2586 return networkData.isPresent();
2590 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2591 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2592 if (null != elanInstance) {
2593 return elanInstance.getPhysicalNetworkName();
2599 public static Map<String, String> getOpenvswitchOtherConfigMap(Uint64 dpnId, DataBroker dataBroker) {
2600 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2601 return getMultiValueMap(otherConfigVal);
2604 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2605 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2606 return Collections.emptyMap();
2609 Map<String, String> valueMap = new HashMap<>();
2610 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2611 for (String keyValue : splitter.split(multiKeyValueStr)) {
2612 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2613 if (split.length == 2) {
2614 valueMap.put(split[0], split[1]);
2621 public static Optional<Node> getBridgeRefInfo(Uint64 dpnId, DataBroker dataBroker) {
2622 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2623 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2625 Optional<BridgeRefEntry> bridgeRefEntry =
2626 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2627 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2628 if (!bridgeRefEntry.isPresent()) {
2629 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2630 return Optional.absent();
2633 InstanceIdentifier<Node> nodeId =
2634 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2636 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2637 LogicalDatastoreType.OPERATIONAL, nodeId);
2641 public static String getProviderMappings(Uint64 dpId, DataBroker dataBroker) {
2642 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2643 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2647 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2648 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2649 if (ovsdbNode == null) {
2650 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2651 if (nodeFromReadOvsdbNode.isPresent()) {
2652 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2656 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2657 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2658 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2659 return openvswitchOtherConfigs.getOtherConfigValue();
2663 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2668 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2669 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2670 if (bridgeAugmentation != null) {
2671 InstanceIdentifier<Node> ovsdbNodeIid =
2672 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2673 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2674 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2676 return Optional.absent();
2681 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2685 return node.augmentation(OvsdbBridgeAugmentation.class);
2688 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, Uint64 dpnId) {
2689 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2692 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2693 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2694 InstanceIdentifier.builder(ExternalSubnets.class)
2697 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2698 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2699 if (optionalExternalSubnets.isPresent()) {
2700 return optionalExternalSubnets.get();
2702 } catch (ReadFailedException e) {
2703 LOG.error("Failed to read the subnets from the datastore.");
2709 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2710 Uint64 dpId, short tableId, String flowId, int priority, String flowName, Uint64 cookie,
2711 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2712 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2713 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2715 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2716 mdsalManager.addFlow(confTx, flowEntity);
2719 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2720 Uint64 dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2721 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2722 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2725 public static String getIpv6FlowRef(Uint64 dpnId, short tableId, Uint32 routerID) {
2726 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2727 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2730 public static String getTunnelInterfaceName(Uint64 srcDpId, Uint64 dstDpId,
2731 ItmRpcService itmManager) {
2732 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2733 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2735 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2736 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2737 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2738 rpcResult = result.get();
2739 if (!rpcResult.isSuccessful()) {
2740 tunType = TunnelTypeGre.class ;
2741 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2742 .setSourceDpid(srcDpId)
2743 .setDestinationDpid(dstDpId)
2744 .setTunnelType(tunType)
2746 rpcResult = result.get();
2747 if (!rpcResult.isSuccessful()) {
2748 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2749 rpcResult.getErrors());
2751 return rpcResult.getResult().getInterfaceName();
2753 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2754 rpcResult.getErrors());
2756 return rpcResult.getResult().getInterfaceName();
2758 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2759 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2760 + "between {} and {}", srcDpId, dstDpId);
2765 public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) {
2766 Port neutronPort = getNeutronPort(broker, ifaceName);
2767 if (neutronPort == null) {
2768 return Boolean.TRUE;
2770 return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE
2775 private static Port getNeutronPort(DataBroker broker, String ifaceName) {
2776 InstanceIdentifier<Port>
2777 portsIdentifier = InstanceIdentifier.create(Neutron.class)
2779 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class)
2780 .child(Port.class, new PortKey(new Uuid(ifaceName)));
2781 Optional<Port> portsOptional;
2783 portsOptional = SingleTransactionDataBroker
2784 .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
2785 } catch (ReadFailedException e) {
2786 LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e);
2787 portsOptional = Optional.absent();
2789 if (!portsOptional.isPresent()) {
2790 LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName);
2793 return portsOptional.get();
2796 public static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
2797 .instance.to.vpn.id.VpnInstance getVpnIdToVpnInstance(DataBroker broker, String vpnName) {
2798 if (vpnName == null) {
2802 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2803 .vpn.instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
2804 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2805 .vpn.instance.to.vpn.id.VpnInstance> vpnInstance = Optional.absent();
2807 vpnInstance = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, id);
2808 } catch (ReadFailedException e) {
2809 LOG.error("Failed to read VpnInstance {}", vpnInstance, e);
2811 if (vpnInstance.isPresent()) {
2812 return vpnInstance.get();
2818 public static Uint32 getExternalVpnIdForExtNetwork(DataBroker broker, Uuid externalNwUuid) {
2819 //Get the VPN ID from the ExternalNetworks model
2820 if (externalNwUuid == null) {
2821 LOG.error("getExternalVpnIdForExtNetwork : externalNwUuid is null");
2824 Uuid vpnUuid = getVpnIdfromNetworkId(broker, externalNwUuid);
2825 if (vpnUuid == null) {
2826 LOG.error("NAT Service : vpnUuid is null");
2829 Uint32 vpnId = getVpnId(broker, vpnUuid.getValue());
2833 static ReentrantLock lockForNat(final Uint64 dataPath) {
2834 // FIXME: wrap this in an Identifier
2835 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
2838 public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
2839 IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
2840 String interfaceName, String routerName) {
2841 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
2842 if (routerId == NatConstants.INVALID_ID) {
2843 LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
2846 Uint64 naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
2847 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2848 LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
2849 + "with Id {}", routerName, routerId);
2852 //getInternalIp for port
2853 List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
2854 if (fixedIps == null) {
2855 LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
2856 interfaceName, routerName, routerId);
2859 List<ProtocolTypes> protocolTypesList = getPortocolList();
2860 for (String internalIp : fixedIps) {
2861 LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
2862 interfaceName, internalIp, routerId);
2863 for (ProtocolTypes protocol : protocolTypesList) {
2864 List<Uint16> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
2865 if (portList != null) {
2866 for (Uint16 portnum : portList) {
2867 //build and remove the flow in outbound table
2868 removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
2869 routerId, internalIp, portnum.toJava(), protocol.getName());
2871 //build and remove the flow in inboundtable
2873 removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
2874 internalIp, portnum.toJava(), protocol.getName());
2876 //Get the external IP address and the port from the model
2878 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
2879 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
2880 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
2881 internalIp, String.valueOf(portnum.toJava()), proto);
2882 if (ipPortExternal == null) {
2883 LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
2884 + "with port {} is not found in "
2885 + "router with Id {}", internalIp, portnum, routerId);
2888 String externalIpAddress = ipPortExternal.getIpAddress();
2889 String internalIpPort = internalIp + ":" + portnum.toJava();
2890 // delete the entry from IntExtIpPortMap DS
2892 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
2893 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
2897 LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
2898 + "in router with id {}",
2899 protocol, interfaceName, internalIp, routerId);
2902 // delete the entry from SnatIntIpPortMap DS
2903 LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
2904 internalIp, routerId);
2905 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
2909 private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
2910 LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
2912 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
2913 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
2914 .setPortId(new Uuid(interfname)).build());
2916 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
2917 if (!rpcResult.isSuccessful()) {
2918 LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
2919 rpcResult.getErrors());
2921 return rpcResult.getResult().getFixedIPs();
2923 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
2924 LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
2929 private static List<ProtocolTypes> getPortocolList() {
2930 List<ProtocolTypes> protocollist = new ArrayList<>();
2931 protocollist.add(ProtocolTypes.TCP);
2932 protocollist.add(ProtocolTypes.UDP);
2933 return protocollist;
2936 private static void removeNatFlow(IMdsalApiManager mdsalManager, Uint64 dpnId, short tableId, Uint32 routerId,
2937 String ipAddress, int ipPort, String protocol) {
2939 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
2941 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
2943 mdsalManager.removeFlow(snatFlowEntity);
2944 LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
2945 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
2948 public static String getDpnFromNodeRef(NodeRef node) {
2949 PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
2950 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
2951 InstanceIdentifier.IdentifiableItem.class);
2952 NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
2953 String dpnKey = key.getId().getValue();
2954 String dpnID = null;
2955 if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
2956 dpnID = Uint64.valueOf(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();