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.genius.infra.Datastore.CONFIGURATION;
12 import static org.opendaylight.mdsal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
14 import com.google.common.base.Preconditions;
15 import com.google.common.base.Splitter;
16 import com.google.common.base.Strings;
17 import com.google.common.collect.Iterables;
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import java.math.BigInteger;
20 import java.net.InetAddress;
21 import java.net.UnknownHostException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
29 import java.util.Objects;
30 import java.util.Optional;
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.sal.common.util.Arguments;
40 import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
41 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
42 import org.opendaylight.genius.infra.Datastore.Configuration;
43 import org.opendaylight.genius.infra.Datastore.Operational;
44 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
45 import org.opendaylight.genius.infra.TypedReadTransaction;
46 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
47 import org.opendaylight.genius.infra.TypedWriteTransaction;
48 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
49 import org.opendaylight.genius.mdsalutil.ActionInfo;
50 import org.opendaylight.genius.mdsalutil.BucketInfo;
51 import org.opendaylight.genius.mdsalutil.FlowEntity;
52 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
53 import org.opendaylight.genius.mdsalutil.GroupEntity;
54 import org.opendaylight.genius.mdsalutil.InstructionInfo;
55 import org.opendaylight.genius.mdsalutil.MDSALUtil;
56 import org.opendaylight.genius.mdsalutil.MatchInfo;
57 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
58 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
59 import org.opendaylight.genius.mdsalutil.NwConstants;
60 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
61 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
62 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
63 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
64 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
65 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
66 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
67 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
68 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
69 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
70 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
71 import org.opendaylight.genius.utils.JvmGlobalLocks;
72 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
73 import org.opendaylight.mdsal.binding.api.DataBroker;
74 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
75 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
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().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 (InterruptedException | ExecutionException e) {
381 LOG.error("Read Failed Exception While read RouterInterface data for router {}", routerName, e);
382 routerInterfacesData = Optional.empty();
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).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).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).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).map(Networks::getVpnid).orElse(null);
532 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
534 return tx.read(buildNetworkIdentifier(networkId)).get().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).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().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).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).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().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).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).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)).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)).orElse(null);
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)).orElse(null);
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;
1090 externalCountersData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
1091 LogicalDatastoreType.OPERATIONAL, id);
1092 } catch (ExecutionException | InterruptedException e) {
1093 LOG.error("getLeastLoadedExternalIp: Exception while reading ExternalCounters DS for the segmentId {}",
1095 return leastLoadedExternalIp;
1097 if (externalCountersData.isPresent()) {
1098 ExternalCounters externalCounter = externalCountersData.get();
1099 short countOfLstLoadExtIp = 32767;
1100 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1101 String curExternalIp = externalIpCounter.getExternalIp();
1102 short countOfCurExtIp = externalIpCounter.getCounter().toJava();
1103 if (countOfCurExtIp < countOfLstLoadExtIp) {
1104 countOfLstLoadExtIp = countOfCurExtIp;
1105 leastLoadedExternalIp = curExternalIp;
1109 return leastLoadedExternalIp;
1112 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1114 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1115 String subnetIP = getSubnetIp(dataBroker, subnetId);
1116 if (subnetIP != null) {
1117 return getSubnetIpAndPrefix(subnetIP);
1119 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1124 public static String[] getSubnetIpAndPrefix(String subnetString) {
1125 String[] subnetSplit = subnetString.split("/");
1126 String subnetIp = subnetSplit[0];
1127 String subnetPrefix = "0";
1128 if (subnetSplit.length == 2) {
1129 subnetPrefix = subnetSplit[1];
1131 return new String[] {subnetIp, subnetPrefix};
1135 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1136 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1137 .builder(Subnetmaps.class)
1138 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1140 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1141 LogicalDatastoreType.CONFIGURATION, subnetmapId).map(Subnetmap::getSubnetIp).orElse(null);
1144 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1145 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1146 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1147 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1148 if (leastLoadedExtIpAddrSplit.length == 2) {
1149 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1151 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1155 public static List<Uint64> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1156 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1157 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1158 Optional<RouterDpnList> routerDpnListData =
1159 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1160 LogicalDatastoreType.OPERATIONAL, id);
1161 List<Uint64> dpns = new ArrayList<>();
1162 if (routerDpnListData.isPresent()) {
1163 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1164 dpns.add(dpnVpnInterface.getDpnId());
1170 public static Uint32 getBgpVpnId(DataBroker dataBroker, String routerName) {
1171 Uint32 bgpVpnId = NatConstants.INVALID_ID;
1172 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1173 if (bgpVpnUuid != null) {
1174 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1179 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1180 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1181 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1182 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orElse(null);
1185 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1186 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1187 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1188 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1189 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1190 .RouterInterface.class,
1191 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1192 .RouterInterfaceKey(interfaceName)).build();
1195 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, Uint64 dpId,
1196 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1198 if (dpId.equals(Uint64.ZERO)) {
1199 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1200 + "to handle router {} association model", interfaceName, routerName);
1204 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1205 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1206 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1208 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1209 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1210 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1211 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1212 .setInterface(interfaceName).build();
1213 if (optionalDpnVpninterfacesList.isPresent()) {
1214 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1215 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1216 operTx.merge(dpnVpnInterfacesListIdentifier
1217 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1218 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1219 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1221 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1222 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1223 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1224 routerDpnListBuilder.setRouterId(routerName);
1225 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1226 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1227 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1228 routerInterfaces.add(routerInterface);
1229 dpnVpnList.setRouterInterfaces(routerInterfaces);
1230 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1231 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1235 public static void addToDpnRoutersMap(String routerName, String interfaceName, Uint64 dpId,
1236 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1237 if (dpId.equals(Uint64.ZERO)) {
1238 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1239 + "association model", interfaceName, routerName);
1243 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1244 + "DPNRouters map", dpId, routerName, interfaceName);
1245 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1247 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1249 if (optionalDpnRoutersList.isPresent()) {
1250 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1251 .setRouter(routerName).build();
1252 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1253 if (!routersListFromDs.contains(routersList)) {
1254 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1255 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1256 operTx.merge(dpnRoutersListIdentifier
1257 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1259 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1260 + "DPNRouters map", routerName, dpId);
1263 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1264 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1265 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1266 dpnRoutersListBuilder.setDpnId(dpId);
1267 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1268 routersListBuilder.setRouter(routerName);
1269 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1270 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1274 public static void removeFromNeutronRouterDpnsMap(String routerName, Uint64 dpId,
1275 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1276 if (dpId.equals(Uint64.ZERO)) {
1277 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1281 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1282 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1283 if (optionalRouterDpnList.isPresent()) {
1284 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1285 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1286 operTx.delete(routerDpnListIdentifier);
1288 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1289 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1293 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1294 Uint64 dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1295 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1296 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1298 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1299 } catch (InterruptedException | ExecutionException e) {
1300 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1301 optionalRouterDpnList = Optional.empty();
1303 if (optionalRouterDpnList.isPresent()) {
1304 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1305 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1306 new ArrayList<>(optionalRouterDpnList.get().nonnullRouterInterfaces());
1307 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1308 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1309 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1310 .setInterface(vpnInterfaceName).build();
1312 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1313 if (routerInterfaces.isEmpty()) {
1314 operTx.delete(routerDpnListIdentifier);
1316 operTx.delete(routerDpnListIdentifier.child(
1317 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1318 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1319 new RouterInterfacesKey(vpnInterfaceName)));
1325 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1326 Uint64 curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1327 throws ExecutionException, InterruptedException {
1329 1) Get the DpnRoutersList for the DPN.
1330 2) Get the RoutersList identifier for the DPN and router.
1331 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1332 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1333 then remove RouterList.
1336 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1337 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1339 //Get the dpn-routers-list instance for the current DPN.
1340 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1341 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1343 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1344 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1345 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1349 //Get the routers-list instance for the router on the current DPN only
1350 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1351 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1353 if (routersListData == null || !routersListData.isPresent()) {
1354 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1355 + "in the ODL-L3VPN:dpn-routers model",
1360 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1361 + "from the NeutronVPN - router-interfaces-map", routerName);
1362 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1363 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1364 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1365 .RouterInterfaces> routerInterfacesData =
1366 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1367 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1369 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1370 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1371 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1372 curDpnId, routerName, routerName);
1373 operTx.delete(routersListIdentifier);
1377 //Get the VM interfaces for the router on the current DPN only.
1378 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1379 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1380 if (vmInterfaces == null) {
1381 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1382 + "NeutronVPN - router-interfaces-map", routerName);
1386 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1387 // then remove RouterList.
1388 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1389 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1390 String vmInterfaceName = vmInterface.getInterfaceId();
1391 Uint64 vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1392 if (vmDpnId.equals(Uint64.ZERO) || !vmDpnId.equals(curDpnId)) {
1393 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1394 + "the DPN ID {} for the checked interface {}",
1395 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1398 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1399 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1400 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1404 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1405 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1406 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1407 operTx.delete(routersListIdentifier);
1410 private static InstanceIdentifier<RoutersList> getRoutersList(Uint64 dpnId, String routerName) {
1411 return InstanceIdentifier.builder(DpnRouters.class)
1412 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1413 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1416 public static Uint64 getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1417 Uint64 nodeId = Uint64.ZERO;
1419 GetDpidFromInterfaceInput
1421 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1422 Future<RpcResult<GetDpidFromInterfaceOutput>>
1424 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1425 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1426 if (dpIdResult.isSuccessful()) {
1427 nodeId = dpIdResult.getResult().getDpid();
1429 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1431 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1432 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1438 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1439 ItmRpcService itmRpcService,
1440 IInterfaceManager interfaceManager, String ifName,
1441 Uint32 tunnelKey, boolean internalTunnelInterface) {
1442 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1443 ifName, tunnelKey, 0, internalTunnelInterface);
1447 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1448 ItmRpcService itmRpcService,
1449 IInterfaceManager interfaceManager,
1450 String ifName, @Nullable Uint32 tunnelKey, int pos,
1451 boolean internalTunnelInterface) {
1452 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1453 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1454 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1455 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1456 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1457 if (tunnelKey != null) {
1458 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1459 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1460 } //init builders, ITM/IFM rpc can be called based on type of interface
1463 List<Action> actions = emptyList();
1464 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1465 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1466 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1467 if (!rpcResult.isSuccessful()) {
1468 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1469 + "returned with Errors {}", ifName, rpcResult.getErrors());
1471 actions = rpcResult.getResult().nonnullAction();
1474 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1475 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1476 if (!rpcResult.isSuccessful()) {
1477 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1478 + "returned with Errors {}", ifName, rpcResult.getErrors());
1480 actions = rpcResult.getResult().nonnullAction();
1483 List<ActionInfo> listActionInfo = new ArrayList<>();
1484 for (Action action : actions) {
1485 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1486 actionClass = action.getAction();
1487 if (actionClass instanceof OutputActionCase) {
1488 listActionInfo.add(new ActionOutput(pos++,
1489 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1490 } else if (actionClass instanceof PushVlanActionCase) {
1491 listActionInfo.add(new ActionPushVlan(pos++));
1492 } else if (actionClass instanceof SetFieldCase) {
1493 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1494 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1495 .getVlanId().getValue().toJava();
1496 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1498 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1499 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable().toJava();
1500 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1501 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1502 NxRegLoad nxRegLoad =
1503 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1504 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart().toJava(),
1505 nxRegLoad.getDst().getEnd().toJava(), nxRegLoad.getValue().longValue()));
1508 return listActionInfo;
1509 } catch (InterruptedException | ExecutionException e) {
1510 LOG.error("Exception when egress actions for interface {}", ifName, e);
1512 LOG.error("Error when getting egress actions for interface {}", ifName);
1517 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1518 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1522 public static List<Port> getNeutronPorts(DataBroker broker) {
1523 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1524 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1525 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1526 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1528 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1529 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1531 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1532 LOG.error("getNeutronPorts : No neutron ports found");
1536 return portsOptional.get().getPort();
1540 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1541 List<Port> ports = getNeutronPorts(
1544 for (Port port : ports) {
1545 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1546 for (FixedIps ip : port.getFixedIps()) {
1547 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1553 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1558 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1560 LOG.error("getSubnetIdForFloatingIp : port is null");
1563 for (FixedIps ip : port.nonnullFixedIps()) {
1564 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1565 return ip.getSubnetId();
1568 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1573 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1574 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1575 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1576 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1577 LogicalDatastoreType.CONFIGURATION, subnetmapId).orElse(null);
1581 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1582 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1583 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1584 List<Uuid> subnetIdList = SingleTransactionDataBroker
1585 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1586 LogicalDatastoreType.CONFIGURATION, id).map(NetworkMap::getSubnetIdList).orElse(
1588 if (!subnetIdList.isEmpty()) {
1589 subnetIdList = new ArrayList<>(subnetIdList);
1592 return subnetIdList;
1596 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1597 if (subnetId == null) {
1598 LOG.error("getSubnetGwMac : subnetID is null");
1602 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1603 .child(Subnet.class, new SubnetKey(subnetId));
1604 Optional<Subnet> subnetOpt =
1605 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1606 LogicalDatastoreType.CONFIGURATION, subnetInst);
1607 if (!subnetOpt.isPresent()) {
1608 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1612 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1613 if (gatewayIp == null) {
1614 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1618 if (null != gatewayIp.getIpv6Address()) {
1622 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1623 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1625 Optional<VpnPortipToPort> portIpToPortOpt =
1626 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1627 LogicalDatastoreType.CONFIGURATION, portIpInst);
1628 if (portIpToPortOpt.isPresent()) {
1629 return portIpToPortOpt.get().getMacAddress();
1632 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1633 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1635 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1636 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1637 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1638 if (learntIpToPortOpt.isPresent()) {
1639 return learntIpToPortOpt.get().getMacAddress();
1642 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1646 public static boolean isIPv6Subnet(String prefix) {
1647 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1650 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(Uint64 dpnId) {
1651 return InstanceIdentifier.builder(DpnRouters.class)
1652 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1655 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, Uint64 dpnId) {
1656 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1657 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1658 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1661 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1662 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1663 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1667 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1668 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1669 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1670 LogicalDatastoreType.CONFIGURATION, id).map(
1671 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1675 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1676 Uuid floatingIpId) {
1678 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().map(
1679 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1680 } catch (InterruptedException | ExecutionException e) {
1681 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1687 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1688 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1689 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1690 LogicalDatastoreType.CONFIGURATION, id).map(
1691 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1695 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1696 Uuid floatingIpId) {
1698 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().map(
1699 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1700 } catch (InterruptedException | ExecutionException e) {
1701 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1706 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1707 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1708 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1712 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1713 InstanceIdentifier<Interface> ifStateId =
1714 buildStateInterfaceId(interfaceName);
1715 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1716 LogicalDatastoreType.OPERATIONAL, ifStateId).orElse(null);
1719 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1720 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1721 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1722 .interfaces.rev140508.InterfacesState.class)
1723 .child(Interface.class,
1724 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1725 .interfaces.state.InterfaceKey(interfaceName));
1726 return idBuilder.build();
1730 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1731 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1732 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1733 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orElse(null);
1737 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1739 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orElse(null);
1740 } catch (InterruptedException | ExecutionException e) {
1741 LOG.error("Error reading router {}", routerName, e);
1746 static void createRouterIdsConfigDS(DataBroker dataBroker, Uint32 routerId, String routerName) {
1747 if (routerId == NatConstants.INVALID_ID) {
1748 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1751 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1752 .setRouterId(routerId).setRouterName(routerName).build();
1753 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1757 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(Uint64 dpId, Uint32 vpnId, String subnetId,
1758 IdManagerService idManager) {
1759 InetAddress defaultIP = null;
1761 defaultIP = InetAddress.getByName("0.0.0.0");
1762 } catch (UnknownHostException e) {
1763 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1764 + "Default Route to NAT.", e);
1768 List<MatchInfo> matches = new ArrayList<>();
1769 matches.add(MatchEthernetType.IPV4);
1770 //add match for vrfid
1771 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
1772 MetaDataUtil.METADATA_MASK_VRFID));
1774 List<InstructionInfo> instructions = new ArrayList<>();
1775 List<ActionInfo> actionsInfo = new ArrayList<>();
1776 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(subnetId));
1777 if (groupId == NatConstants.INVALID_ID) {
1778 LOG.error("Unable to get groupId for subnet {} while building defauly flow entity", subnetId);
1781 actionsInfo.add(new ActionGroup(groupId.longValue()));
1782 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1783 instructions.add(new InstructionApplyActions(actionsInfo));
1784 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1785 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1786 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1790 static String getExtGwMacAddFromRouterId(DataBroker broker, Uint32 routerId) {
1791 String routerName = getRouterName(broker, routerId);
1792 if (routerName == null) {
1793 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1796 return getExtGwMacAddFromRouterName(broker, routerName);
1800 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1801 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1802 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1803 LogicalDatastoreType.CONFIGURATION, id).map(Routers::getExtGwMacAddress).orElse(null);
1807 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1809 return tx.read(buildRouterIdentifier(routerName)).get().map(
1810 Routers::getExtGwMacAddress).orElse(null);
1811 } catch (InterruptedException | ExecutionException e) {
1812 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1817 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1818 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1819 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1820 .child(Router.class, new RouterKey(routerUuid));
1821 return routerInstanceIdentifier;
1825 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1826 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1827 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1828 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).map(Router::getName).orElse(
1833 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1834 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1835 List<Ports> portsList = SingleTransactionDataBroker
1836 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION,
1837 routerPortsIdentifier).map(RouterPorts::getPorts).orElse(emptyList());
1838 if (!portsList.isEmpty()) {
1839 portsList = new ArrayList<>(portsList);
1845 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1846 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1847 Optional<ExternalNetworks> externalNwData =
1848 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1849 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1850 if (externalNwData.isPresent()) {
1851 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1852 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1853 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1854 return routerIds != null ? new ArrayList<>(routerIds) : emptyList();
1861 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1864 long ipLo = ipToLong(InetAddress.getByName(start));
1865 long ipHi = ipToLong(InetAddress.getByName(end));
1866 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1867 return ipToTest >= ipLo && ipToTest <= ipHi;
1868 } catch (UnknownHostException e) {
1869 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1875 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1876 if (externalIps == null) {
1877 return Collections.emptySet();
1880 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1884 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1885 if (routerName == null) {
1886 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1887 return Collections.emptySet();
1890 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1891 Optional<Routers> routerData =
1892 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1893 LogicalDatastoreType.CONFIGURATION, id);
1894 if (routerData.isPresent()) {
1895 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1897 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1898 return Collections.emptySet();
1903 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1904 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1905 if (subnetId == null) {
1906 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1907 return Optional.empty();
1910 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1911 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1912 InstanceIdentifier.builder(ExternalSubnets.class)
1913 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1914 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1915 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1916 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1920 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1921 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1922 if (subnetId == null) {
1923 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1924 return Optional.empty();
1927 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1928 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1929 InstanceIdentifier.builder(ExternalSubnets.class)
1930 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1931 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1933 return tx.read(subnetsIdentifier).get();
1934 } catch (InterruptedException | ExecutionException e) {
1935 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1936 return Optional.empty();
1940 protected static Uint32 getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1941 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1942 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1944 if (optionalExternalSubnets.isPresent()) {
1945 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1948 return NatConstants.INVALID_ID;
1951 protected static Uint32 getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1952 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1953 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1955 if (optionalExternalSubnets.isPresent()) {
1956 return NatUtil.getVpnId(tx, subnetId.getValue());
1959 return NatConstants.INVALID_ID;
1962 protected static Uint32 getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1964 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1965 if (externalSubnetId != null) {
1966 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1969 return NatConstants.INVALID_ID;
1973 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1974 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1975 for (ExternalIps extIp : router.nonnullExternalIps()) {
1976 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1977 if (extIpString.equals(externalIpAddress)) {
1978 return extIp.getSubnetId();
1981 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1985 private static long ipToLong(InetAddress ip) {
1986 byte[] octets = ip.getAddress();
1988 for (byte octet : octets) {
1990 result |= octet & 0xff;
1996 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1997 if (externalIps == null) {
2001 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
2004 // elan-instances config container
2006 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
2007 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
2008 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2009 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orElse(null);
2013 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
2015 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orElse(null);
2016 } catch (InterruptedException | ExecutionException e) {
2017 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
2022 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
2023 return InstanceIdentifier.builder(ElanInstances.class)
2024 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
2027 public static Uint64 getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
2028 IElanService elanManager, IdManagerService idManager,
2029 Uint32 routerId, String routerName) {
2030 if (elanManager.isOpenStackVniSemanticsEnforced()) {
2031 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
2032 return natOverVxlanUtil.getRouterVni(routerName, routerId);
2034 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
2038 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, Uint64 naptDpnId,
2039 short tableId, TypedWriteTransaction<Configuration> confTx) {
2040 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2041 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
2043 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
2044 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
2045 List<MatchInfo> matches = new ArrayList<>();
2046 matches.add(MatchEthernetType.IPV4);
2047 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2048 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
2049 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
2050 matches, preDnatToSnatInstructions);
2052 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
2053 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
2054 preDnatToSnatTableFlowEntity, naptDpnId);
2057 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
2058 IMdsalApiManager mdsalManager, Uint64 naptDpnId) throws ExecutionException, InterruptedException {
2059 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2060 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
2061 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2062 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
2063 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
2064 flowRef, naptDpnId);
2067 private static String getFlowRefPreDnatToSnat(Uint64 dpnId, short tableId, String uniqueId) {
2068 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
2069 + NwConstants.FLOWID_SEPARATOR + uniqueId;
2072 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, Uint64 dpnId, String rd,
2073 String vpnName, String externalIp,
2074 Boolean isMoreThanOneFipCheckOnDpn) {
2075 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
2076 Optional<VpnToDpnList> dpnInVpn;
2078 dpnInVpn = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2079 LogicalDatastoreType.OPERATIONAL, id);
2080 } catch (ExecutionException | InterruptedException e) {
2081 LOG.error("isFloatingIpPresentForDpn: Exception while reading VpnToDpnList DS for the rd {} dpnId {}",
2085 if (dpnInVpn.isPresent()) {
2086 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2087 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2089 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2090 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2091 int floatingIpPresentCount = 0;
2092 for (IpAddresses ipAddress: ipAddressList) {
2093 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2094 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2095 floatingIpPresentCount++;
2096 //Add tunnel table check
2097 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2100 //Remove tunnel table check
2101 if (!isMoreThanOneFipCheckOnDpn) {
2107 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2111 } catch (NullPointerException e) {
2112 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2113 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2120 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, Uint64 dpnId) {
2121 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2122 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2123 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2127 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2128 throws ExecutionException, InterruptedException {
2129 return tx.read(getVpnInstanceIdentifier(vpnName)).get().map(NatUtil::getPrimaryRd).orElse(null);
2133 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2134 if (vpnInstance == null) {
2137 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2138 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2141 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2142 return InstanceIdentifier.builder(VpnInstances.class)
2143 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2147 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2148 return vpnInstance.getRouteDistinguisher() != null ? new ArrayList<>(
2149 vpnInstance.getRouteDistinguisher()) : new ArrayList<>();
2152 public static String validateAndAddNetworkMask(String ipAddress) {
2153 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2156 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2157 String vpnInterfaceName, String vpnName) {
2158 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2159 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2162 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2163 String routerName, Uint64 dpnId) {
2164 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2165 Optional<Networks> networkData = null;
2167 networkData = SingleTransactionDataBroker.syncReadOptional(broker,
2168 LogicalDatastoreType.CONFIGURATION, id);
2169 } catch (ExecutionException | InterruptedException e) {
2170 LOG.error("checkForRoutersWithSameExtNetAndNaptSwitch: Exception while reading Networks DS for the "
2171 + "network {} router {} dpnId {}", networkId.getValue(), routerName, dpnId, e);
2174 if (networkData != null && networkData.isPresent()) {
2175 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2176 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2177 for (Uuid routerUuid : routerUuidList) {
2178 String sharedRouterName = routerUuid.getValue();
2179 if (!routerName.equals(sharedRouterName)) {
2180 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2181 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2182 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2183 + "associated with other active router {} on NAPT switch {}", networkId,
2184 sharedRouterName, switchDpnId);
2194 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2195 String routerName, Uint64 dpnId) {
2196 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId)
2197 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2198 .subnets.Subnets::getRouterIds).orElse(emptyList());
2199 if (!routerUuidList.isEmpty()) {
2200 for (Uuid routerUuid : routerUuidList) {
2201 String sharedRouterName = routerUuid.getValue();
2202 if (!routerName.equals(sharedRouterName)) {
2203 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2204 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2205 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2206 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2207 sharedRouterName, switchDpnId);
2216 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2217 Routers router, Uint64 primarySwitchId, int addOrRemove) {
2218 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2219 List<ExternalIps> externalIps = router.getExternalIps();
2220 List<String> externalIpsSting = new ArrayList<>();
2222 if (externalIps == null || externalIps.isEmpty()) {
2223 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2226 for (ExternalIps externalIp : externalIps) {
2227 externalIpsSting.add(externalIp.getIpAddress());
2229 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2230 if (addOrRemove == NwConstants.ADD_FLOW) {
2231 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2232 router.getNetworkId(), subnetVpnName.getValue(), tx);
2233 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2234 router.getExtGwMacAddress(), primarySwitchId,
2235 router.getNetworkId());
2237 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2238 router.getNetworkId(), subnetVpnName.getValue(), tx);
2239 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2240 router.getExtGwMacAddress(), primarySwitchId,
2241 router.getNetworkId());
2243 }), LOG, "Error installing router gateway flows");
2246 @SuppressWarnings("checkstyle:IllegalCatch")
2247 public static void handleSNATForDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2248 IdManagerService idManager, NaptSwitchHA naptSwitchHA,
2249 Uint64 dpnId, Routers extRouters, Uint32 routerId, Uint32 routerVpnId,
2250 TypedReadWriteTransaction<Configuration> confTx,
2251 ProviderTypes extNwProvType, UpgradeState upgradeState) {
2252 //Check if primary and secondary switch are selected, If not select the role
2253 //Install select group to NAPT switch
2254 //Install default miss entry to NAPT switch
2256 String routerName = extRouters.getRouterName();
2257 Boolean upgradeInProgress = false;
2258 if (upgradeState != null) {
2259 upgradeInProgress = upgradeState.isUpgradeInProgress();
2261 Uint64 naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2262 if (naptId == null || naptId.equals(Uint64.ZERO)
2263 || (!NatUtil.getSwitchStatus(dataBroker, naptId) && (upgradeInProgress == false))) {
2264 LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}",
2265 routerName, naptId);
2267 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
2269 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
2270 naptSwitch, routerName);
2273 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
2275 String externalVpnName = null;
2276 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
2277 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
2278 Uuid extNwUuid = extRouters.getNetworkId();
2279 externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNwUuid);
2280 if (externalVpnName != null) {
2281 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, extNwUuid,
2282 externalVpnName, confTx);
2284 // Install miss entry (table 26) pointing to table 46
2285 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
2286 routerVpnId, NatConstants.ADD_FLOW);
2287 if (flowEntity == null) {
2288 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
2292 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
2293 mdsalManager.addFlow(confTx, flowEntity);
2294 //Removing primary flows from old napt switch
2295 if (naptId != null && !naptId.equals(Uint64.ZERO)) {
2296 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
2297 naptId, routerName);
2299 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouters, routerId, naptId, null,
2300 externalVpnName, confTx);
2301 } catch (Exception e) {
2302 LOG.error("Exception while removing SnatFlows form OldNaptSwitch {}", naptId, e);
2305 naptSwitchHA.updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
2306 } else if (naptId.equals(dpnId)) {
2307 LOG.error("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
2309 naptSwitch = naptId;
2310 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
2311 naptId, routerName);
2314 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
2315 routerName, routerId, naptSwitch);
2316 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
2318 // Install miss entry (table 26) pointing to group
2319 Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
2320 NatUtil.getGroupIdKey(routerName));
2321 if (groupId != NatConstants.INVALID_ID) {
2322 FlowEntity flowEntity =
2323 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId.longValue(),
2324 routerVpnId, NatConstants.ADD_FLOW);
2325 if (flowEntity == null) {
2326 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}"
2327 + " groupId {}", routerName, dpnId, groupId);
2330 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
2331 dpnId, routerName, groupId);
2332 mdsalManager.addFlow(confTx, flowEntity);
2334 LOG.error("handleSNATForDPN: Unable to get groupId for router:{}", routerName);
2339 @SuppressWarnings("checkstyle:IllegalCatch")
2340 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2341 IdManagerService idManager, NaptSwitchHA naptSwitchHA, Uint64 dpnId,
2342 Routers extRouter, Uint32 routerId, Uint32 routerVpnId, String externalVpnName,
2343 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2344 throws ExecutionException, InterruptedException {
2345 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2346 //remove miss entry to NAPT switch
2347 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2348 if (extNwProvType == null) {
2351 String routerName = extRouter.getRouterName();
2352 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2353 Map<String, Uint32> externalIpLabel;
2354 if (extNwProvType == ProviderTypes.VXLAN) {
2355 externalIpLabel = null;
2357 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2359 Uint64 naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2360 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2361 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2364 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2365 boolean naptStatus =
2366 naptSwitchHA.isNaptSwitchDown(extRouter, routerId, dpnId, naptSwitch, routerVpnId,
2367 externalIpCache, confTx);
2369 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2371 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
2372 FlowEntity flowEntity = null;
2374 if (groupId != NatConstants.INVALID_ID) {
2375 flowEntity = naptSwitchHA
2376 .buildSnatFlowEntity(dpnId, routerName, groupId.longValue(), routerVpnId,
2377 NatConstants.DEL_FLOW);
2378 if (flowEntity == null) {
2379 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2380 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2383 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}",
2385 mdsalManager.removeFlow(confTx, flowEntity);
2387 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2390 } catch (Exception ex) {
2391 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2395 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2399 GroupEntity groupEntity = null;
2401 if (groupId != NatConstants.INVALID_ID) {
2402 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId.longValue(), routerName,
2403 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2404 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2405 mdsalManager.removeGroup(groupEntity);
2407 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2409 } catch (Exception ex) {
2410 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2413 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2416 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouter, routerId, naptSwitch,
2417 externalIpLabel, externalVpnName, confTx);
2418 //remove table 26 flow ppointing to table46
2419 FlowEntity flowEntity = null;
2421 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2422 NatConstants.DEL_FLOW);
2423 if (flowEntity == null) {
2424 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2428 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2429 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2430 mdsalManager.removeFlow(confTx, flowEntity);
2432 } catch (Exception ex) {
2433 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2437 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2440 //best effort to check IntExt model
2441 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2445 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2446 ProviderTypes extNwProvType) {
2447 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2448 || extNwProvType == ProviderTypes.VXLAN)) {
2454 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2455 Uint64 dpnId, DataBroker dataBroker) {
2456 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2457 elanInstanceName, dpnId);
2458 // FIXME: separate this out?
2459 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2462 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2463 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2464 List<String> elanInterfaceList = new ArrayList<>();
2465 DpnInterfaces dpnInterface;
2466 if (dpnInElanInterfaces.isPresent()) {
2467 dpnInterface = dpnInElanInterfaces.get();
2469 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2470 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2472 if (!elanInterfaceList.contains(pseudoPortId)) {
2473 elanInterfaceList.add(pseudoPortId);
2474 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2475 .withKey(new DpnInterfacesKey(dpnId)).build();
2476 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2477 elanDpnInterfaceId, dpnInterface);
2479 } catch (InterruptedException | ExecutionException e) {
2480 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2481 } catch (TransactionCommitFailedException e) {
2482 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2488 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2489 Uint64 dpnId, DataBroker dataBroker) {
2490 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2491 elanInstanceName, dpnId);
2492 // FIXME: separate this out?
2493 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2496 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2497 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2498 List<String> elanInterfaceList = new ArrayList<>();
2499 DpnInterfaces dpnInterface;
2500 if (!dpnInElanInterfaces.isPresent()) {
2501 LOG.info("No interface in any dpn for {}", elanInstanceName);
2505 dpnInterface = dpnInElanInterfaces.get();
2506 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2507 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2508 if (!elanInterfaceList.contains(pseudoPortId)) {
2509 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2512 elanInterfaceList.remove(pseudoPortId);
2513 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2514 .withKey(new DpnInterfacesKey(dpnId)).build();
2515 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2516 elanDpnInterfaceId, dpnInterface);
2517 } catch (InterruptedException | ExecutionException e) {
2518 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2519 } catch (TransactionCommitFailedException e) {
2520 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2526 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2527 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2528 for (Map.Entry<String,Routers> router : extRouter) {
2529 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2530 .equals(networkid)) {
2538 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2540 return SingleTransactionDataBroker.syncRead(dataBroker,
2541 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2543 catch (ExpectedDataObjectNotFoundException e) {
2544 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2549 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2550 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2551 .builder(LearntVpnVipToPortData.class).build();
2552 return learntVpnVipToPortDataId;
2555 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2557 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2558 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2559 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2562 public static InstanceIdentifier<Group> getGroupInstanceId(Uint64 dpnId, Uint32 groupId) {
2563 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2564 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2565 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2568 public static void createGroupIdPool(IdManagerService idManager) {
2569 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2570 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2571 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2572 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2575 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2576 if (result != null && result.get().isSuccessful()) {
2577 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2579 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2581 } catch (InterruptedException | ExecutionException e) {
2582 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2586 public static boolean getSwitchStatus(DataBroker broker, Uint64 switchId) {
2587 NodeId nodeId = new NodeId("openflow:" + switchId);
2588 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2589 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2590 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2591 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2592 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2593 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2594 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2595 if (nodeOptional.isPresent()) {
2596 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2599 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2603 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2604 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2605 Optional<Networks> networkData =
2606 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2607 broker, LogicalDatastoreType.CONFIGURATION, id);
2608 return networkData.isPresent();
2612 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2613 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2614 if (null != elanInstance) {
2615 return elanInstance.getPhysicalNetworkName();
2621 public static Map<String, String> getOpenvswitchOtherConfigMap(Uint64 dpnId, DataBroker dataBroker) {
2622 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2623 return getMultiValueMap(otherConfigVal);
2626 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2627 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2628 return Collections.emptyMap();
2631 Map<String, String> valueMap = new HashMap<>();
2632 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2633 for (String keyValue : splitter.split(multiKeyValueStr)) {
2634 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2635 if (split.length == 2) {
2636 valueMap.put(split[0], split[1]);
2643 public static Optional<Node> getBridgeRefInfo(Uint64 dpnId, DataBroker dataBroker) {
2644 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2645 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2647 Optional<BridgeRefEntry> bridgeRefEntry =
2648 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2649 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2650 if (!bridgeRefEntry.isPresent()) {
2651 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2652 return Optional.empty();
2655 InstanceIdentifier<Node> nodeId =
2656 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2658 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2659 LogicalDatastoreType.OPERATIONAL, nodeId);
2663 public static String getProviderMappings(Uint64 dpId, DataBroker dataBroker) {
2664 return getBridgeRefInfo(dpId, dataBroker).map(node -> getOpenvswitchOtherConfigs(node,
2665 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2669 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2670 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2671 if (ovsdbNode == null) {
2672 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2673 if (nodeFromReadOvsdbNode.isPresent()) {
2674 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2678 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2679 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2680 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2681 return openvswitchOtherConfigs.getOtherConfigValue();
2685 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2690 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2691 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2692 if (bridgeAugmentation != null) {
2693 InstanceIdentifier<Node> ovsdbNodeIid =
2694 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2695 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2696 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2698 return Optional.empty();
2703 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2707 return node.augmentation(OvsdbBridgeAugmentation.class);
2710 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, Uint64 dpnId) {
2711 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2714 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2715 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2716 InstanceIdentifier.builder(ExternalSubnets.class)
2719 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2720 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2721 if (optionalExternalSubnets.isPresent()) {
2722 return optionalExternalSubnets.get();
2724 } catch (InterruptedException | ExecutionException e) {
2725 LOG.error("Failed to read the subnets from the datastore.");
2731 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2732 Uint64 dpId, short tableId, String flowId, int priority, String flowName, Uint64 cookie,
2733 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2734 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2735 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2737 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2738 mdsalManager.addFlow(confTx, flowEntity);
2741 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2742 Uint64 dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2743 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2744 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2747 public static String getIpv6FlowRef(Uint64 dpnId, short tableId, Uint32 routerID) {
2748 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2749 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2752 public static String getTunnelInterfaceName(Uint64 srcDpId, Uint64 dstDpId,
2753 ItmRpcService itmManager) {
2754 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2755 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2757 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2758 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2759 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2760 rpcResult = result.get();
2761 if (!rpcResult.isSuccessful()) {
2762 tunType = TunnelTypeGre.class ;
2763 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2764 .setSourceDpid(srcDpId)
2765 .setDestinationDpid(dstDpId)
2766 .setTunnelType(tunType)
2768 rpcResult = result.get();
2769 if (!rpcResult.isSuccessful()) {
2770 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2771 rpcResult.getErrors());
2773 return rpcResult.getResult().getInterfaceName();
2775 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2776 rpcResult.getErrors());
2778 return rpcResult.getResult().getInterfaceName();
2780 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2781 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2782 + "between {} and {}", srcDpId, dstDpId);
2787 public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) {
2788 Port neutronPort = getNeutronPort(broker, ifaceName);
2789 if (neutronPort == null) {
2790 return Boolean.TRUE;
2792 return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE
2797 private static Port getNeutronPort(DataBroker broker, String ifaceName) {
2798 InstanceIdentifier<Port>
2799 portsIdentifier = InstanceIdentifier.create(Neutron.class)
2801 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class)
2802 .child(Port.class, new PortKey(new Uuid(ifaceName)));
2803 Optional<Port> portsOptional;
2805 portsOptional = SingleTransactionDataBroker
2806 .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
2807 } catch (InterruptedException | ExecutionException e) {
2808 LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e);
2809 portsOptional = Optional.empty();
2811 if (!portsOptional.isPresent()) {
2812 LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName);
2815 return portsOptional.get();
2818 public static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
2819 .instance.to.vpn.id.VpnInstance getVpnIdToVpnInstance(DataBroker broker, String vpnName) {
2820 if (vpnName == null) {
2824 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2825 .vpn.instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
2826 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2827 .vpn.instance.to.vpn.id.VpnInstance> vpnInstance = Optional.empty();
2829 vpnInstance = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, id);
2830 } catch (InterruptedException | ExecutionException e) {
2831 LOG.error("Failed to read VpnInstance {}", vpnInstance, e);
2833 if (vpnInstance.isPresent()) {
2834 return vpnInstance.get();
2840 public static Uint32 getExternalVpnIdForExtNetwork(DataBroker broker, Uuid externalNwUuid) {
2841 //Get the VPN ID from the ExternalNetworks model
2842 if (externalNwUuid == null) {
2843 LOG.error("getExternalVpnIdForExtNetwork : externalNwUuid is null");
2846 Uuid vpnUuid = getVpnIdfromNetworkId(broker, externalNwUuid);
2847 if (vpnUuid == null) {
2848 LOG.error("NAT Service : vpnUuid is null");
2851 Uint32 vpnId = getVpnId(broker, vpnUuid.getValue());
2855 static ReentrantLock lockForNat(final Uint64 dataPath) {
2856 // FIXME: wrap this in an Identifier
2857 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
2860 public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
2861 IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
2862 String interfaceName, String routerName) {
2863 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
2864 if (routerId == NatConstants.INVALID_ID) {
2865 LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
2868 Uint64 naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
2869 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2870 LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
2871 + "with Id {}", routerName, routerId);
2874 //getInternalIp for port
2875 List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
2876 if (fixedIps == null) {
2877 LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
2878 interfaceName, routerName, routerId);
2881 List<ProtocolTypes> protocolTypesList = getPortocolList();
2882 for (String internalIp : fixedIps) {
2883 LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
2884 interfaceName, internalIp, routerId);
2885 for (ProtocolTypes protocol : protocolTypesList) {
2886 List<Uint16> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
2887 if (portList != null) {
2888 for (Uint16 portnum : portList) {
2889 //build and remove the flow in outbound table
2890 removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
2891 routerId, internalIp, portnum.toJava(), protocol.getName());
2893 //build and remove the flow in inboundtable
2895 removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
2896 internalIp, portnum.toJava(), protocol.getName());
2898 //Get the external IP address and the port from the model
2900 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
2901 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
2902 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
2903 internalIp, String.valueOf(portnum.toJava()), proto);
2904 if (ipPortExternal == null) {
2905 LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
2906 + "with port {} is not found in "
2907 + "router with Id {}", internalIp, portnum, routerId);
2910 String externalIpAddress = ipPortExternal.getIpAddress();
2911 String internalIpPort = internalIp + ":" + portnum.toJava();
2912 // delete the entry from IntExtIpPortMap DS
2914 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
2915 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
2919 LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
2920 + "in router with id {}",
2921 protocol, interfaceName, internalIp, routerId);
2924 // delete the entry from SnatIntIpPortMap DS
2925 LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
2926 internalIp, routerId);
2927 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
2931 private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
2932 LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
2934 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
2935 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
2936 .setPortId(new Uuid(interfname)).build());
2938 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
2939 if (!rpcResult.isSuccessful()) {
2940 LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
2941 rpcResult.getErrors());
2943 return rpcResult.getResult().getFixedIPs();
2945 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
2946 LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
2951 private static List<ProtocolTypes> getPortocolList() {
2952 List<ProtocolTypes> protocollist = new ArrayList<>();
2953 protocollist.add(ProtocolTypes.TCP);
2954 protocollist.add(ProtocolTypes.UDP);
2955 return protocollist;
2958 private static void removeNatFlow(IMdsalApiManager mdsalManager, Uint64 dpnId, short tableId, Uint32 routerId,
2959 String ipAddress, int ipPort, String protocol) {
2961 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
2963 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
2965 mdsalManager.removeFlow(snatFlowEntity);
2966 LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
2967 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
2970 public static String getDpnFromNodeRef(NodeRef node) {
2971 PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
2972 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
2973 InstanceIdentifier.IdentifiableItem.class);
2974 NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
2975 String dpnKey = key.getId().getValue();
2976 String dpnID = null;
2977 if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
2978 dpnID = Uint64.valueOf(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();