2 * Copyright © 2016, 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.natservice.internal;
10 import static java.util.Collections.emptyList;
11 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
13 import com.google.common.base.Preconditions;
14 import com.google.common.base.Splitter;
15 import com.google.common.base.Strings;
16 import com.google.common.collect.Iterables;
17 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
18 import java.math.BigInteger;
19 import java.net.InetAddress;
20 import java.net.UnknownHostException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
28 import java.util.Objects;
29 import java.util.Optional;
31 import java.util.concurrent.ExecutionException;
32 import java.util.concurrent.Future;
33 import java.util.concurrent.locks.ReentrantLock;
34 import java.util.stream.Collectors;
35 import org.apache.commons.net.util.SubnetUtils;
36 import org.eclipse.jdt.annotation.NonNull;
37 import org.eclipse.jdt.annotation.Nullable;
38 import org.opendaylight.controller.sal.common.util.Arguments;
39 import org.opendaylight.genius.datastoreutils.ExpectedDataObjectNotFoundException;
40 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
41 import org.opendaylight.genius.infra.Datastore.Configuration;
42 import org.opendaylight.genius.infra.Datastore.Operational;
43 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
44 import org.opendaylight.genius.infra.TypedReadTransaction;
45 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
46 import org.opendaylight.genius.infra.TypedWriteTransaction;
47 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
48 import org.opendaylight.genius.mdsalutil.ActionInfo;
49 import org.opendaylight.genius.mdsalutil.BucketInfo;
50 import org.opendaylight.genius.mdsalutil.FlowEntity;
51 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
52 import org.opendaylight.genius.mdsalutil.GroupEntity;
53 import org.opendaylight.genius.mdsalutil.InstructionInfo;
54 import org.opendaylight.genius.mdsalutil.MDSALUtil;
55 import org.opendaylight.genius.mdsalutil.MatchInfo;
56 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
57 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
58 import org.opendaylight.genius.mdsalutil.NwConstants;
59 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
60 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
61 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
62 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
63 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
64 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
65 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
66 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
67 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
68 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
69 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
70 import org.opendaylight.genius.utils.JvmGlobalLocks;
71 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
72 import org.opendaylight.mdsal.binding.api.DataBroker;
73 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
74 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
75 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
76 import org.opendaylight.netvirt.elanmanager.api.IElanService;
77 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
78 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
79 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
80 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
81 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
82 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
83 import org.opendaylight.serviceutils.upgrade.UpgradeState;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
87 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddressesKey;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
222 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;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.Interfaces;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map.router.interfaces.InterfacesKey;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
262 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
263 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
264 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
265 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
266 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
267 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
268 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
269 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
270 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;
271 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
272 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
273 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
274 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
275 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
276 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
277 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
278 import org.opendaylight.yangtools.yang.common.RpcResult;
279 import org.opendaylight.yangtools.yang.common.Uint16;
280 import org.opendaylight.yangtools.yang.common.Uint32;
281 import org.opendaylight.yangtools.yang.common.Uint64;
282 import org.slf4j.Logger;
283 import org.slf4j.LoggerFactory;
285 public final class NatUtil {
287 private static String OF_URI_SEPARATOR = ":";
288 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
289 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
290 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
291 private static final String PROVIDER_MAPPINGS = "provider_mappings";
298 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
301 public static Uint64 getCookieSnatFlow(long routerId) {
302 return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0110000", 16)).add(
303 BigInteger.valueOf(routerId)));
307 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
310 public static Uint64 getCookieNaptFlow(Uint32 routerId) {
311 return Uint64.valueOf(NatConstants.COOKIE_NAPT_BASE.toJava().add(new BigInteger("0111000", 16)).add(
312 BigInteger.valueOf(routerId.longValue())));
316 getVpnId() returns the VPN ID from the VPN name
318 public static Uint32 getVpnId(DataBroker broker, @Nullable String vpnName) {
319 if (vpnName == null) {
320 return NatConstants.INVALID_ID;
323 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
324 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
325 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
326 .instance.to.vpn.id.VpnInstance> vpnInstance =
327 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
328 LogicalDatastoreType.CONFIGURATION, id);
330 Uint32 vpnId = NatConstants.INVALID_ID;
331 if (vpnInstance.isPresent()) {
332 Uint32 vpnIdAsLong = vpnInstance.get().getVpnId();
333 if (vpnIdAsLong != null) {
340 public static Uint32 getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
341 if (vpnName == null) {
342 return NatConstants.INVALID_ID;
346 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().map(
347 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
348 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
349 } catch (InterruptedException | ExecutionException e) {
350 LOG.error("Error retrieving VPN id for {}", vpnName, e);
353 return NatConstants.INVALID_ID;
356 public static Uint32 getNetworkVpnIdFromRouterId(DataBroker broker, Uint32 routerId) {
357 //Get the external network ID from the ExternalRouter model
358 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
359 if (networkId == null) {
360 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
361 return NatConstants.INVALID_ID;
364 //Get the VPN ID from the ExternalNetworks model
365 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
366 if (vpnUuid == null) {
367 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
368 return NatConstants.INVALID_ID;
370 Uint32 vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
374 public static Boolean validateIsIntefacePartofRouter(DataBroker broker, String routerName, String interfaceName) {
375 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
376 .map.router.interfaces.Interfaces> vmInterfaceIdentifier = getRoutersInterfacesIdentifier(routerName,
379 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
380 .map.router.interfaces.Interfaces> routerInterfacesData;
382 routerInterfacesData = SingleTransactionDataBroker.syncReadOptional(broker,
383 LogicalDatastoreType.CONFIGURATION, vmInterfaceIdentifier);
384 } catch (InterruptedException | ExecutionException e) {
385 LOG.error("Read Failed Exception While read RouterInterface data for router {}", routerName, e);
386 routerInterfacesData = Optional.empty();
388 if (routerInterfacesData.isPresent()) {
391 return Boolean.FALSE;
395 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
396 .rev150602.router.interfaces
397 .map.router.interfaces.Interfaces> getRoutersInterfacesIdentifier(String routerName, String interfaceName) {
398 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
399 .rev150602.RouterInterfacesMap.class)
400 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
401 .interfaces.map.RouterInterfaces.class,
402 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
403 .interfaces.map.RouterInterfacesKey(new Uuid(routerName)))
404 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
405 .map.router.interfaces.Interfaces.class,
406 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
407 .map.router.interfaces.InterfacesKey(interfaceName)).build();
410 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
411 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
412 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
413 .rev150602.RouterInterfacesMap.class)
414 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
415 .interfaces.map.RouterInterfaces.class,
416 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
417 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
420 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
421 return InstanceIdentifier.builder(FloatingIpInfo.class)
422 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
425 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
426 return InstanceIdentifier.builder(RouterToVpnMapping.class)
427 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
430 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
431 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
432 .child(Ports.class, new PortsKey(portName)).build();
435 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
437 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
438 .child(Ports.class, new PortsKey(portName))
439 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
442 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
443 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
444 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
445 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
446 .instance.to.vpn.id.VpnInstance.class,
447 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
448 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
452 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, Uint32 vpnId) {
453 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
454 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
455 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
456 LogicalDatastoreType.CONFIGURATION, id).map(VpnIds::getVpnInstanceName).orElse(null);
460 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
462 public static String getFlowRef(Uint64 dpnId, short tableId, Uint32 routerID, String ip) {
463 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
464 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
465 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
468 public static String getFlowRef(Uint64 dpnId, short tableId, InetAddress destPrefix, Uint32 vpnId) {
469 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
470 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
471 .append(destPrefix.getHostAddress()).append(NatConstants.FLOWID_SEPARATOR).append(vpnId).toString();
474 public static String getNaptFlowRef(Uint64 dpnId, short tableId, String routerID, String ip,
475 int port, String protocol) {
476 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
477 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
478 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).append(NatConstants.FLOWID_SEPARATOR)
479 .append(port).append(NatConstants.FLOWID_SEPARATOR).append(protocol).toString();
483 static Uuid getNetworkIdFromRouterId(DataBroker broker, Uint32 routerId) {
484 String routerName = getRouterName(broker, routerId);
485 if (routerName == null) {
486 LOG.error("getNetworkIdFromRouterId - empty routerName received");
489 return getNetworkIdFromRouterName(broker, routerName);
493 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
494 if (routerName == null) {
495 LOG.error("getNetworkIdFromRouterName - empty routerName received");
498 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
499 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
500 LogicalDatastoreType.CONFIGURATION, id).map(Routers::getNetworkId).orElse(null);
503 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
504 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
505 .child(Routers.class, new RoutersKey(routerId)).build();
506 return routerInstanceIndentifier;
509 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Uint32 routerId) {
510 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
511 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
516 * Return if SNAT is enabled for the given router.
518 * @param broker The DataBroker
519 * @param routerId The router
520 * @return boolean true if enabled, otherwise false
522 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
523 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
524 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
525 LogicalDatastoreType.CONFIGURATION, id).map(Routers::isEnableSnat).orElse(false);
529 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
530 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
531 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
532 LogicalDatastoreType.CONFIGURATION, id).map(Networks::getVpnid).orElse(null);
536 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
538 return tx.read(buildNetworkIdentifier(networkId)).get().map(Networks::getVpnid).orElse(null);
539 } catch (InterruptedException | ExecutionException e) {
540 LOG.error("Error reading network VPN id for {}", networkId, e);
546 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
547 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
548 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
549 LogicalDatastoreType.CONFIGURATION, id).map(Networks::getProviderNetworkType).orElse(null);
553 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
554 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
556 return tx.read(id).get().map(Networks::getProviderNetworkType).orElse(null);
557 } catch (InterruptedException | ExecutionException e) {
558 LOG.error("Error retrieving provider type for {}", networkId, e);
564 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
565 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
566 Optional<Routers> routerData =
567 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
568 LogicalDatastoreType.CONFIGURATION, id);
569 if (routerData.isPresent()) {
570 Uuid networkId = routerData.get().getNetworkId();
571 if (networkId != null) {
572 return networkId.getValue();
575 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
579 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
580 return InstanceIdentifier.builder(ExternalNetworks.class)
581 .child(Networks.class, new NetworksKey(networkId)).build();
585 public static Uint64 getPrimaryNaptfromRouterId(DataBroker broker, Uint32 routerId) {
586 // convert routerId to Name
587 String routerName = getRouterName(broker, routerId);
588 if (routerName == null) {
589 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
592 return getPrimaryNaptfromRouterName(broker, routerName);
596 public static Uint64 getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
597 if (routerName == null) {
598 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
601 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
602 return (SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
603 LogicalDatastoreType.CONFIGURATION, id).map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
604 Uint64.valueOf(0L)));
607 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
608 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
609 new RouterToNaptSwitchKey(routerId)).build();
612 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
613 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
614 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
618 public static String getRouterName(DataBroker broker, Uint32 routerId) {
619 return getVpnInstanceFromVpnIdentifier(broker, routerId);
622 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
623 return InstanceIdentifier.builder(VpnInstanceOpData.class)
624 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
627 public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, Uint64 cookie, String flowId) {
628 return new FlowEntityBuilder()
636 public static FlowEntity buildFlowEntity(Uint64 dpnId, short tableId, String flowId) {
637 return new FlowEntityBuilder()
645 public static String getEndpointIpAddressForDPN(DataBroker broker, Uint64 dpnId) {
646 String nextHopIp = null;
647 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
648 InstanceIdentifier.builder(DpnEndpoints.class)
649 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
650 Optional<DPNTEPsInfo> tunnelInfo =
651 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
652 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
653 if (tunnelInfo.isPresent()) {
654 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
655 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
656 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
663 public static String getVpnRd(DataBroker broker, String vpnName) {
664 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
665 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
666 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
667 LogicalDatastoreType.CONFIGURATION, id).map(
668 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
669 .VpnInstance::getVrfId).orElse(null);
673 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
675 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().map(
676 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
677 .VpnInstance::getVrfId).orElse(null);
678 } catch (InterruptedException | ExecutionException e) {
679 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
685 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Uint32 routerId, String internalIpAddress,
686 String internalPort, NAPTEntryEvent.Protocol protocol) {
687 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
688 InstanceIdentifier<IpPortMap> ipPortMapId =
689 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
690 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
691 LogicalDatastoreType.CONFIGURATION, ipPortMapId).map(IpPortMap::getIpPortExternal).orElse(
695 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Uint32 routerId, String internalIpAddress,
697 ProtocolTypes protocolType) {
698 return InstanceIdentifier.builder(IntextIpPortMap.class)
699 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
700 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
701 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
704 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
705 return InstanceIdentifier.builder(VpnInterfaces.class)
706 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
710 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
712 * NodeConnectorId is of form 'openflow:dpnid:portnum'
714 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
715 if (split.length != 3) {
716 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
722 public static Uint64 getDpIdFromInterface(
723 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
724 .state.Interface ifState) {
725 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
726 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
727 return Uint64.valueOf(getDpnFromNodeConnectorId(nodeConnectorId));
732 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
733 // returns only router, attached to IPv4 networks
734 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
735 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
736 Optional<VpnMap> optionalVpnMap =
737 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
738 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
739 if (!optionalVpnMap.isPresent()) {
740 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
743 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(
744 new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602
745 .vpnmaps.vpnmap.RouterIds>(optionalVpnMap.get().nonnullRouterIds().values()));
746 if (routerIdsList != null && !routerIdsList.isEmpty()) {
747 for (Uuid routerUuid : routerIdsList) {
748 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
749 Optional<Routers> routerData =
750 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
751 LogicalDatastoreType.CONFIGURATION, id);
752 if (routerData.isPresent()) {
753 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
754 for (Uuid subnetUuid : subnetIdsList) {
755 String subnetIp = getSubnetIp(broker, subnetUuid);
756 SubnetUtils subnet = new SubnetUtils(subnetIp);
757 if (subnet.getInfo().isInRange(ipAddress)) {
758 return routerUuid.getValue();
764 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
769 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
770 Preconditions.checkNotNull(routerId, "getVpnForRouter: routerId not found!");
771 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
772 Optional<VpnMaps> optionalVpnMaps =
773 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
774 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
775 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
776 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap().values()) {
777 if (routerId.equals(vpnMap.getVpnId().getValue())) {
780 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(
781 new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602
782 .vpnmaps.vpnmap.RouterIds>(vpnMap.nonnullRouterIds().values()));
783 if (routerIdsList.isEmpty()) {
786 // Skip router vpnId fetching from internet BGP-VPN
787 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
788 // We only need to check the first network; if it’s not an external network there’s no
789 // need to check the rest of the VPN’s network list
790 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
794 if (routerIdsList.contains(new Uuid(routerId))) {
795 return vpnMap.getVpnId();
799 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
803 static Uint32 getAssociatedVpn(DataBroker broker, String routerName) {
804 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
805 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
806 LogicalDatastoreType.OPERATIONAL, routerMappingId).map(Routermapping::getVpnId).orElse(
807 NatConstants.INVALID_ID);
811 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
812 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
813 if (vpnUuid == null) {
814 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
817 return vpnUuid.getValue();
821 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
822 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
823 if (vpnUuid == null) {
824 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
827 return vpnUuid.getValue();
830 // TODO Clean up the exception handling
831 @SuppressWarnings("checkstyle:IllegalCatch")
832 public static void addPrefixToBGP(DataBroker broker,
833 IBgpManager bgpManager,
834 IFibManager fibManager,
839 @Nullable String parentVpnRd,
840 @Nullable String macAddress,
846 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
847 prefix, nextHopIp, label);
848 if (nextHopIp == null) {
849 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
854 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
855 dpId, Prefixes.PrefixCue.Nat);
857 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
858 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, label, l3vni /*l3vni*/,
859 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
860 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
861 /* Publish to Bgp only if its an INTERNET VPN */
862 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
863 VrfEntry.EncapType.Mplsgre, label, Uint32.ZERO /*l3vni*/, Uint32.ZERO /*l2vni*/,
864 null /*gatewayMac*/);
866 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
867 prefix, nextHopIp, label);
868 } catch (Exception e) {
869 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
870 prefix, nextHopIp, label, e);
874 static void addPrefixToInterface(DataBroker broker, Uint32 vpnId, @Nullable String interfaceName, String ipPrefix,
875 String networkId, Uint64 dpId, Prefixes.PrefixCue prefixCue) {
876 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
877 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
878 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
879 .to._interface.VpnIdsKey(vpnId))
880 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
881 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
882 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
883 prefixBuilder.setNetworkId(new Uuid(networkId));
885 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
886 prefixBuilder.build());
887 } catch (TransactionCommitFailedException e) {
888 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
889 ipPrefix, vpnId, dpId, e);
893 public static void deletePrefixToInterface(DataBroker broker, Uint32 vpnId, String ipPrefix) {
895 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
896 InstanceIdentifier.builder(PrefixToInterface.class)
897 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
898 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
899 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
901 } catch (TransactionCommitFailedException e) {
902 LOG.error("deletePrefixToInterface : Failed to delete prefxi-to-interface for vpn-id {}",
907 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
908 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
909 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
913 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
914 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
915 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
916 return routerInstanceIndentifier;
920 public static List<Uint16> getInternalIpPortListInfo(DataBroker dataBroker, Uint32 routerId,
921 String internalIpAddress, ProtocolTypes protocolType) {
922 List<Uint16> portList = SingleTransactionDataBroker
923 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
924 LogicalDatastoreType.CONFIGURATION,
925 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).map(
926 IntIpProtoType::getPorts).orElse(emptyList());
928 if (!portList.isEmpty()) {
929 portList = new ArrayList<>(portList);
934 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Uint32 routerId,
935 String internalIpAddress,
936 ProtocolTypes protocolType) {
937 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
938 InstanceIdentifier.builder(SnatintIpPortMap.class)
939 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
940 .child(IpPort.class, new IpPortKey(internalIpAddress))
941 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
942 return intIpProtocolTypeId;
945 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
946 String internalIpAddress) {
947 InstanceIdentifier<IpPort> intIpProtocolTypeId =
948 InstanceIdentifier.builder(SnatintIpPortMap.class)
949 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
950 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
951 return intIpProtocolTypeId;
955 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
956 String internalIpAddress) {
957 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
958 LogicalDatastoreType.CONFIGURATION,
959 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orElse(null);
962 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
963 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
964 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
968 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
969 return InstanceIdentifier.create(NaptSwitches.class);
972 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
973 return InstanceIdentifier.create(NaptSwitches.class)
974 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
977 public static String getGroupIdKey(String routerName) {
978 return "snatmiss." + routerName;
981 public static Uint32 getUniqueId(IdManagerService idManager, String poolName, String idKey) {
983 AllocateIdInput getIdInput = (new AllocateIdInputBuilder()).setPoolName(poolName).setIdKey(idKey).build();
985 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
986 RpcResult<AllocateIdOutput> rpcResult = (RpcResult)result.get();
987 return rpcResult.isSuccessful() ? rpcResult.getResult().getIdValue()
988 : NatConstants.INVALID_ID;
989 } catch (InterruptedException | ExecutionException e) {
990 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
992 return NatConstants.INVALID_ID;
995 public static Uint32 releaseId(IdManagerService idManager, String poolName, String idKey) {
996 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
998 Future<RpcResult<ReleaseIdOutput>> result = idManager.releaseId(idInput);
999 if (result == null || result.get() == null || !result.get().isSuccessful()) {
1000 LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}",
1002 (result != null && result.get() != null) ? result.get().getErrors() : "RpcResult is null");
1006 } catch (InterruptedException | ExecutionException e) {
1007 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
1009 return NatConstants.INVALID_ID;
1012 // TODO Clean up the exception handling
1013 @SuppressWarnings("checkstyle:IllegalCatch")
1014 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
1015 String rd, String prefix, String vpnName) {
1017 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
1018 fibManager.removeFibEntry(rd, prefix, null, null);
1019 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
1020 bgpManager.withdrawPrefix(rd, prefix);
1022 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
1023 } catch (Exception e) {
1024 LOG.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
1025 rd, prefix, vpnName, e);
1030 public static IpPortMapping getIportMapping(DataBroker broker, Uint32 routerId) {
1031 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1032 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orElse(null);
1035 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(Uint32 routerId) {
1036 return InstanceIdentifier.builder(IntextIpPortMap.class)
1037 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
1040 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1041 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Uint32 routerId) {
1042 return InstanceIdentifier.builder(IntextIpMap.class)
1043 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
1044 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
1045 .intext.ip.map.IpMappingKey(routerId))
1050 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Uint32 routerId) {
1051 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1052 .ip.map.IpMapping> ipMappingOptional =
1053 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1054 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1055 // Ensure there are no duplicates
1056 Collection<String> externalIps = new HashSet<>();
1057 if (ipMappingOptional.isPresent()) {
1058 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap().values()) {
1059 externalIps.add(ipMap.getExternalIp());
1066 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
1067 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1068 if (routerData != null) {
1069 return NatUtil.getIpsListFromExternalIps(
1070 new ArrayList<ExternalIps>(routerData.nonnullExternalIps().values()));
1077 public static Map<String, Uint32> getExternalIpsLabelForRouter(DataBroker dataBroker, Uint32 routerId) {
1078 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1079 .ip.map.IpMapping> ipMappingOptional =
1080 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1081 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1082 Map<String, Uint32> externalIpsLabel = new HashMap<>();
1083 if (ipMappingOptional.isPresent()) {
1084 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap().values()) {
1085 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1088 return externalIpsLabel;
1092 public static String getLeastLoadedExternalIp(DataBroker dataBroker, Uint32 segmentId) {
1093 String leastLoadedExternalIp = null;
1094 InstanceIdentifier<ExternalCounters> id =
1095 InstanceIdentifier.builder(ExternalIpsCounter.class)
1096 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1097 Optional<ExternalCounters> externalCountersData;
1099 externalCountersData = SingleTransactionDataBroker.syncReadOptional(dataBroker,
1100 LogicalDatastoreType.OPERATIONAL, id);
1101 } catch (ExecutionException | InterruptedException e) {
1102 LOG.error("getLeastLoadedExternalIp: Exception while reading ExternalCounters DS for the segmentId {}",
1104 return leastLoadedExternalIp;
1106 if (externalCountersData.isPresent()) {
1107 ExternalCounters externalCounter = externalCountersData.get();
1108 short countOfLstLoadExtIp = 32767;
1109 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter().values()) {
1110 String curExternalIp = externalIpCounter.getExternalIp();
1111 short countOfCurExtIp = externalIpCounter.getCounter().toJava();
1112 if (countOfCurExtIp < countOfLstLoadExtIp) {
1113 countOfLstLoadExtIp = countOfCurExtIp;
1114 leastLoadedExternalIp = curExternalIp;
1118 return leastLoadedExternalIp;
1121 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1123 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1124 String subnetIP = getSubnetIp(dataBroker, subnetId);
1125 if (subnetIP != null) {
1126 return getSubnetIpAndPrefix(subnetIP);
1128 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1133 public static String[] getSubnetIpAndPrefix(String subnetString) {
1134 String[] subnetSplit = subnetString.split("/");
1135 String subnetIp = subnetSplit[0];
1136 String subnetPrefix = "0";
1137 if (subnetSplit.length == 2) {
1138 subnetPrefix = subnetSplit[1];
1140 return new String[] {subnetIp, subnetPrefix};
1144 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1145 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1146 .builder(Subnetmaps.class)
1147 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1149 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1150 LogicalDatastoreType.CONFIGURATION, subnetmapId).map(Subnetmap::getSubnetIp).orElse(null);
1153 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1154 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1155 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1156 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1157 if (leastLoadedExtIpAddrSplit.length == 2) {
1158 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1160 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1164 public static List<Uint64> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1165 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1166 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1167 Optional<RouterDpnList> routerDpnListData =
1168 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1169 LogicalDatastoreType.OPERATIONAL, id);
1170 List<Uint64> dpns = new ArrayList<>();
1171 if (routerDpnListData.isPresent()) {
1172 for (DpnVpninterfacesList dpnVpnInterface
1173 : routerDpnListData.get().nonnullDpnVpninterfacesList().values()) {
1174 dpns.add(dpnVpnInterface.getDpnId());
1180 public static Uint32 getBgpVpnId(DataBroker dataBroker, String routerName) {
1181 Uint32 bgpVpnId = NatConstants.INVALID_ID;
1182 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1183 if (bgpVpnUuid != null) {
1184 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1189 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1190 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1191 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1192 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orElse(null);
1195 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1196 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1197 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1198 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1199 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1200 .RouterInterface.class,
1201 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1202 .RouterInterfaceKey(interfaceName)).build();
1205 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, Uint64 dpId,
1206 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1208 if (dpId.equals(Uint64.ZERO)) {
1209 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1210 + "to handle router {} association model", interfaceName, routerName);
1214 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1215 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1216 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1218 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1219 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1220 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1221 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1222 .setInterface(interfaceName).build();
1223 if (optionalDpnVpninterfacesList.isPresent()) {
1224 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1225 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1226 operTx.mergeParentStructureMerge(dpnVpnInterfacesListIdentifier
1227 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1228 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1229 new RouterInterfacesKey(interfaceName)), routerInterface);
1231 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1232 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1233 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1234 routerDpnListBuilder.setRouterId(routerName);
1235 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1236 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1237 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1238 routerInterfaces.add(routerInterface);
1239 dpnVpnList.setRouterInterfaces(routerInterfaces);
1240 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1241 operTx.mergeParentStructureMerge(getRouterId(routerName), routerDpnListBuilder.build());
1245 public static void addToDpnRoutersMap(String routerName, String interfaceName, Uint64 dpId,
1246 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1247 if (dpId.equals(Uint64.ZERO)) {
1248 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1249 + "association model", interfaceName, routerName);
1253 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1254 + "DPNRouters map", dpId, routerName, interfaceName);
1255 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1257 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1259 if (optionalDpnRoutersList.isPresent()) {
1260 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1261 .setRouter(routerName).build();
1262 Map<RoutersListKey, RoutersList> keyroutersMapFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1263 if (!keyroutersMapFromDs.values().contains(routersList)) {
1264 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1265 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1266 operTx.mergeParentStructureMerge(dpnRoutersListIdentifier
1267 .child(RoutersList.class, new RoutersListKey(routerName)), routersList);
1269 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1270 + "DPNRouters map", routerName, dpId);
1273 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1274 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1275 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1276 dpnRoutersListBuilder.setDpnId(dpId);
1277 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1278 routersListBuilder.setRouter(routerName);
1279 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1280 operTx.mergeParentStructureMerge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build());
1284 public static void removeFromNeutronRouterDpnsMap(String routerName, Uint64 dpId,
1285 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1286 if (dpId.equals(Uint64.ZERO)) {
1287 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1291 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1292 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1293 if (optionalRouterDpnList.isPresent()) {
1294 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1295 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1296 operTx.delete(routerDpnListIdentifier);
1298 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1299 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1303 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1304 Uint64 dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1305 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1306 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1308 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1309 } catch (InterruptedException | ExecutionException e) {
1310 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1311 optionalRouterDpnList = Optional.empty();
1313 if (optionalRouterDpnList.isPresent()) {
1314 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1315 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1316 new ArrayList<>(optionalRouterDpnList.get().nonnullRouterInterfaces().values());
1317 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1318 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1319 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1320 .setInterface(vpnInterfaceName).build();
1322 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1323 if (routerInterfaces.isEmpty()) {
1324 operTx.delete(routerDpnListIdentifier);
1326 operTx.delete(routerDpnListIdentifier.child(
1327 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1328 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1329 new RouterInterfacesKey(vpnInterfaceName)));
1335 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1336 Uint64 curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1337 throws ExecutionException, InterruptedException {
1339 1) Get the DpnRoutersList for the DPN.
1340 2) Get the RoutersList identifier for the DPN and router.
1341 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1342 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1343 then remove RouterList.
1346 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1347 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1349 //Get the dpn-routers-list instance for the current DPN.
1350 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1351 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1353 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1354 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1355 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1359 //Get the routers-list instance for the router on the current DPN only
1360 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1361 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1363 if (routersListData == null || !routersListData.isPresent()) {
1364 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1365 + "in the ODL-L3VPN:dpn-routers model",
1370 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1371 + "from the NeutronVPN - router-interfaces-map", routerName);
1372 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1373 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1374 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1375 .RouterInterfaces> routerInterfacesData =
1376 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1377 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1379 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1380 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1381 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1382 curDpnId, routerName, routerName);
1383 operTx.delete(routersListIdentifier);
1387 //Get the VM interfaces for the router on the current DPN only.
1388 Map<InterfacesKey, Interfaces> vmInterfacesMap
1389 = routerInterfacesData.get().nonnullInterfaces();
1390 if (vmInterfacesMap == null) {
1391 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1392 + "NeutronVPN - router-interfaces-map", routerName);
1396 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1397 // then remove RouterList.
1398 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1399 .router.interfaces.Interfaces vmInterface : vmInterfacesMap.values()) {
1400 String vmInterfaceName = vmInterface.getInterfaceId();
1401 Uint64 vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1402 if (vmDpnId.equals(Uint64.ZERO) || !vmDpnId.equals(curDpnId)) {
1403 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1404 + "the DPN ID {} for the checked interface {}",
1405 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1408 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1409 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1410 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1414 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1415 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1416 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1417 operTx.delete(routersListIdentifier);
1420 private static InstanceIdentifier<RoutersList> getRoutersList(Uint64 dpnId, String routerName) {
1421 return InstanceIdentifier.builder(DpnRouters.class)
1422 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1423 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1426 public static Uint64 getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1427 Uint64 nodeId = Uint64.ZERO;
1429 GetDpidFromInterfaceInput
1431 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1432 Future<RpcResult<GetDpidFromInterfaceOutput>>
1434 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1435 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1436 if (dpIdResult.isSuccessful()) {
1437 nodeId = dpIdResult.getResult().getDpid();
1439 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1441 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1442 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1448 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1449 ItmRpcService itmRpcService,
1450 IInterfaceManager interfaceManager, String ifName,
1451 Uint32 tunnelKey, boolean internalTunnelInterface) {
1452 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1453 ifName, tunnelKey, 0, internalTunnelInterface);
1457 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1458 ItmRpcService itmRpcService,
1459 IInterfaceManager interfaceManager,
1460 String ifName, @Nullable Uint32 tunnelKey, int pos,
1461 boolean internalTunnelInterface) {
1462 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1463 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1464 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1465 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1466 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1467 if (tunnelKey != null) {
1468 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1469 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1470 } //init builders, ITM/IFM rpc can be called based on type of interface
1473 List<Action> actions = emptyList();
1474 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1475 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1476 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1477 if (!rpcResult.isSuccessful()) {
1478 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1479 + "returned with Errors {}", ifName, rpcResult.getErrors());
1481 actions = new ArrayList<Action>(rpcResult.getResult().nonnullAction().values());
1484 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1485 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1486 if (!rpcResult.isSuccessful()) {
1487 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1488 + "returned with Errors {}", ifName, rpcResult.getErrors());
1490 actions = new ArrayList<Action>(rpcResult.getResult().nonnullAction().values());
1493 List<ActionInfo> listActionInfo = new ArrayList<>();
1494 for (Action action : actions) {
1495 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1496 actionClass = action.getAction();
1497 if (actionClass instanceof OutputActionCase) {
1498 listActionInfo.add(new ActionOutput(pos++,
1499 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1500 } else if (actionClass instanceof PushVlanActionCase) {
1501 listActionInfo.add(new ActionPushVlan(pos++));
1502 } else if (actionClass instanceof SetFieldCase) {
1503 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1504 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1505 .getVlanId().getValue().toJava();
1506 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1508 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1509 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable().toJava();
1510 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1511 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1512 NxRegLoad nxRegLoad =
1513 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1514 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart().toJava(),
1515 nxRegLoad.getDst().getEnd().toJava(), nxRegLoad.getValue().longValue()));
1518 return listActionInfo;
1519 } catch (InterruptedException | ExecutionException e) {
1520 LOG.error("Exception when egress actions for interface {}", ifName, e);
1522 LOG.error("Error when getting egress actions for interface {}", ifName);
1527 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1528 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1532 public static List<Port> getNeutronPorts(DataBroker broker) {
1533 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1534 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1535 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1536 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1538 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1539 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1541 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1542 LOG.error("getNeutronPorts : No neutron ports found");
1546 return new ArrayList<Port>(portsOptional.get().nonnullPort().values());
1550 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1551 List<Port> ports = getNeutronPorts(
1554 for (Port port : ports) {
1555 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1556 for (FixedIps ip : port.nonnullFixedIps().values()) {
1557 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1563 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1568 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1570 LOG.error("getSubnetIdForFloatingIp : port is null");
1573 for (FixedIps ip : port.nonnullFixedIps().values()) {
1574 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1575 return ip.getSubnetId();
1578 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1583 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1584 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1585 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1586 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1587 LogicalDatastoreType.CONFIGURATION, subnetmapId).orElse(null);
1591 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1592 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1593 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1594 List<Uuid> subnetIdList = SingleTransactionDataBroker
1595 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1596 LogicalDatastoreType.CONFIGURATION, id).map(NetworkMap::getSubnetIdList).orElse(
1598 if (!subnetIdList.isEmpty()) {
1599 subnetIdList = new ArrayList<>(subnetIdList);
1602 return subnetIdList;
1606 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1607 if (subnetId == null) {
1608 LOG.error("getSubnetGwMac : subnetID is null");
1612 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1613 .child(Subnet.class, new SubnetKey(subnetId));
1614 Optional<Subnet> subnetOpt =
1615 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1616 LogicalDatastoreType.CONFIGURATION, subnetInst);
1617 if (!subnetOpt.isPresent()) {
1618 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1622 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1623 if (gatewayIp == null) {
1624 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1628 if (null != gatewayIp.getIpv6Address()) {
1632 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1633 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1635 Optional<VpnPortipToPort> portIpToPortOpt =
1636 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1637 LogicalDatastoreType.CONFIGURATION, portIpInst);
1638 if (portIpToPortOpt.isPresent()) {
1639 return portIpToPortOpt.get().getMacAddress();
1642 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1643 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1645 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1646 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1647 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1648 if (learntIpToPortOpt.isPresent()) {
1649 return learntIpToPortOpt.get().getMacAddress();
1652 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1656 public static boolean isIPv6Subnet(String prefix) {
1657 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1660 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(Uint64 dpnId) {
1661 return InstanceIdentifier.builder(DpnRouters.class)
1662 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1665 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, Uint64 dpnId) {
1666 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1667 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1668 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1671 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1672 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1673 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1677 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1678 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1679 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1680 LogicalDatastoreType.CONFIGURATION, id).map(
1681 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1685 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1686 Uuid floatingIpId) {
1688 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().map(
1689 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1690 } catch (InterruptedException | ExecutionException e) {
1691 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1697 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1698 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1699 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1700 LogicalDatastoreType.CONFIGURATION, id).map(
1701 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1705 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1706 Uuid floatingIpId) {
1708 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().map(
1709 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1710 } catch (InterruptedException | ExecutionException e) {
1711 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1716 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1717 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1718 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1722 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1723 InstanceIdentifier<Interface> ifStateId =
1724 buildStateInterfaceId(interfaceName);
1725 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1726 LogicalDatastoreType.OPERATIONAL, ifStateId).orElse(null);
1729 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1730 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1731 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1732 .interfaces.rev140508.InterfacesState.class)
1733 .child(Interface.class,
1734 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1735 .interfaces.state.InterfaceKey(interfaceName));
1736 return idBuilder.build();
1740 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1741 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1742 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1743 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orElse(null);
1747 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1749 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orElse(null);
1750 } catch (InterruptedException | ExecutionException e) {
1751 LOG.error("Error reading router {}", routerName, e);
1756 static void createRouterIdsConfigDS(DataBroker dataBroker, Uint32 routerId, String routerName) {
1757 if (routerId == NatConstants.INVALID_ID) {
1758 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1761 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1762 .setRouterId(routerId).setRouterName(routerName).build();
1763 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1767 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(Uint64 dpId, Uint32 vpnId, String subnetId,
1768 IdManagerService idManager) {
1769 InetAddress defaultIP = null;
1771 defaultIP = InetAddress.getByName("0.0.0.0");
1772 } catch (UnknownHostException e) {
1773 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1774 + "Default Route to NAT.", e);
1778 List<MatchInfo> matches = new ArrayList<>();
1779 matches.add(MatchEthernetType.IPV4);
1780 //add match for vrfid
1781 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId.longValue()),
1782 MetaDataUtil.METADATA_MASK_VRFID));
1784 List<InstructionInfo> instructions = new ArrayList<>();
1785 List<ActionInfo> actionsInfo = new ArrayList<>();
1786 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(subnetId));
1787 if (groupId == NatConstants.INVALID_ID) {
1788 LOG.error("Unable to get groupId for subnet {} while building defauly flow entity", subnetId);
1791 actionsInfo.add(new ActionGroup(groupId.longValue()));
1792 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1793 instructions.add(new InstructionApplyActions(actionsInfo));
1794 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1795 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1796 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1800 static String getExtGwMacAddFromRouterId(DataBroker broker, Uint32 routerId) {
1801 String routerName = getRouterName(broker, routerId);
1802 if (routerName == null) {
1803 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1806 return getExtGwMacAddFromRouterName(broker, routerName);
1810 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1811 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1812 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1813 LogicalDatastoreType.CONFIGURATION, id).map(Routers::getExtGwMacAddress).orElse(null);
1817 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1819 return tx.read(buildRouterIdentifier(routerName)).get().map(
1820 Routers::getExtGwMacAddress).orElse(null);
1821 } catch (InterruptedException | ExecutionException e) {
1822 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1827 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1828 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1829 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1830 .child(Router.class, new RouterKey(routerUuid));
1831 return routerInstanceIdentifier;
1835 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1836 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1837 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1838 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).map(Router::getName).orElse(
1843 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1844 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1845 List<Ports> portsList = new ArrayList<Ports>(SingleTransactionDataBroker
1846 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker, LogicalDatastoreType.CONFIGURATION,
1847 routerPortsIdentifier).map(RouterPorts::nonnullPorts).orElse(Collections.emptyMap()).values());
1849 if (!portsList.isEmpty()) {
1850 portsList = new ArrayList<>(portsList);
1856 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1857 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1858 Optional<ExternalNetworks> externalNwData =
1859 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1860 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1861 if (externalNwData.isPresent()) {
1862 for (Networks externalNw : externalNwData.get().nonnullNetworks().values()) {
1863 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1864 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1865 return routerIds != null ? new ArrayList<>(routerIds) : emptyList();
1872 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1875 long ipLo = ipToLong(InetAddress.getByName(start));
1876 long ipHi = ipToLong(InetAddress.getByName(end));
1877 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1878 return ipToTest >= ipLo && ipToTest <= ipHi;
1879 } catch (UnknownHostException e) {
1880 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1886 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1887 if (externalIps == null) {
1888 return Collections.emptySet();
1891 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1895 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1896 if (routerName == null) {
1897 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1898 return Collections.emptySet();
1901 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1902 Optional<Routers> routerData =
1903 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1904 LogicalDatastoreType.CONFIGURATION, id);
1905 if (routerData.isPresent()) {
1906 return NatUtil.getExternalSubnetIdsFromExternalIps(
1907 new ArrayList<ExternalIps>(routerData.get().nonnullExternalIps().values()));
1909 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1910 return Collections.emptySet();
1915 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1916 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1917 if (subnetId == null) {
1918 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1919 return Optional.empty();
1922 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1923 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1924 InstanceIdentifier.builder(ExternalSubnets.class)
1925 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1926 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1927 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1928 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1932 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1933 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1934 if (subnetId == null) {
1935 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1936 return Optional.empty();
1939 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1940 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1941 InstanceIdentifier.builder(ExternalSubnets.class)
1942 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1943 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1945 return tx.read(subnetsIdentifier).get();
1946 } catch (InterruptedException | ExecutionException e) {
1947 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1948 return Optional.empty();
1952 protected static Uint32 getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1953 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1954 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1956 if (optionalExternalSubnets.isPresent()) {
1957 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1960 return NatConstants.INVALID_ID;
1963 protected static Uint32 getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1964 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1965 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1967 if (optionalExternalSubnets.isPresent()) {
1968 return NatUtil.getVpnId(tx, subnetId.getValue());
1971 return NatConstants.INVALID_ID;
1974 protected static Uint32 getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1976 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1977 if (externalSubnetId != null) {
1978 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1981 return NatConstants.INVALID_ID;
1985 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1986 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1987 for (ExternalIps extIp : router.nonnullExternalIps().values()) {
1988 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1989 if (extIpString.equals(externalIpAddress)) {
1990 return extIp.getSubnetId();
1993 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1997 private static long ipToLong(InetAddress ip) {
1998 byte[] octets = ip.getAddress();
2000 for (byte octet : octets) {
2002 result |= octet & 0xff;
2008 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
2009 if (externalIps == null) {
2013 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
2016 // elan-instances config container
2018 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
2019 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
2020 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2021 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orElse(null);
2025 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
2027 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orElse(null);
2028 } catch (InterruptedException | ExecutionException e) {
2029 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
2034 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
2035 return InstanceIdentifier.builder(ElanInstances.class)
2036 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
2039 public static Uint64 getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
2040 IElanService elanManager, IdManagerService idManager,
2041 Uint32 routerId, String routerName) {
2042 if (elanManager.isOpenStackVniSemanticsEnforced()) {
2043 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
2044 return natOverVxlanUtil.getRouterVni(routerName, routerId);
2046 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
2050 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, Uint64 naptDpnId,
2051 short tableId, TypedWriteTransaction<Configuration> confTx) {
2052 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2053 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
2055 Map<InstructionKey, Instruction> preDnatToSnatInstructionsMap = new HashMap<InstructionKey, Instruction>();
2056 preDnatToSnatInstructionsMap.put(new InstructionKey(0),
2057 new InstructionGotoTable(tableId).buildInstruction(0));
2058 List<MatchInfo> matches = new ArrayList<>();
2059 matches.add(MatchEthernetType.IPV4);
2060 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2061 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
2062 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
2063 matches, preDnatToSnatInstructionsMap);
2065 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
2066 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
2067 preDnatToSnatTableFlowEntity, naptDpnId);
2070 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
2071 IMdsalApiManager mdsalManager, Uint64 naptDpnId) throws ExecutionException, InterruptedException {
2072 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2073 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
2074 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2075 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
2076 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
2077 flowRef, naptDpnId);
2080 private static String getFlowRefPreDnatToSnat(Uint64 dpnId, short tableId, String uniqueId) {
2081 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
2082 + NwConstants.FLOWID_SEPARATOR + uniqueId;
2085 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, Uint64 dpnId, String rd,
2086 String vpnName, String externalIp,
2087 Boolean isMoreThanOneFipCheckOnDpn) {
2088 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
2089 Optional<VpnToDpnList> dpnInVpn;
2091 dpnInVpn = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2092 LogicalDatastoreType.OPERATIONAL, id);
2093 } catch (ExecutionException | InterruptedException e) {
2094 LOG.error("isFloatingIpPresentForDpn: Exception while reading VpnToDpnList DS for the rd {} dpnId {}",
2098 if (dpnInVpn.isPresent()) {
2099 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2100 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2102 Map<IpAddressesKey, IpAddresses> keyIpAddressesMap = dpnInVpn.get().getIpAddresses();
2103 if (keyIpAddressesMap != null && !keyIpAddressesMap.isEmpty()) {
2104 int floatingIpPresentCount = 0;
2105 for (IpAddresses ipAddress: keyIpAddressesMap.values()) {
2106 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2107 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2108 floatingIpPresentCount++;
2109 //Add tunnel table check
2110 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2113 //Remove tunnel table check
2114 if (!isMoreThanOneFipCheckOnDpn) {
2120 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2124 } catch (NullPointerException e) {
2125 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2126 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2133 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, Uint64 dpnId) {
2134 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2135 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2136 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2140 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2141 throws ExecutionException, InterruptedException {
2142 return tx.read(getVpnInstanceIdentifier(vpnName)).get().map(NatUtil::getPrimaryRd).orElse(null);
2146 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2147 if (vpnInstance == null) {
2150 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2151 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2154 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2155 return InstanceIdentifier.builder(VpnInstances.class)
2156 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2160 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2161 return vpnInstance.getRouteDistinguisher() != null ? new ArrayList<>(
2162 vpnInstance.getRouteDistinguisher()) : new ArrayList<>();
2165 public static String validateAndAddNetworkMask(String ipAddress) {
2166 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2169 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2170 String vpnInterfaceName, String vpnName) {
2171 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2172 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2175 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2176 String routerName, Uint64 dpnId) {
2177 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2178 Optional<Networks> networkData = null;
2180 networkData = SingleTransactionDataBroker.syncReadOptional(broker,
2181 LogicalDatastoreType.CONFIGURATION, id);
2182 } catch (ExecutionException | InterruptedException e) {
2183 LOG.error("checkForRoutersWithSameExtNetAndNaptSwitch: Exception while reading Networks DS for the "
2184 + "network {} router {} dpnId {}", networkId.getValue(), routerName, dpnId, e);
2187 if (networkData != null && networkData.isPresent()) {
2188 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2189 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2190 for (Uuid routerUuid : routerUuidList) {
2191 String sharedRouterName = routerUuid.getValue();
2192 if (!routerName.equals(sharedRouterName)) {
2193 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2194 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2195 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2196 + "associated with other active router {} on NAPT switch {}", networkId,
2197 sharedRouterName, switchDpnId);
2207 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2208 String routerName, Uint64 dpnId) {
2209 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId)
2210 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2211 .subnets.Subnets::getRouterIds).orElse(emptyList());
2212 if (!routerUuidList.isEmpty()) {
2213 for (Uuid routerUuid : routerUuidList) {
2214 String sharedRouterName = routerUuid.getValue();
2215 if (!routerName.equals(sharedRouterName)) {
2216 Uint64 switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2217 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2218 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2219 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2220 sharedRouterName, switchDpnId);
2229 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2230 Routers router, Uint64 primarySwitchId, int addOrRemove) {
2231 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2232 Map<ExternalIpsKey, ExternalIps> keyExternalIpsMap = router.getExternalIps();
2233 List<String> externalIpsSting = new ArrayList<>();
2235 if (keyExternalIpsMap == null || keyExternalIpsMap.isEmpty()) {
2236 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2239 for (ExternalIps externalIp : keyExternalIpsMap.values()) {
2240 externalIpsSting.add(externalIp.getIpAddress());
2242 Uuid subnetVpnName = keyExternalIpsMap.get(0).getSubnetId();
2243 if (addOrRemove == NwConstants.ADD_FLOW) {
2244 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2245 router.getNetworkId(), subnetVpnName.getValue(), tx);
2246 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2247 router.getExtGwMacAddress(), primarySwitchId,
2248 router.getNetworkId());
2250 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2251 router.getNetworkId(), subnetVpnName.getValue(), tx);
2252 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2253 router.getExtGwMacAddress(), primarySwitchId,
2254 router.getNetworkId());
2256 }), LOG, "Error installing router gateway flows");
2259 @SuppressWarnings("checkstyle:IllegalCatch")
2260 public static void handleSNATForDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2261 IdManagerService idManager, NaptSwitchHA naptSwitchHA,
2262 Uint64 dpnId, Routers extRouters, Uint32 routerId, Uint32 routerVpnId,
2263 TypedReadWriteTransaction<Configuration> confTx,
2264 ProviderTypes extNwProvType, UpgradeState upgradeState) {
2265 //Check if primary and secondary switch are selected, If not select the role
2266 //Install select group to NAPT switch
2267 //Install default miss entry to NAPT switch
2269 String routerName = extRouters.getRouterName();
2270 Boolean upgradeInProgress = false;
2271 if (upgradeState != null) {
2272 upgradeInProgress = upgradeState.isUpgradeInProgress();
2274 Uint64 naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2275 if (naptId == null || naptId.equals(Uint64.ZERO)
2276 || (!NatUtil.getSwitchStatus(dataBroker, naptId) && (upgradeInProgress == false))) {
2277 LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}",
2278 routerName, naptId);
2280 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
2282 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
2283 naptSwitch, routerName);
2286 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
2288 String externalVpnName = null;
2289 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
2290 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
2291 Uuid extNwUuid = extRouters.getNetworkId();
2292 externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNwUuid);
2293 if (externalVpnName != null) {
2294 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, extNwUuid,
2295 externalVpnName, confTx);
2297 // Install miss entry (table 26) pointing to table 46
2298 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
2299 routerVpnId, NatConstants.ADD_FLOW);
2300 if (flowEntity == null) {
2301 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
2305 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
2306 mdsalManager.addFlow(confTx, flowEntity);
2307 //Removing primary flows from old napt switch
2308 if (naptId != null && !naptId.equals(Uint64.ZERO)) {
2309 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
2310 naptId, routerName);
2312 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouters, routerId, naptId, null,
2313 externalVpnName, confTx);
2314 } catch (Exception e) {
2315 LOG.error("Exception while removing SnatFlows form OldNaptSwitch {}", naptId, e);
2318 naptSwitchHA.updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
2319 } else if (naptId.equals(dpnId)) {
2320 LOG.error("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
2322 naptSwitch = naptId;
2323 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
2324 naptId, routerName);
2327 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
2328 routerName, routerId, naptSwitch);
2329 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
2331 // Install miss entry (table 26) pointing to group
2332 Uint32 groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
2333 NatUtil.getGroupIdKey(routerName));
2334 if (groupId != NatConstants.INVALID_ID) {
2335 FlowEntity flowEntity =
2336 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId.longValue(),
2337 routerVpnId, NatConstants.ADD_FLOW);
2338 if (flowEntity == null) {
2339 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}"
2340 + " groupId {}", routerName, dpnId, groupId);
2343 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
2344 dpnId, routerName, groupId);
2345 mdsalManager.addFlow(confTx, flowEntity);
2347 LOG.error("handleSNATForDPN: Unable to get groupId for router:{}", routerName);
2352 @SuppressWarnings("checkstyle:IllegalCatch")
2353 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2354 IdManagerService idManager, NaptSwitchHA naptSwitchHA, Uint64 dpnId,
2355 Routers extRouter, Uint32 routerId, Uint32 routerVpnId, String externalVpnName,
2356 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2357 throws ExecutionException, InterruptedException {
2358 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2359 //remove miss entry to NAPT switch
2360 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2361 if (extNwProvType == null) {
2364 String routerName = extRouter.getRouterName();
2365 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2366 Map<String, Uint32> externalIpLabel;
2367 if (extNwProvType == ProviderTypes.VXLAN) {
2368 externalIpLabel = null;
2370 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2372 Uint64 naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2373 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2374 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2377 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2378 boolean naptStatus =
2379 naptSwitchHA.isNaptSwitchDown(extRouter, routerId, dpnId, naptSwitch, routerVpnId,
2380 externalIpCache, confTx);
2382 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2384 Uint32 groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
2385 FlowEntity flowEntity = null;
2387 if (groupId != NatConstants.INVALID_ID) {
2388 flowEntity = naptSwitchHA
2389 .buildSnatFlowEntity(dpnId, routerName, groupId.longValue(), routerVpnId,
2390 NatConstants.DEL_FLOW);
2391 if (flowEntity == null) {
2392 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2393 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2396 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}",
2398 mdsalManager.removeFlow(confTx, flowEntity);
2400 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2403 } catch (Exception ex) {
2404 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2408 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2412 GroupEntity groupEntity = null;
2414 if (groupId != NatConstants.INVALID_ID) {
2415 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId.longValue(), routerName,
2416 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2417 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2418 mdsalManager.removeGroup(groupEntity);
2420 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2422 } catch (Exception ex) {
2423 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2426 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2429 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(extRouter, routerId, naptSwitch,
2430 externalIpLabel, externalVpnName, confTx);
2431 //remove table 26 flow ppointing to table46
2432 FlowEntity flowEntity = null;
2434 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2435 NatConstants.DEL_FLOW);
2436 if (flowEntity == null) {
2437 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2441 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2442 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2443 mdsalManager.removeFlow(confTx, flowEntity);
2445 } catch (Exception ex) {
2446 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2450 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2453 //best effort to check IntExt model
2454 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2458 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2459 ProviderTypes extNwProvType) {
2460 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2461 || extNwProvType == ProviderTypes.VXLAN)) {
2467 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2468 Uint64 dpnId, DataBroker dataBroker) {
2469 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2470 elanInstanceName, dpnId);
2471 // FIXME: separate this out?
2472 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2475 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2476 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2477 List<String> elanInterfaceList = new ArrayList<>();
2478 DpnInterfaces dpnInterface;
2479 if (dpnInElanInterfaces.isPresent()) {
2480 dpnInterface = dpnInElanInterfaces.get();
2482 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2483 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2485 if (!elanInterfaceList.contains(pseudoPortId)) {
2486 elanInterfaceList.add(pseudoPortId);
2487 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2488 .withKey(new DpnInterfacesKey(dpnId)).build();
2489 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2490 elanDpnInterfaceId, dpnInterface);
2492 } catch (InterruptedException | ExecutionException e) {
2493 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2494 } catch (TransactionCommitFailedException e) {
2495 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2501 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2502 Uint64 dpnId, DataBroker dataBroker) {
2503 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2504 elanInstanceName, dpnId);
2505 // FIXME: separate this out?
2506 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2509 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2510 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2511 List<String> elanInterfaceList = new ArrayList<>();
2512 DpnInterfaces dpnInterface;
2513 if (!dpnInElanInterfaces.isPresent()) {
2514 LOG.info("No interface in any dpn for {}", elanInstanceName);
2518 dpnInterface = dpnInElanInterfaces.get();
2519 elanInterfaceList = (dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty())
2520 ? new ArrayList<>(dpnInterface.getInterfaces()) : elanInterfaceList;
2521 if (!elanInterfaceList.contains(pseudoPortId)) {
2522 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2525 elanInterfaceList.remove(pseudoPortId);
2526 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2527 .withKey(new DpnInterfacesKey(dpnId)).build();
2528 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2529 elanDpnInterfaceId, dpnInterface);
2530 } catch (InterruptedException | ExecutionException e) {
2531 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2532 } catch (TransactionCommitFailedException e) {
2533 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2539 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2540 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2541 for (Map.Entry<String,Routers> router : extRouter) {
2542 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2543 .equals(networkid)) {
2551 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2553 return SingleTransactionDataBroker.syncRead(dataBroker,
2554 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2556 catch (ExpectedDataObjectNotFoundException e) {
2557 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2562 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2563 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2564 .builder(LearntVpnVipToPortData.class).build();
2565 return learntVpnVipToPortDataId;
2568 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2570 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2571 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2572 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2575 public static InstanceIdentifier<Group> getGroupInstanceId(Uint64 dpnId, Uint32 groupId) {
2576 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2577 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2578 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2581 public static void createGroupIdPool(IdManagerService idManager) {
2582 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2583 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2584 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2585 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2588 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2589 if (result != null && result.get().isSuccessful()) {
2590 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2592 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2594 } catch (InterruptedException | ExecutionException e) {
2595 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2599 public static boolean getSwitchStatus(DataBroker broker, Uint64 switchId) {
2600 NodeId nodeId = new NodeId("openflow:" + switchId);
2601 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2602 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2603 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2604 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2605 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2606 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2607 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2608 if (nodeOptional.isPresent()) {
2609 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2612 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2616 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2617 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2618 Optional<Networks> networkData =
2619 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2620 broker, LogicalDatastoreType.CONFIGURATION, id);
2621 return networkData.isPresent();
2625 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2626 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2627 if (null != elanInstance) {
2628 return elanInstance.getPhysicalNetworkName();
2634 public static Map<String, String> getOpenvswitchOtherConfigMap(Uint64 dpnId, DataBroker dataBroker) {
2635 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2636 return getMultiValueMap(otherConfigVal);
2639 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2640 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2641 return Collections.emptyMap();
2644 Map<String, String> valueMap = new HashMap<>();
2645 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2646 for (String keyValue : splitter.split(multiKeyValueStr)) {
2647 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2648 if (split.length == 2) {
2649 valueMap.put(split[0], split[1]);
2656 public static Optional<Node> getBridgeRefInfo(Uint64 dpnId, DataBroker dataBroker) {
2657 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2658 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2660 Optional<BridgeRefEntry> bridgeRefEntry =
2661 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2662 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2663 if (!bridgeRefEntry.isPresent()) {
2664 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2665 return Optional.empty();
2668 InstanceIdentifier<Node> nodeId =
2669 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2671 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2672 LogicalDatastoreType.OPERATIONAL, nodeId);
2676 public static String getProviderMappings(Uint64 dpId, DataBroker dataBroker) {
2677 return getBridgeRefInfo(dpId, dataBroker).map(node -> getOpenvswitchOtherConfigs(node,
2678 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2682 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2683 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2684 if (ovsdbNode == null) {
2685 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2686 if (nodeFromReadOvsdbNode.isPresent()) {
2687 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2691 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2692 for (OpenvswitchOtherConfigs openvswitchOtherConfigs
2693 : ovsdbNode.nonnullOpenvswitchOtherConfigs().values()) {
2694 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2695 return openvswitchOtherConfigs.getOtherConfigValue();
2699 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2704 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2705 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2706 if (bridgeAugmentation != null) {
2707 InstanceIdentifier<Node> ovsdbNodeIid =
2708 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2709 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2710 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2712 return Optional.empty();
2717 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2721 return node.augmentation(OvsdbBridgeAugmentation.class);
2724 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, Uint64 dpnId) {
2725 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2728 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2729 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2730 InstanceIdentifier.builder(ExternalSubnets.class)
2733 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2734 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2735 if (optionalExternalSubnets.isPresent()) {
2736 return optionalExternalSubnets.get();
2738 } catch (InterruptedException | ExecutionException e) {
2739 LOG.error("Failed to read the subnets from the datastore.");
2745 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2746 Uint64 dpId, short tableId, String flowId, int priority, String flowName, Uint64 cookie,
2747 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2748 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2749 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2751 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2752 mdsalManager.addFlow(confTx, flowEntity);
2755 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2756 Uint64 dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2757 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2758 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2761 public static String getIpv6FlowRef(Uint64 dpnId, short tableId, Uint32 routerID) {
2762 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2763 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2766 public static String getTunnelInterfaceName(Uint64 srcDpId, Uint64 dstDpId,
2767 ItmRpcService itmManager) {
2768 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2769 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2771 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2772 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2773 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2774 rpcResult = result.get();
2775 if (!rpcResult.isSuccessful()) {
2776 tunType = TunnelTypeGre.class ;
2777 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2778 .setSourceDpid(srcDpId)
2779 .setDestinationDpid(dstDpId)
2780 .setTunnelType(tunType)
2782 rpcResult = result.get();
2783 if (!rpcResult.isSuccessful()) {
2784 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2785 rpcResult.getErrors());
2787 return rpcResult.getResult().getInterfaceName();
2789 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2790 rpcResult.getErrors());
2792 return rpcResult.getResult().getInterfaceName();
2794 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2795 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2796 + "between {} and {}", srcDpId, dstDpId);
2801 public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) {
2802 Port neutronPort = getNeutronPort(broker, ifaceName);
2803 if (neutronPort == null) {
2804 return Boolean.TRUE;
2806 return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE
2811 private static Port getNeutronPort(DataBroker broker, String ifaceName) {
2812 InstanceIdentifier<Port>
2813 portsIdentifier = InstanceIdentifier.create(Neutron.class)
2815 org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class)
2816 .child(Port.class, new PortKey(new Uuid(ifaceName)));
2817 Optional<Port> portsOptional;
2819 portsOptional = SingleTransactionDataBroker
2820 .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
2821 } catch (InterruptedException | ExecutionException e) {
2822 LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e);
2823 portsOptional = Optional.empty();
2825 if (!portsOptional.isPresent()) {
2826 LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName);
2829 return portsOptional.get();
2832 public static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
2833 .instance.to.vpn.id.VpnInstance getVpnIdToVpnInstance(DataBroker broker, String vpnName) {
2834 if (vpnName == null) {
2838 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2839 .vpn.instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
2840 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
2841 .vpn.instance.to.vpn.id.VpnInstance> vpnInstance = Optional.empty();
2843 vpnInstance = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, id);
2844 } catch (InterruptedException | ExecutionException e) {
2845 LOG.error("Failed to read VpnInstance {}", vpnInstance, e);
2847 if (vpnInstance.isPresent()) {
2848 return vpnInstance.get();
2854 public static Uint32 getExternalVpnIdForExtNetwork(DataBroker broker, Uuid externalNwUuid) {
2855 //Get the VPN ID from the ExternalNetworks model
2856 if (externalNwUuid == null) {
2857 LOG.error("getExternalVpnIdForExtNetwork : externalNwUuid is null");
2860 Uuid vpnUuid = getVpnIdfromNetworkId(broker, externalNwUuid);
2861 if (vpnUuid == null) {
2862 LOG.error("NAT Service : vpnUuid is null");
2865 Uint32 vpnId = getVpnId(broker, vpnUuid.getValue());
2869 static ReentrantLock lockForNat(final Uint64 dataPath) {
2870 // FIXME: wrap this in an Identifier
2871 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
2874 public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
2875 IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
2876 String interfaceName, String routerName) {
2877 Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
2878 if (routerId == NatConstants.INVALID_ID) {
2879 LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
2882 Uint64 naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
2883 if (naptSwitch == null || naptSwitch.equals(Uint64.ZERO)) {
2884 LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
2885 + "with Id {}", routerName, routerId);
2888 //getInternalIp for port
2889 List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
2890 if (fixedIps == null) {
2891 LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
2892 interfaceName, routerName, routerId);
2895 List<ProtocolTypes> protocolTypesList = getPortocolList();
2896 for (String internalIp : fixedIps) {
2897 LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
2898 interfaceName, internalIp, routerId);
2899 for (ProtocolTypes protocol : protocolTypesList) {
2900 List<Uint16> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
2901 if (portList != null) {
2902 for (Uint16 portnum : portList) {
2903 //build and remove the flow in outbound table
2904 removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
2905 routerId, internalIp, portnum.toJava(), protocol.getName());
2907 //build and remove the flow in inboundtable
2909 removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
2910 internalIp, portnum.toJava(), protocol.getName());
2912 //Get the external IP address and the port from the model
2914 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
2915 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
2916 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
2917 internalIp, String.valueOf(portnum.toJava()), proto);
2918 if (ipPortExternal == null) {
2919 LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
2920 + "with port {} is not found in "
2921 + "router with Id {}", internalIp, portnum, routerId);
2924 String externalIpAddress = ipPortExternal.getIpAddress();
2925 String internalIpPort = internalIp + ":" + portnum.toJava();
2926 // delete the entry from IntExtIpPortMap DS
2928 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
2929 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
2933 LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
2934 + "in router with id {}",
2935 protocol, interfaceName, internalIp, routerId);
2938 // delete the entry from SnatIntIpPortMap DS
2939 LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
2940 internalIp, routerId);
2941 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
2945 private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
2946 LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
2948 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
2949 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
2950 .setPortId(new Uuid(interfname)).build());
2952 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
2953 if (!rpcResult.isSuccessful()) {
2954 LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
2955 rpcResult.getErrors());
2957 return rpcResult.getResult().getFixedIPs();
2959 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
2960 LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
2965 private static List<ProtocolTypes> getPortocolList() {
2966 List<ProtocolTypes> protocollist = new ArrayList<>();
2967 protocollist.add(ProtocolTypes.TCP);
2968 protocollist.add(ProtocolTypes.UDP);
2969 return protocollist;
2972 private static void removeNatFlow(IMdsalApiManager mdsalManager, Uint64 dpnId, short tableId, Uint32 routerId,
2973 String ipAddress, int ipPort, String protocol) {
2975 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
2977 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
2979 mdsalManager.removeFlow(snatFlowEntity);
2980 LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
2981 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
2984 public static String getDpnFromNodeRef(NodeRef node) {
2985 PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
2986 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
2987 InstanceIdentifier.IdentifiableItem.class);
2988 NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
2989 String dpnKey = key.getId().getValue();
2990 String dpnID = null;
2991 if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
2992 dpnID = Uint64.valueOf(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();