2 * Copyright © 2016, 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.natservice.internal;
10 import static java.util.Collections.emptyList;
11 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
12 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import com.google.common.base.Splitter;
17 import com.google.common.base.Strings;
18 import com.google.common.collect.Iterables;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import java.math.BigInteger;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Objects;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.locks.ReentrantLock;
35 import java.util.stream.Collectors;
36 import org.apache.commons.net.util.SubnetUtils;
37 import org.eclipse.jdt.annotation.NonNull;
38 import org.eclipse.jdt.annotation.Nullable;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
42 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
43 import org.opendaylight.controller.sal.common.util.Arguments;
44 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
45 import org.opendaylight.genius.infra.Datastore.Configuration;
46 import org.opendaylight.genius.infra.Datastore.Operational;
47 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
48 import org.opendaylight.genius.infra.TypedReadTransaction;
49 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
50 import org.opendaylight.genius.infra.TypedWriteTransaction;
51 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
52 import org.opendaylight.genius.mdsalutil.ActionInfo;
53 import org.opendaylight.genius.mdsalutil.BucketInfo;
54 import org.opendaylight.genius.mdsalutil.FlowEntity;
55 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
56 import org.opendaylight.genius.mdsalutil.GroupEntity;
57 import org.opendaylight.genius.mdsalutil.InstructionInfo;
58 import org.opendaylight.genius.mdsalutil.MDSALUtil;
59 import org.opendaylight.genius.mdsalutil.MatchInfo;
60 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
61 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
62 import org.opendaylight.genius.mdsalutil.NwConstants;
63 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
64 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
65 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
66 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
67 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
68 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
69 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
70 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
71 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
72 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
73 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
74 import org.opendaylight.genius.utils.JvmGlobalLocks;
75 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
76 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
77 import org.opendaylight.netvirt.elanmanager.api.IElanService;
78 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
79 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
80 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
81 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
82 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
83 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
84 import org.opendaylight.serviceutils.upgrade.UpgradeState;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
87 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
88 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
89 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
90 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
91 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
94 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
95 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
188 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;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
227 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;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
262 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
263 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
264 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
265 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
266 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
267 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;
268 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
269 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
270 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
271 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
272 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
273 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
274 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
275 import org.opendaylight.yangtools.yang.common.RpcResult;
276 import org.opendaylight.yangtools.yang.common.Uint16;
277 import org.opendaylight.yangtools.yang.common.Uint32;
278 import org.opendaylight.yangtools.yang.common.Uint64;
279 import org.slf4j.Logger;
280 import org.slf4j.LoggerFactory;
282 public final class NatUtil {
284 private static String OF_URI_SEPARATOR = ":";
285 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
286 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
287 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
288 private static final String PROVIDER_MAPPINGS = "provider_mappings";
295 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
298 public static Uint64 getCookieSnatFlow(long routerId) {
299 return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0110000", 16)).add(
300 BigInteger.valueOf(routerId)));
304 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
307 public static Uint64 getCookieNaptFlow(Uint32 routerId) {
308 return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0111000", 16)).add(
309 BigInteger.valueOf(routerId.longValue())));
313 getVpnId() returns the VPN ID from the VPN name
315 public static Uint32 getVpnId(DataBroker broker, @Nullable String vpnName) {
316 if (vpnName == null) {
317 return NatConstants.INVALID_ID;
320 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
321 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
322 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
323 .instance.to.vpn.id.VpnInstance> vpnInstance =
324 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
325 LogicalDatastoreType.CONFIGURATION, id);
327 Uint32 vpnId = NatConstants.INVALID_ID;
328 if (vpnInstance.isPresent()) {
329 Uint32 vpnIdAsLong = vpnInstance.get().getVpnId();
330 if (vpnIdAsLong != null) {
337 public static Uint32 getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
338 if (vpnName == null) {
339 return NatConstants.INVALID_ID;
343 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
344 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
345 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
346 } catch (InterruptedException | ExecutionException e) {
347 LOG.error("Error retrieving VPN id for {}", vpnName, e);
350 return NatConstants.INVALID_ID;
353 public static Uint32 getNetworkVpnIdFromRouterId(DataBroker broker, Uint32 routerId) {
354 //Get the external network ID from the ExternalRouter model
355 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
356 if (networkId == null) {
357 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
358 return NatConstants.INVALID_ID;
361 //Get the VPN ID from the ExternalNetworks model
362 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
363 if (vpnUuid == null) {
364 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
365 return NatConstants.INVALID_ID;
367 Uint32 vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
371 public static Boolean validateIsIntefacePartofRouter(DataBroker broker, String routerName, String interfaceName) {
372 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
373 .map.router.interfaces.Interfaces> vmInterfaceIdentifier = getRoutersInterfacesIdentifier(routerName,
376 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
377 .map.router.interfaces.Interfaces> routerInterfacesData;
379 routerInterfacesData = SingleTransactionDataBroker.syncReadOptional(broker,
380 LogicalDatastoreType.CONFIGURATION, vmInterfaceIdentifier);
381 } catch (ReadFailedException e) {
382 LOG.error("Read Failed Exception While read RouterInterface data for router {}", routerName, e);
383 routerInterfacesData = Optional.absent();
385 if (routerInterfacesData.isPresent()) {
388 return Boolean.FALSE;
392 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
393 .rev150602.router.interfaces
394 .map.router.interfaces.Interfaces> getRoutersInterfacesIdentifier(String routerName, String interfaceName) {
395 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
396 .rev150602.RouterInterfacesMap.class)
397 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
398 .interfaces.map.RouterInterfaces.class,
399 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
400 .interfaces.map.RouterInterfacesKey(new Uuid(routerName)))
401 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
402 .map.router.interfaces.Interfaces.class,
403 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
404 .map.router.interfaces.InterfacesKey(interfaceName)).build();
407 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
408 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
409 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
410 .rev150602.RouterInterfacesMap.class)
411 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
412 .interfaces.map.RouterInterfaces.class,
413 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
414 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
417 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
418 return InstanceIdentifier.builder(FloatingIpInfo.class)
419 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
422 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
423 return InstanceIdentifier.builder(RouterToVpnMapping.class)
424 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
427 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
428 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
429 .child(Ports.class, new PortsKey(portName)).build();
432 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
434 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
435 .child(Ports.class, new PortsKey(portName))
436 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
439 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
440 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
441 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
442 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
443 .instance.to.vpn.id.VpnInstance.class,
444 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
445 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
449 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, Uint32 vpnId) {
450 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
451 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
452 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
453 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
457 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
459 public static String getFlowRef(Uint64 dpnId, short tableId, Uint32 routerID, String ip) {
460 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
461 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
462 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
465 public static String getFlowRef(Uint64 dpnId, short tableId, InetAddress destPrefix, Uint32 vpnId) {
466 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
467 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
468 .append(destPrefix.getHostAddress()).append(NatConstants.FLOWID_SEPARATOR).append(vpnId).toString();
471 public static String getNaptFlowRef(Uint64 dpnId, short tableId, String routerID, String ip,
472 int port, String protocol) {
473 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
474 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
475 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).append(NatConstants.FLOWID_SEPARATOR)
476 .append(port).append(NatConstants.FLOWID_SEPARATOR).append(protocol).toString();
480 static Uuid getNetworkIdFromRouterId(DataBroker broker, Uint32 routerId) {
481 String routerName = getRouterName(broker, routerId);
482 if (routerName == null) {
483 LOG.error("getNetworkIdFromRouterId - empty routerName received");
486 return getNetworkIdFromRouterName(broker, routerName);
490 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
491 if (routerName == null) {
492 LOG.error("getNetworkIdFromRouterName - empty routerName received");
495 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
496 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
497 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
500 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
501 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
502 .child(Routers.class, new RoutersKey(routerId)).build();
503 return routerInstanceIndentifier;
506 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Uint32 routerId) {
507 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
508 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
513 * Return if SNAT is enabled for the given router.
515 * @param broker The DataBroker
516 * @param routerId The router
517 * @return boolean true if enabled, otherwise false
519 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
520 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
521 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
522 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
526 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
527 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
528 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
529 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
533 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
535 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
536 } catch (InterruptedException | ExecutionException e) {
537 LOG.error("Error reading network VPN id for {}", networkId, e);
543 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
544 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
545 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
546 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
550 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
551 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
553 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
554 } catch (InterruptedException | ExecutionException e) {
555 LOG.error("Error retrieving provider type for {}", networkId, e);
561 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
562 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
563 Optional<Routers> routerData =
564 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
565 LogicalDatastoreType.CONFIGURATION, id);
566 if (routerData.isPresent()) {
567 Uuid networkId = routerData.get().getNetworkId();
568 if (networkId != null) {
569 return networkId.getValue();
572 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
576 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
577 return InstanceIdentifier.builder(ExternalNetworks.class)
578 .child(Networks.class, new NetworksKey(networkId)).build();
582 public static Uint64 getPrimaryNaptfromRouterId(DataBroker broker, Uint32 routerId) {
583 // convert routerId to Name
584 String routerName = getRouterName(broker, routerId);
585 if (routerName == null) {
586 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
589 return getPrimaryNaptfromRouterName(broker, routerName);
593 public static Uint64 getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
594 if (routerName == null) {
595 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
598 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
599 return (SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
600 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
601 Uint64.valueOf(0L)));
604 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
605 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
606 new RouterToNaptSwitchKey(routerId)).build();
609 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
610 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
611 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
615 public static String getRouterName(DataBroker broker, Uint32 routerId) {
616 return getVpnInstanceFromVpnIdentifier(broker, routerId);
619 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
620 return InstanceIdentifier.builder(VpnInstanceOpData.class)
621 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
624 public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, Uint64 cookie, String flowId) {
625 return new FlowEntityBuilder()
633 public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, String flowId) {
634 return new FlowEntityBuilder()
642 public static String getEndpointIpAddressForDPN(DataBroker broker, Uint64 dpnId) {
643 String nextHopIp = null;
644 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
645 InstanceIdentifier.builder(DpnEndpoints.class)
646 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
647 Optional<DPNTEPsInfo> tunnelInfo =
648 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
649 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
650 if (tunnelInfo.isPresent()) {
651 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
652 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
653 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
660 public static String getVpnRd(DataBroker broker, String vpnName) {
661 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
662 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
663 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
664 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
665 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
666 .VpnInstance::getVrfId).orElse(null);
670 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
672 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
673 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
674 .VpnInstance::getVrfId).orElse(null);
675 } catch (InterruptedException | ExecutionException e) {
676 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
682 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Uint32 routerId, String internalIpAddress,
683 String internalPort, NAPTEntryEvent.Protocol protocol) {
684 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
685 InstanceIdentifier<IpPortMap> ipPortMapId =
686 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
687 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
688 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
692 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Uint32 routerId, String internalIpAddress,
694 ProtocolTypes protocolType) {
695 return InstanceIdentifier.builder(IntextIpPortMap.class)
696 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
697 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
698 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
701 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
702 return InstanceIdentifier.builder(VpnInterfaces.class)
703 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
707 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
709 * NodeConnectorId is of form 'openflow:dpnid:portnum'
711 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
712 if (split.length != 3) {
713 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
719 public static Uint64 getDpIdFromInterface(
720 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
721 .state.Interface ifState) {
722 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
723 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
724 return Uint64.valueOf(getDpnFromNodeConnectorId(nodeConnectorId));
729 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
730 // returns only router, attached to IPv4 networks
731 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
732 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
733 Optional<VpnMap> optionalVpnMap =
734 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
735 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
736 if (!optionalVpnMap.isPresent()) {
737 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
740 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
741 if (routerIdsList != null && !routerIdsList.isEmpty()) {
742 for (Uuid routerUuid : routerIdsList) {
743 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
744 Optional<Routers> routerData =
745 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
746 LogicalDatastoreType.CONFIGURATION, id);
747 if (routerData.isPresent()) {
748 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
749 for (Uuid subnetUuid : subnetIdsList) {
750 String subnetIp = getSubnetIp(broker, subnetUuid);
751 SubnetUtils subnet = new SubnetUtils(subnetIp);
752 if (subnet.getInfo().isInRange(ipAddress)) {
753 return routerUuid.getValue();
759 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
764 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
765 Preconditions.checkNotNull(routerId, "getVpnForRouter: routerId not found!");
766 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
767 Optional<VpnMaps> optionalVpnMaps =
768 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
769 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
770 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
771 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap()) {
772 if (routerId.equals(vpnMap.getVpnId().getValue())) {
775 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
776 if (routerIdsList.isEmpty()) {
779 // Skip router vpnId fetching from internet BGP-VPN
780 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
781 // We only need to check the first network; if it’s not an external network there’s no
782 // need to check the rest of the VPN’s network list
783 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
787 if (routerIdsList.contains(new Uuid(routerId))) {
788 return vpnMap.getVpnId();
792 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
796 static Uint32 getAssociatedVpn(DataBroker broker, String routerName) {
797 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
798 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
799 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
800 NatConstants.INVALID_ID);
804 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
805 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
806 if (vpnUuid == null) {
807 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
810 return vpnUuid.getValue();
814 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
815 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
816 if (vpnUuid == null) {
817 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
820 return vpnUuid.getValue();
823 // TODO Clean up the exception handling
824 @SuppressWarnings("checkstyle:IllegalCatch")
825 public static void addPrefixToBGP(DataBroker broker,
826 IBgpManager bgpManager,
827 IFibManager fibManager,
832 @Nullable String parentVpnRd,
833 @Nullable String macAddress,
839 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
840 prefix, nextHopIp, label);
841 if (nextHopIp == null) {
842 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
847 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
848 dpId, Prefixes.PrefixCue.Nat);
850 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
851 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, label, l3vni /*l3vni*/,
852 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
853 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
854 /* Publish to Bgp only if its an INTERNET VPN */
855 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
856 VrfEntry.EncapType.Mplsgre, label, Uint32.ZERO /*l3vni*/, Uint32.ZERO /*l2vni*/,
857 null /*gatewayMac*/);
859 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
860 prefix, nextHopIp, label);
861 } catch (Exception e) {
862 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
863 prefix, nextHopIp, label, e);
867 static void addPrefixToInterface(DataBroker broker, Uint32 vpnId, @Nullable String interfaceName, String ipPrefix,
868 String networkId, Uint64 dpId, Prefixes.PrefixCue prefixCue) {
869 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
870 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
871 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
872 .to._interface.VpnIdsKey(vpnId))
873 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
874 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
875 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
876 prefixBuilder.setNetworkId(new Uuid(networkId));
878 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
879 prefixBuilder.build());
880 } catch (TransactionCommitFailedException e) {
881 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
882 ipPrefix, vpnId, dpId, e);
886 public static void deletePrefixToInterface(DataBroker broker, Uint32 vpnId, String ipPrefix) {
888 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
889 InstanceIdentifier.builder(PrefixToInterface.class)
890 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
891 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
892 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
894 } catch (TransactionCommitFailedException e) {
895 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
900 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
901 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
902 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
906 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
907 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
908 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
909 return routerInstanceIndentifier;
913 public static List<Uint16> getInternalIpPortListInfo(DataBroker dataBroker, Uint32 routerId,
914 String internalIpAddress, ProtocolTypes protocolType) {
915 List<Uint16> portList = SingleTransactionDataBroker
916 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
917 LogicalDatastoreType.CONFIGURATION,
918 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
919 IntIpProtoType::getPorts).orElse(emptyList());
921 if (!portList.isEmpty()) {
922 portList = new ArrayList<>(portList);
927 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Uint32 routerId,
928 String internalIpAddress,
929 ProtocolTypes protocolType) {
930 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
931 InstanceIdentifier.builder(SnatintIpPortMap.class)
932 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
933 .child(IpPort.class, new IpPortKey(internalIpAddress))
934 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
935 return intIpProtocolTypeId;
938 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
939 String internalIpAddress) {
940 InstanceIdentifier<IpPort> intIpProtocolTypeId =
941 InstanceIdentifier.builder(SnatintIpPortMap.class)
942 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
943 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
944 return intIpProtocolTypeId;
948 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
949 String internalIpAddress) {
950 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
951 LogicalDatastoreType.CONFIGURATION,
952 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
955 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
956 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
957 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
961 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
962 return InstanceIdentifier.create(NaptSwitches.class);
965 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
966 return InstanceIdentifier.create(NaptSwitches.class)
967 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
970 public static String getGroupIdKey(String routerName) {
971 return "snatmiss." + routerName;
974 public static Uint32 getUniqueId(IdManagerService idManager, String poolName, String idKey) {
976 AllocateIdInput getIdInput = (new AllocateIdInputBuilder()).setPoolName(poolName).setIdKey(idKey).build();
978 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
979 RpcResult<AllocateIdOutput> rpcResult = (RpcResult)result.get();
980 return rpcResult.isSuccessful() ? rpcResult.getResult().getIdValue()
981 : NatConstants.INVALID_ID;
982 } catch (InterruptedException | ExecutionException e) {
983 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
985 return NatConstants.INVALID_ID;
988 public static Uint32 releaseId(IdManagerService idManager, String poolName, String idKey) {
989 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
991 Future<RpcResult<ReleaseIdOutput>> result = idManager.releaseId(idInput);
992 if (result == null || result.get() == null || !result.get().isSuccessful()) {
993 LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}",
995 (result != null && result.get() != null) ? result.get().getErrors() : "RpcResult is null");
999 } catch (InterruptedException | ExecutionException e) {
1000 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
1002 return NatConstants.INVALID_ID;
1005 // TODO Clean up the exception handling
1006 @SuppressWarnings("checkstyle:IllegalCatch")
1007 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
1008 String rd, String prefix, String vpnName) {
1010 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
1011 fibManager.removeFibEntry(rd, prefix, null);
1012 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
1013 bgpManager.withdrawPrefix(rd, prefix);
1015 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
1016 } catch (Exception e) {
1017 LOG.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
1018 rd, prefix, vpnName, e);
1023 public static IpPortMapping getIportMapping(DataBroker broker, Uint32 routerId) {
1024 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1025 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
1028 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(Uint32 routerId) {
1029 return InstanceIdentifier.builder(IntextIpPortMap.class)
1030 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
1033 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1034 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Uint32 routerId) {
1035 return InstanceIdentifier.builder(IntextIpMap.class)
1036 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
1037 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
1038 .intext.ip.map.IpMappingKey(routerId))
1043 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Uint32 routerId) {
1044 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1045 .ip.map.IpMapping> ipMappingOptional =
1046 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1047 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1048 // Ensure there are no duplicates
1049 Collection<String> externalIps = new HashSet<>();
1050 if (ipMappingOptional.isPresent()) {
1051 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1052 externalIps.add(ipMap.getExternalIp());
1059 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
1060 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1061 if (routerData != null) {
1062 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
1069 public static Map<String, Uint32> getExternalIpsLabelForRouter(DataBroker dataBroker, Uint32 routerId) {
1070 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1071 .ip.map.IpMapping> ipMappingOptional =
1072 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1073 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1074 Map<String, Uint32> externalIpsLabel = new HashMap<>();
1075 if (ipMappingOptional.isPresent()) {
1076 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1077 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1080 return externalIpsLabel;
1084 public static String getLeastLoadedExternalIp(DataBroker dataBroker, Uint32 segmentId) {
1085 String leastLoadedExternalIp = null;
1086 InstanceIdentifier<ExternalCounters> id =
1087 InstanceIdentifier.builder(ExternalIpsCounter.class)
1088 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1089 Optional<ExternalCounters> externalCountersData =
1090 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1091 if (externalCountersData.isPresent()) {
1092 ExternalCounters externalCounter = externalCountersData.get();
1093 short countOfLstLoadExtIp = 32767;
1094 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1095 String curExternalIp = externalIpCounter.getExternalIp();
1096 short countOfCurExtIp = externalIpCounter.getCounter().toJava();
1097 if (countOfCurExtIp < countOfLstLoadExtIp) {
1098 countOfLstLoadExtIp = countOfCurExtIp;
1099 leastLoadedExternalIp = curExternalIp;
1103 return leastLoadedExternalIp;
1106 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1108 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1109 String subnetIP = getSubnetIp(dataBroker, subnetId);
1110 if (subnetIP != null) {
1111 return getSubnetIpAndPrefix(subnetIP);
1113 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1118 public static String[] getSubnetIpAndPrefix(String subnetString) {
1119 String[] subnetSplit = subnetString.split("/");
1120 String subnetIp = subnetSplit[0];
1121 String subnetPrefix = "0";
1122 if (subnetSplit.length == 2) {
1123 subnetPrefix = subnetSplit[1];
1125 return new String[] {subnetIp, subnetPrefix};
1129 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1130 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1131 .builder(Subnetmaps.class)
1132 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1134 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1135 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1138 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1139 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1140 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1141 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1142 if (leastLoadedExtIpAddrSplit.length == 2) {
1143 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1145 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1149 public static List<Uint64> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1150 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1151 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1152 Optional<RouterDpnList> routerDpnListData =
1153 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1154 LogicalDatastoreType.OPERATIONAL, id);
1155 List<Uint64> dpns = new ArrayList<>();
1156 if (routerDpnListData.isPresent()) {
1157 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1158 dpns.add(dpnVpnInterface.getDpnId());
1164 public static Uint32 getBgpVpnId(DataBroker dataBroker, String routerName) {
1165 Uint32 bgpVpnId = NatConstants.INVALID_ID;
1166 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1167 if (bgpVpnUuid != null) {
1168 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1173 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1174 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1175 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1176 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1179 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1180 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1181 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1182 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1183 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1184 .RouterInterface.class,
1185 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1186 .RouterInterfaceKey(interfaceName)).build();
1189 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, Uint64 dpId,
1190 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1192 if (dpId.equals(Uint64.ZERO)) {
1193 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1194 + "to handle router {} association model", interfaceName, routerName);
1198 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1199 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1200 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1202 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1203 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1204 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1205 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1206 .setInterface(interfaceName).build();
1207 if (optionalDpnVpninterfacesList.isPresent()) {
1208 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1209 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1210 operTx.merge(dpnVpnInterfacesListIdentifier
1211 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1212 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1213 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1215 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1216 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1217 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1218 routerDpnListBuilder.setRouterId(routerName);
1219 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1220 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1221 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1222 routerInterfaces.add(routerInterface);
1223 dpnVpnList.setRouterInterfaces(routerInterfaces);
1224 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1225 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1229 public static void addToDpnRoutersMap(String routerName, String interfaceName, Uint64 dpId,
1230 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1231 if (dpId.equals(Uint64.ZERO)) {
1232 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1233 + "association model", interfaceName, routerName);
1237 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1238 + "DPNRouters map", dpId, routerName, interfaceName);
1239 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1241 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1243 if (optionalDpnRoutersList.isPresent()) {
1244 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1245 .setRouter(routerName).build();
1246 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1247 if (!routersListFromDs.contains(routersList)) {
1248 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1249 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1250 operTx.merge(dpnRoutersListIdentifier
1251 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1253 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1254 + "DPNRouters map", routerName, dpId);
1257 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1258 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1259 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1260 dpnRoutersListBuilder.setDpnId(dpId);
1261 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1262 routersListBuilder.setRouter(routerName);
1263 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1264 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1268 public static void removeFromNeutronRouterDpnsMap(String routerName, Uint64 dpId,
1269 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1270 if (dpId.equals(Uint64.ZERO)) {
1271 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1275 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1276 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1277 if (optionalRouterDpnList.isPresent()) {
1278 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1279 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1280 operTx.delete(routerDpnListIdentifier);
1282 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1283 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1287 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1288 Uint64 dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1289 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1290 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1292 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1293 } catch (InterruptedException | ExecutionException e) {
1294 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1295 optionalRouterDpnList = Optional.absent();
1297 if (optionalRouterDpnList.isPresent()) {
1298 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1299 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1300 new ArrayList<>(optionalRouterDpnList.get().nonnullRouterInterfaces());
1301 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1302 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1303 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1304 .setInterface(vpnInterfaceName).build();
1306 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1307 if (routerInterfaces.isEmpty()) {
1308 operTx.delete(routerDpnListIdentifier);
1310 operTx.delete(routerDpnListIdentifier.child(
1311 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1312 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1313 new RouterInterfacesKey(vpnInterfaceName)));
1319 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1320 Uint64 curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1321 throws ExecutionException, InterruptedException {
1323 1) Get the DpnRoutersList for the DPN.
1324 2) Get the RoutersList identifier for the DPN and router.
1325 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1326 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1327 then remove RouterList.
1330 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1331 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1333 //Get the dpn-routers-list instance for the current DPN.
1334 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1335 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1337 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1338 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1339 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1343 //Get the routers-list instance for the router on the current DPN only
1344 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1345 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1347 if (routersListData == null || !routersListData.isPresent()) {
1348 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1349 + "in the ODL-L3VPN:dpn-routers model",
1354 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1355 + "from the NeutronVPN - router-interfaces-map", routerName);
1356 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1357 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1358 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1359 .RouterInterfaces> routerInterfacesData =
1360 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1361 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1363 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1364 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1365 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1366 curDpnId, routerName, routerName);
1367 operTx.delete(routersListIdentifier);
1371 //Get the VM interfaces for the router on the current DPN only.
1372 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1373 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1374 if (vmInterfaces == null) {
1375 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1376 + "NeutronVPN - router-interfaces-map", routerName);
1380 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1381 // then remove RouterList.
1382 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1383 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1384 String vmInterfaceName = vmInterface.getInterfaceId();
1385 Uint64 vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1386 if (vmDpnId.equals(Uint64.ZERO) || !vmDpnId.equals(curDpnId)) {
1387 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1388 + "the DPN ID {} for the checked interface {}",
1389 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1392 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1393 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1394 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1398 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1399 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1400 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1401 operTx.delete(routersListIdentifier);
1404 private static InstanceIdentifier<RoutersList> getRoutersList(Uint64 dpnId, String routerName) {
1405 return InstanceIdentifier.builder(DpnRouters.class)
1406 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1407 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1410 public static Uint64 getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1411 Uint64 nodeId = Uint64.ZERO;
1413 GetDpidFromInterfaceInput
1415 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1416 Future<RpcResult<GetDpidFromInterfaceOutput>>
1418 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1419 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1420 if (dpIdResult.isSuccessful()) {
1421 nodeId = dpIdResult.getResult().getDpid();
1423 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1425 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1426 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1432 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1433 ItmRpcService itmRpcService,
1434 IInterfaceManager interfaceManager, String ifName,
1435 Uint32 tunnelKey, boolean internalTunnelInterface) {
1436 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1437 ifName, tunnelKey, 0, internalTunnelInterface);
1441 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1442 ItmRpcService itmRpcService,
1443 IInterfaceManager interfaceManager,
1444 String ifName, @Nullable Uint32 tunnelKey, int pos,
1445 boolean internalTunnelInterface) {
1446 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1447 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1448 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1449 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1450 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1451 if (tunnelKey != null) {
1452 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1453 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1454 } //init builders, ITM/IFM rpc can be called based on type of interface
1457 List<Action> actions = emptyList();
1458 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1459 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1460 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1461 if (!rpcResult.isSuccessful()) {
1462 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1463 + "returned with Errors {}", ifName, rpcResult.getErrors());
1465 actions = rpcResult.getResult().nonnullAction();
1468 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1469 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1470 if (!rpcResult.isSuccessful()) {
1471 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1472 + "returned with Errors {}", ifName, rpcResult.getErrors());
1474 actions = rpcResult.getResult().nonnullAction();
1477 List<ActionInfo> listActionInfo = new ArrayList<>();
1478 for (Action action : actions) {
1479 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1480 actionClass = action.getAction();
1481 if (actionClass instanceof OutputActionCase) {
1482 listActionInfo.add(new ActionOutput(pos++,
1483 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1484 } else if (actionClass instanceof PushVlanActionCase) {
1485 listActionInfo.add(new ActionPushVlan(pos++));
1486 } else if (actionClass instanceof SetFieldCase) {
1487 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1488 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1489 .getVlanId().getValue().toJava();
1490 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1492 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1493 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable().toJava();
1494 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1495 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1496 NxRegLoad nxRegLoad =
1497 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1498 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart().toJava(),
1499 nxRegLoad.getDst().getEnd().toJava(), nxRegLoad.getValue().longValue()));
1502 return listActionInfo;
1503 } catch (InterruptedException | ExecutionException e) {
1504 LOG.error("Exception when egress actions for interface {}", ifName, e);
1506 LOG.error("Error when getting egress actions for interface {}", ifName);
1511 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1512 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1516 public static List<Port> getNeutronPorts(DataBroker broker) {
1517 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1518 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1519 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1520 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1522 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1523 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1525 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1526 LOG.error("getNeutronPorts : No neutron ports found");
1530 return portsOptional.get().getPort();
1534 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1535 List<Port> ports = getNeutronPorts(
1538 for (Port port : ports) {
1539 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1540 for (FixedIps ip : port.getFixedIps()) {
1541 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1547 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1552 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1554 LOG.error("getSubnetIdForFloatingIp : port is null");
1557 for (FixedIps ip : port.nonnullFixedIps()) {
1558 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1559 return ip.getSubnetId();
1562 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1567 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1568 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1569 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1570 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1571 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1575 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1576 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1577 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1578 List<Uuid> subnetIdList = SingleTransactionDataBroker
1579 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1580 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1582 if (!subnetIdList.isEmpty()) {
1583 subnetIdList = new ArrayList<>(subnetIdList);
1586 return subnetIdList;
1590 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1591 if (subnetId == null) {
1592 LOG.error("getSubnetGwMac : subnetID is null");
1596 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1597 .child(Subnet.class, new SubnetKey(subnetId));
1598 Optional<Subnet> subnetOpt =
1599 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1600 LogicalDatastoreType.CONFIGURATION, subnetInst);
1601 if (!subnetOpt.isPresent()) {
1602 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1606 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1607 if (gatewayIp == null) {
1608 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1612 if (null != gatewayIp.getIpv6Address()) {
1616 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1617 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1619 Optional<VpnPortipToPort> portIpToPortOpt =
1620 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1621 LogicalDatastoreType.CONFIGURATION, portIpInst);
1622 if (portIpToPortOpt.isPresent()) {
1623 return portIpToPortOpt.get().getMacAddress();
1626 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1627 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1629 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1630 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1631 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1632 if (learntIpToPortOpt.isPresent()) {
1633 return learntIpToPortOpt.get().getMacAddress();
1636 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1640 public static boolean isIPv6Subnet(String prefix) {
1641 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1644 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(Uint64 dpnId) {
1645 return InstanceIdentifier.builder(DpnRouters.class)
1646 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1649 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, Uint64 dpnId) {
1650 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1651 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1652 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1655 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1656 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1657 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1661 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1662 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1663 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1664 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1665 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1669 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1670 Uuid floatingIpId) {
1672 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1673 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1674 } catch (InterruptedException | ExecutionException e) {
1675 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1681 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1682 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1683 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1684 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1685 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1689 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1690 Uuid floatingIpId) {
1692 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1693 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1694 } catch (InterruptedException | ExecutionException e) {
1695 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1700 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1701 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1702 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1706 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1707 InstanceIdentifier<Interface> ifStateId =
1708 buildStateInterfaceId(interfaceName);
1709 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1710 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1713 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1714 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1715 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1716 .interfaces.rev140508.InterfacesState.class)
1717 .child(Interface.class,
1718 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1719 .interfaces.state.InterfaceKey(interfaceName));
1720 return idBuilder.build();
1724 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1725 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1726 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1727 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1731 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1733 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1734 } catch (InterruptedException | ExecutionException e) {
1735 LOG.error("Error reading router {}", routerName, e);
1740 static void createRouterIdsConfigDS(DataBroker dataBroker, Uint32 routerId, String routerName) {
1741 if (routerId == NatConstants.INVALID_ID) {
1742 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1745 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1746 .setRouterId(routerId).setRouterName(routerName).build();
1747 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1751 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(Uint64 dpId, Uint32 vpnId, String subnetId,
1752 IdManagerService idManager) {
1753 InetAddress defaultIP = null;
1755 defaultIP = InetAddress.getByName("0.0.0.0");
1756 } catch (UnknownHostException e) {
1757 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1758 + "Default Route to NAT.", e);
1762 List<MatchInfo> matches = new ArrayList<>();
1763 matches.add(MatchEthernetType.IPV4);
1764 //add match for vrfid
1765 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
1766 MetaDataUtil.METADATA_MASK_VRFID));
1768 List<InstructionInfo> instructions = new ArrayList<>();
1769 List<ActionInfo> actionsInfo = new ArrayList<>();
1770 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(subnetId));
1771 if (groupId == NatConstants.INVALID_ID) {
1772 LOG.error("Unable to get groupId for subnet {} while building defauly flow entity", subnetId);
1775 actionsInfo.add(new ActionGroup(groupId.longValue()));
1776 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1777 instructions.add(new InstructionApplyActions(actionsInfo));
1778 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1779 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1780 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1784 static String getExtGwMacAddFromRouterId(DataBroker broker, Uint32 routerId) {
1785 String routerName = getRouterName(broker, routerId);
1786 if (routerName == null) {
1787 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1790 return getExtGwMacAddFromRouterName(broker, routerName);
1794 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1795 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1796 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1797 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1801 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1803 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1804 Routers::getExtGwMacAddress).orElse(null);
1805 } catch (InterruptedException | ExecutionException e) {
1806 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1811 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1812 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1813 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1814 .child(Router.class, new RouterKey(routerUuid));
1815 return routerInstanceIdentifier;
1819 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1820 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1821 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1822 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1827 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1828 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1829 List<Ports> portsList = SingleTransactionDataBroker
1830 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION,
1831 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1832 if (!portsList.isEmpty()) {
1833 portsList = new ArrayList<>(portsList);
1839 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1840 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1841 Optional<ExternalNetworks> externalNwData =
1842 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1843 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1844 if (externalNwData.isPresent()) {
1845 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1846 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1847 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1848 return routerIds != null ? new ArrayList<>(routerIds) : emptyList();
1855 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1858 long ipLo = ipToLong(InetAddress.getByName(start));
1859 long ipHi = ipToLong(InetAddress.getByName(end));
1860 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1861 return ipToTest >= ipLo && ipToTest <= ipHi;
1862 } catch (UnknownHostException e) {
1863 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1869 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1870 if (externalIps == null) {
1871 return Collections.emptySet();
1874 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1878 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1879 if (routerName == null) {
1880 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1881 return Collections.emptySet();
1884 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1885 Optional<Routers> routerData =
1886 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1887 LogicalDatastoreType.CONFIGURATION, id);
1888 if (routerData.isPresent()) {
1889 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1891 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1892 return Collections.emptySet();
1897 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1898 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1899 if (subnetId == null) {
1900 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1901 return Optional.absent();
1904 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1905 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1906 InstanceIdentifier.builder(ExternalSubnets.class)
1907 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1908 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1909 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1910 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1914 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1915 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1916 if (subnetId == null) {
1917 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1918 return Optional.absent();
1921 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1922 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1923 InstanceIdentifier.builder(ExternalSubnets.class)
1924 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1925 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1927 return tx.read(subnetsIdentifier).get();
1928 } catch (InterruptedException | ExecutionException e) {
1929 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1930 return Optional.absent();
1934 protected static Uint32 getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1935 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1936 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1938 if (optionalExternalSubnets.isPresent()) {
1939 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1942 return NatConstants.INVALID_ID;
1945 protected static Uint32 getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1946 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1947 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1949 if (optionalExternalSubnets.isPresent()) {
1950 return NatUtil.getVpnId(tx, subnetId.getValue());
1953 return NatConstants.INVALID_ID;
1956 protected static Uint32 getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1958 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1959 if (externalSubnetId != null) {
1960 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1963 return NatConstants.INVALID_ID;
1967 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1968 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1969 for (ExternalIps extIp : router.nonnullExternalIps()) {
1970 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1971 if (extIpString.equals(externalIpAddress)) {
1972 return extIp.getSubnetId();
1975 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1979 private static long ipToLong(InetAddress ip) {
1980 byte[] octets = ip.getAddress();
1982 for (byte octet : octets) {
1984 result |= octet & 0xff;
1990 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1991 if (externalIps == null) {
1995 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1998 // elan-instances config container
2000 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
2001 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
2002 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2003 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
2007 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
2009 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
2010 } catch (InterruptedException | ExecutionException e) {
2011 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
2016 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
2017 return InstanceIdentifier.builder(ElanInstances.class)
2018 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
2021 public static Uint64 getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
2022 IElanService elanManager, IdManagerService idManager,
2023 Uint32 routerId, String routerName) {
2024 if (elanManager.isOpenStackVniSemanticsEnforced()) {
2025 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
2026 return natOverVxlanUtil.getRouterVni(routerName, routerId);
2028 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
2032 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, Uint64 naptDpnId,
2033 short tableId, TypedWriteTransaction<Configuration> confTx) {
2034 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2035 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
2037 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
2038 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
2039 List<MatchInfo> matches = new ArrayList<>();
2040 matches.add(MatchEthernetType.IPV4);
2041 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2042 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
2043 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
2044 matches, preDnatToSnatInstructions);
2046 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
2047 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
2048 preDnatToSnatTableFlowEntity, naptDpnId);
2051 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
2052 IMdsalApiManager mdsalManager, Uint64 naptDpnId) throws ExecutionException, InterruptedException {
2053 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2054 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
2055 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2056 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
2057 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
2058 flowRef, naptDpnId);
2061 private static String getFlowRefPreDnatToSnat(Uint64 dpnId, short tableId, String uniqueId) {
2062 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
2063 + NwConstants.FLOWID_SEPARATOR + uniqueId;
2066 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, Uint64 dpnId, String rd,
2067 String vpnName, String externalIp,
2068 Boolean isMoreThanOneFipCheckOnDpn) {
2069 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
2070 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
2071 if (dpnInVpn.isPresent()) {
2072 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2073 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2075 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2076 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2077 int floatingIpPresentCount = 0;
2078 for (IpAddresses ipAddress: ipAddressList) {
2079 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2080 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2081 floatingIpPresentCount++;
2082 //Add tunnel table check
2083 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2086 //Remove tunnel table check
2087 if (!isMoreThanOneFipCheckOnDpn) {
2093 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2097 } catch (NullPointerException e) {
2098 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2099 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2106 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, Uint64 dpnId) {
2107 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2108 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2109 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2113 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2114 throws ExecutionException, InterruptedException {
2115 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2119 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2120 if (vpnInstance == null) {
2123 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2124 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2127 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2128 return InstanceIdentifier.builder(VpnInstances.class)
2129 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2133 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2134 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2135 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2136 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2139 public static String validateAndAddNetworkMask(String ipAddress) {
2140 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2143 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2144 String vpnInterfaceName, String vpnName) {
2145 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2146 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2149 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2150 String routerName, Uint64 dpnId) {
2151 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2152 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2154 if (networkData != null && networkData.isPresent()) {
2155 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2156 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2157 for (Uuid routerUuid : routerUuidList) {
2158 String sharedRouterName = routerUuid.getValue();
2159 if (!routerName.equals(sharedRouterName)) {
2160 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2161 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2162 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2163 + "associated with other active router {} on NAPT switch {}", networkId,
2164 sharedRouterName, switchDpnId);
2174 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2175 String routerName, Uint64 dpnId) {
2176 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2177 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2178 .subnets.Subnets::getRouterIds).orElse(emptyList());
2179 if (!routerUuidList.isEmpty()) {
2180 for (Uuid routerUuid : routerUuidList) {
2181 String sharedRouterName = routerUuid.getValue();
2182 if (!routerName.equals(sharedRouterName)) {
2183 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2184 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2185 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2186 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2187 sharedRouterName, switchDpnId);
2196 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2197 Routers router, Uint64 primarySwitchId, int addOrRemove) {
2198 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2199 List<ExternalIps> externalIps = router.getExternalIps();
2200 List<String> externalIpsSting = new ArrayList<>();
2202 if (externalIps == null || externalIps.isEmpty()) {
2203 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2206 for (ExternalIps externalIp : externalIps) {
2207 externalIpsSting.add(externalIp.getIpAddress());
2209 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2210 if (addOrRemove == NwConstants.ADD_FLOW) {
2211 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2212 router.getNetworkId(), subnetVpnName.getValue(), tx);
2213 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2214 router.getExtGwMacAddress(), primarySwitchId,
2215 router.getNetworkId());
2217 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2218 router.getNetworkId(), subnetVpnName.getValue(), tx);
2219 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2220 router.getExtGwMacAddress(), primarySwitchId,
2221 router.getNetworkId());
2223 }), LOG, "Error installing router gateway flows");
2226 @SuppressWarnings("checkstyle:IllegalCatch")
2227 public static void handleSNATForDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2228 IdManagerService idManager, NaptSwitchHA naptSwitchHA,
2229 Uint64 dpnId, Routers extRouters, Uint32 routerId, Uint32 routerVpnId,
2230 TypedReadWriteTransaction<Configuration> confTx,
2231 ProviderTypes extNwProvType, UpgradeState upgradeState) {
2232 //Check if primary and secondary switch are selected, If not select the role
2233 //Install select group to NAPT switch
2234 //Install default miss entry to NAPT switch
2236 String routerName = extRouters.getRouterName();
2237 Boolean upgradeInProgress = false;
2238 if (upgradeState != null) {
2239 upgradeInProgress = upgradeState.isUpgradeInProgress();
2241 Uint64 naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2242 if (naptId == null || naptId.equals(Uint64.ZERO)
2243 || (!NatUtil.getSwitchStatus(dataBroker, naptId) && (upgradeInProgress == false))) {
2244 LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}",
2245 routerName, naptId);
2247 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
2249 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
2250 naptSwitch, routerName);
2253 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
2255 String externalVpnName = null;
2256 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
2257 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
2258 Uuid extNwUuid = extRouters.getNetworkId();
2259 externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNwUuid);
2260 if (externalVpnName != null) {
2261 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, extNwUuid,
2262 externalVpnName, confTx);
2264 // Install miss entry (table 26) pointing to table 46
2265 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
2266 routerVpnId, NatConstants.ADD_FLOW);
2267 if (flowEntity == null) {
2268 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
2272 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
2273 mdsalManager.addFlow(confTx, flowEntity);
2274 //Removing primary flows from old napt switch
2275 if (naptId != null && !naptId.equals(Uint64.ZERO)) {
2276 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
2277 naptId, routerName);
2279 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouters, routerId, naptId, null,
2280 externalVpnName, confTx);
2281 } catch (Exception e) {
2282 LOG.error("Exception while removing SnatFlows form OldNaptSwitch {}", naptId, e);
2285 naptSwitchHA.updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
2286 } else if (naptId.equals(dpnId)) {
2287 LOG.error("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
2289 naptSwitch = naptId;
2290 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
2291 naptId, routerName);
2294 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
2295 routerName, routerId, naptSwitch);
2296 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
2298 // Install miss entry (table 26) pointing to group
2299 Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
2300 NatUtil.getGroupIdKey(routerName));
2301 if (groupId != NatConstants.INVALID_ID) {
2302 FlowEntity flowEntity =
2303 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId.longValue(),
2304 routerVpnId, NatConstants.ADD_FLOW);
2305 if (flowEntity == null) {
2306 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}"
2307 + " groupId {}", routerName, dpnId, groupId);
2310 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
2311 dpnId, routerName, groupId);
2312 mdsalManager.addFlow(confTx, flowEntity);
2314 LOG.error("handleSNATForDPN: Unable to get groupId for router:{}", routerName);
2319 @SuppressWarnings("checkstyle:IllegalCatch")
2320 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2321 IdManagerService idManager, NaptSwitchHA naptSwitchHA, Uint64 dpnId,
2322 Routers extRouter, Uint32 routerId, Uint32 routerVpnId, String externalVpnName,
2323 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2324 throws ExecutionException, InterruptedException {
2325 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2326 //remove miss entry to NAPT switch
2327 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2328 if (extNwProvType == null) {
2331 String routerName = extRouter.getRouterName();
2332 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2333 Map<String, Uint32> externalIpLabel;
2334 if (extNwProvType == ProviderTypes.VXLAN) {
2335 externalIpLabel = null;
2337 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2339 Uint64 naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2340 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2341 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2344 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2345 boolean naptStatus =
2346 naptSwitchHA.isNaptSwitchDown(extRouter, routerId, dpnId, naptSwitch, routerVpnId,
2347 externalIpCache, confTx);
2349 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2351 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
2352 FlowEntity flowEntity = null;
2354 if (groupId != NatConstants.INVALID_ID) {
2355 flowEntity = naptSwitchHA
2356 .buildSnatFlowEntity(dpnId, routerName, groupId.longValue(), routerVpnId,
2357 NatConstants.DEL_FLOW);
2358 if (flowEntity == null) {
2359 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2360 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2363 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}",
2365 mdsalManager.removeFlow(confTx, flowEntity);
2367 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2370 } catch (Exception ex) {
2371 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2375 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2379 GroupEntity groupEntity = null;
2381 if (groupId != NatConstants.INVALID_ID) {
2382 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId.longValue(), routerName,
2383 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2384 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2385 mdsalManager.removeGroup(groupEntity);
2387 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2389 } catch (Exception ex) {
2390 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2393 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2396 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouter, routerId, naptSwitch,
2397 externalIpLabel, externalVpnName, confTx);
2398 //remove table 26 flow ppointing to table46
2399 FlowEntity flowEntity = null;
2401 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2402 NatConstants.DEL_FLOW);
2403 if (flowEntity == null) {
2404 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2408 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2409 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2410 mdsalManager.removeFlow(confTx, flowEntity);
2412 } catch (Exception ex) {
2413 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2417 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2420 //best effort to check IntExt model
2421 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2425 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2426 ProviderTypes extNwProvType) {
2427 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2428 || extNwProvType == ProviderTypes.VXLAN)) {
2434 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2435 Uint64 dpnId, DataBroker dataBroker) {
2436 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2437 elanInstanceName, dpnId);
2438 // FIXME: separate this out?
2439 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2442 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2443 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2444 List<String> elanInterfaceList = new ArrayList<>();
2445 DpnInterfaces dpnInterface;
2446 if (dpnInElanInterfaces.isPresent()) {
2447 dpnInterface = dpnInElanInterfaces.get();
2449 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2450 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2452 if (!elanInterfaceList.contains(pseudoPortId)) {
2453 elanInterfaceList.add(pseudoPortId);
2454 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2455 .withKey(new DpnInterfacesKey(dpnId)).build();
2456 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2457 elanDpnInterfaceId, dpnInterface);
2459 } catch (ReadFailedException e) {
2460 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2461 } catch (TransactionCommitFailedException e) {
2462 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2468 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2469 Uint64 dpnId, DataBroker dataBroker) {
2470 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2471 elanInstanceName, dpnId);
2472 // FIXME: separate this out?
2473 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2476 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2477 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2478 List<String> elanInterfaceList = new ArrayList<>();
2479 DpnInterfaces dpnInterface;
2480 if (!dpnInElanInterfaces.isPresent()) {
2481 LOG.info("No interface in any dpn for {}", elanInstanceName);
2485 dpnInterface = dpnInElanInterfaces.get();
2486 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2487 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2488 if (!elanInterfaceList.contains(pseudoPortId)) {
2489 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2492 elanInterfaceList.remove(pseudoPortId);
2493 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2494 .withKey(new DpnInterfacesKey(dpnId)).build();
2495 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2496 elanDpnInterfaceId, dpnInterface);
2497 } catch (ReadFailedException e) {
2498 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2499 } catch (TransactionCommitFailedException e) {
2500 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2506 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2507 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2508 for (Map.Entry<String,Routers> router : extRouter) {
2509 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2510 .equals(networkid)) {
2518 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2520 return SingleTransactionDataBroker.syncRead(dataBroker,
2521 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2523 catch (ReadFailedException e) {
2524 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2529 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2530 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2531 .builder(LearntVpnVipToPortData.class).build();
2532 return learntVpnVipToPortDataId;
2535 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2537 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2538 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2539 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2542 public static InstanceIdentifier<Group> getGroupInstanceId(Uint64 dpnId, Uint32 groupId) {
2543 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2544 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2545 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2548 public static void createGroupIdPool(IdManagerService idManager) {
2549 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2550 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2551 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2552 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2555 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2556 if (result != null && result.get().isSuccessful()) {
2557 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2559 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2561 } catch (InterruptedException | ExecutionException e) {
2562 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2566 public static boolean getSwitchStatus(DataBroker broker, Uint64 switchId) {
2567 NodeId nodeId = new NodeId("openflow:" + switchId);
2568 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2569 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2570 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2571 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2572 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2573 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2574 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2575 if (nodeOptional.isPresent()) {
2576 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2579 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2583 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2584 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2585 Optional<Networks> networkData =
2586 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2587 broker, LogicalDatastoreType.CONFIGURATION, id);
2588 return networkData.isPresent();
2592 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2593 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2594 if (null != elanInstance) {
2595 return elanInstance.getPhysicalNetworkName();
2601 public static Map<String, String> getOpenvswitchOtherConfigMap(Uint64 dpnId, DataBroker dataBroker) {
2602 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2603 return getMultiValueMap(otherConfigVal);
2606 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2607 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2608 return Collections.emptyMap();
2611 Map<String, String> valueMap = new HashMap<>();
2612 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2613 for (String keyValue : splitter.split(multiKeyValueStr)) {
2614 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2615 if (split.length == 2) {
2616 valueMap.put(split[0], split[1]);
2623 public static Optional<Node> getBridgeRefInfo(Uint64 dpnId, DataBroker dataBroker) {
2624 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2625 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2627 Optional<BridgeRefEntry> bridgeRefEntry =
2628 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2629 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2630 if (!bridgeRefEntry.isPresent()) {
2631 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2632 return Optional.absent();
2635 InstanceIdentifier<Node> nodeId =
2636 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2638 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2639 LogicalDatastoreType.OPERATIONAL, nodeId);
2643 public static String getProviderMappings(Uint64 dpId, DataBroker dataBroker) {
2644 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2645 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2649 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2650 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2651 if (ovsdbNode == null) {
2652 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2653 if (nodeFromReadOvsdbNode.isPresent()) {
2654 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2658 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2659 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2660 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2661 return openvswitchOtherConfigs.getOtherConfigValue();
2665 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2670 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2671 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2672 if (bridgeAugmentation != null) {
2673 InstanceIdentifier<Node> ovsdbNodeIid =
2674 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2675 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2676 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2678 return Optional.absent();
2683 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2687 return node.augmentation(OvsdbBridgeAugmentation.class);
2690 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, Uint64 dpnId) {
2691 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2694 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2695 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2696 InstanceIdentifier.builder(ExternalSubnets.class)
2699 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2700 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2701 if (optionalExternalSubnets.isPresent()) {
2702 return optionalExternalSubnets.get();
2704 } catch (ReadFailedException e) {
2705 LOG.error("Failed to read the subnets from the datastore.");
2711 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2712 Uint64 dpId, short tableId, String flowId, int priority, String flowName, Uint64 cookie,
2713 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2714 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2715 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2717 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2718 mdsalManager.addFlow(confTx, flowEntity);
2721 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2722 Uint64 dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2723 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2724 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2727 public static String getIpv6FlowRef(Uint64 dpnId, short tableId, Uint32 routerID) {
2728 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2729 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2732 public static String getTunnelInterfaceName(Uint64 srcDpId, Uint64 dstDpId,
2733 ItmRpcService itmManager) {
2734 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2735 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2737 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2738 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2739 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2740 rpcResult = result.get();
2741 if (!rpcResult.isSuccessful()) {
2742 tunType = TunnelTypeGre.class ;
2743 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2744 .setSourceDpid(srcDpId)
2745 .setDestinationDpid(dstDpId)
2746 .setTunnelType(tunType)
2748 rpcResult = result.get();
2749 if (!rpcResult.isSuccessful()) {
2750 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2751 rpcResult.getErrors());
2753 return rpcResult.getResult().getInterfaceName();
2755 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2756 rpcResult.getErrors());
2758 return rpcResult.getResult().getInterfaceName();
2760 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2761 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2762 + "between {} and {}", srcDpId, dstDpId);
2767 public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) {
2768 Port neutronPort = getNeutronPort(broker, ifaceName);
2769 if (neutronPort == null) {
2770 return Boolean.TRUE;
2772 return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE
2777 private static Port getNeutronPort(DataBroker broker, String ifaceName) {
2778 InstanceIdentifier<Port>
2779 portsIdentifier = InstanceIdentifier.create(Neutron.class)
2781 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class)
2782 .child(Port.class, new PortKey(new Uuid(ifaceName)));
2783 Optional<Port> portsOptional;
2785 portsOptional = SingleTransactionDataBroker
2786 .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
2787 } catch (ReadFailedException e) {
2788 LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e);
2789 portsOptional = Optional.absent();
2791 if (!portsOptional.isPresent()) {
2792 LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName);
2795 return portsOptional.get();
2798 public static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
2799 .instance.to.vpn.id.VpnInstance getVpnIdToVpnInstance(DataBroker broker, String vpnName) {
2800 if (vpnName == null) {
2804 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2805 .vpn.instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
2806 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2807 .vpn.instance.to.vpn.id.VpnInstance> vpnInstance = Optional.absent();
2809 vpnInstance = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, id);
2810 } catch (ReadFailedException e) {
2811 LOG.error("Failed to read VpnInstance {}", vpnInstance, e);
2813 if (vpnInstance.isPresent()) {
2814 return vpnInstance.get();
2820 public static Uint32 getExternalVpnIdForExtNetwork(DataBroker broker, Uuid externalNwUuid) {
2821 //Get the VPN ID from the ExternalNetworks model
2822 if (externalNwUuid == null) {
2823 LOG.error("getExternalVpnIdForExtNetwork : externalNwUuid is null");
2826 Uuid vpnUuid = getVpnIdfromNetworkId(broker, externalNwUuid);
2827 if (vpnUuid == null) {
2828 LOG.error("NAT Service : vpnUuid is null");
2831 Uint32 vpnId = getVpnId(broker, vpnUuid.getValue());
2835 static ReentrantLock lockForNat(final Uint64 dataPath) {
2836 // FIXME: wrap this in an Identifier
2837 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
2840 public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
2841 IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
2842 String interfaceName, String routerName) {
2843 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
2844 if (routerId == NatConstants.INVALID_ID) {
2845 LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
2848 Uint64 naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
2849 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2850 LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
2851 + "with Id {}", routerName, routerId);
2854 //getInternalIp for port
2855 List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
2856 if (fixedIps == null) {
2857 LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
2858 interfaceName, routerName, routerId);
2861 List<ProtocolTypes> protocolTypesList = getPortocolList();
2862 for (String internalIp : fixedIps) {
2863 LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
2864 interfaceName, internalIp, routerId);
2865 for (ProtocolTypes protocol : protocolTypesList) {
2866 List<Uint16> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
2867 if (portList != null) {
2868 for (Uint16 portnum : portList) {
2869 //build and remove the flow in outbound table
2870 removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
2871 routerId, internalIp, portnum.toJava(), protocol.getName());
2873 //build and remove the flow in inboundtable
2875 removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
2876 internalIp, portnum.toJava(), protocol.getName());
2878 //Get the external IP address and the port from the model
2880 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
2881 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
2882 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
2883 internalIp, String.valueOf(portnum.toJava()), proto);
2884 if (ipPortExternal == null) {
2885 LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
2886 + "with port {} is not found in "
2887 + "router with Id {}", internalIp, portnum, routerId);
2890 String externalIpAddress = ipPortExternal.getIpAddress();
2891 String internalIpPort = internalIp + ":" + portnum.toJava();
2892 // delete the entry from IntExtIpPortMap DS
2894 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
2895 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
2899 LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
2900 + "in router with id {}",
2901 protocol, interfaceName, internalIp, routerId);
2904 // delete the entry from SnatIntIpPortMap DS
2905 LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
2906 internalIp, routerId);
2907 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
2911 private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
2912 LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
2914 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
2915 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
2916 .setPortId(new Uuid(interfname)).build());
2918 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
2919 if (!rpcResult.isSuccessful()) {
2920 LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
2921 rpcResult.getErrors());
2923 return rpcResult.getResult().getFixedIPs();
2925 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
2926 LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
2931 private static List<ProtocolTypes> getPortocolList() {
2932 List<ProtocolTypes> protocollist = new ArrayList<>();
2933 protocollist.add(ProtocolTypes.TCP);
2934 protocollist.add(ProtocolTypes.UDP);
2935 return protocollist;
2938 private static void removeNatFlow(IMdsalApiManager mdsalManager, Uint64 dpnId, short tableId, Uint32 routerId,
2939 String ipAddress, int ipPort, String protocol) {
2941 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
2943 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
2945 mdsalManager.removeFlow(snatFlowEntity);
2946 LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
2947 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
2950 public static String getDpnFromNodeRef(NodeRef node) {
2951 PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
2952 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
2953 InstanceIdentifier.IdentifiableItem.class);
2954 NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
2955 String dpnKey = key.getId().getValue();
2956 String dpnID = null;
2957 if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
2958 dpnID = Uint64.valueOf(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();