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
9 package org.opendaylight.netvirt.natservice.internal;
11 import static java.util.Collections.emptyList;
12 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
13 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
15 import com.google.common.base.Optional;
16 import com.google.common.base.Preconditions;
17 import com.google.common.base.Splitter;
18 import com.google.common.base.Strings;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import java.math.BigInteger;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Objects;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.locks.ReentrantLock;
35 import java.util.stream.Collectors;
36 import org.apache.commons.net.util.SubnetUtils;
37 import org.eclipse.jdt.annotation.NonNull;
38 import org.eclipse.jdt.annotation.Nullable;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
42 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
43 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
44 import org.opendaylight.genius.infra.Datastore.Configuration;
45 import org.opendaylight.genius.infra.Datastore.Operational;
46 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
47 import org.opendaylight.genius.infra.TypedReadTransaction;
48 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
49 import org.opendaylight.genius.infra.TypedWriteTransaction;
50 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
51 import org.opendaylight.genius.mdsalutil.ActionInfo;
52 import org.opendaylight.genius.mdsalutil.FlowEntity;
53 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
54 import org.opendaylight.genius.mdsalutil.GroupEntity;
55 import org.opendaylight.genius.mdsalutil.InstructionInfo;
56 import org.opendaylight.genius.mdsalutil.MDSALUtil;
57 import org.opendaylight.genius.mdsalutil.MatchInfo;
58 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
59 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
60 import org.opendaylight.genius.mdsalutil.NwConstants;
61 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
62 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
63 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
64 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
65 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
66 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
67 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
68 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
69 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
70 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
71 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
72 import org.opendaylight.genius.utils.JvmGlobalLocks;
73 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
74 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
75 import org.opendaylight.netvirt.elanmanager.api.IElanService;
76 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
77 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
78 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
79 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
80 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
81 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
82 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
83 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
84 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
87 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
88 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
256 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;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
261 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
262 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
263 import org.opendaylight.yangtools.yang.common.RpcResult;
264 import org.slf4j.Logger;
265 import org.slf4j.LoggerFactory;
267 public final class NatUtil {
269 private static String OF_URI_SEPARATOR = ":";
270 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
271 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
272 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
273 private static final String PROVIDER_MAPPINGS = "provider_mappings";
275 private NatUtil() { }
278 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
281 public static BigInteger getCookieSnatFlow(long routerId) {
282 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
283 BigInteger.valueOf(routerId));
287 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
290 public static BigInteger getCookieNaptFlow(long routerId) {
291 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
292 BigInteger.valueOf(routerId));
296 getVpnId() returns the VPN ID from the VPN name
298 public static long getVpnId(DataBroker broker, @Nullable String vpnName) {
299 if (vpnName == null) {
300 return NatConstants.INVALID_ID;
303 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
304 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
305 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
306 .instance.to.vpn.id.VpnInstance> vpnInstance =
307 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
308 LogicalDatastoreType.CONFIGURATION, id);
310 long vpnId = NatConstants.INVALID_ID;
311 if (vpnInstance.isPresent()) {
312 Long vpnIdAsLong = vpnInstance.get().getVpnId();
313 if (vpnIdAsLong != null) {
320 public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
321 if (vpnName == null) {
322 return NatConstants.INVALID_ID;
326 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
327 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
328 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
329 } catch (InterruptedException | ExecutionException e) {
330 LOG.error("Error retrieving VPN id for {}", vpnName, e);
333 return NatConstants.INVALID_ID;
336 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
337 //Get the external network ID from the ExternalRouter model
338 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
339 if (networkId == null) {
340 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
341 return NatConstants.INVALID_ID;
344 //Get the VPN ID from the ExternalNetworks model
345 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
346 if (vpnUuid == null) {
347 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
348 return NatConstants.INVALID_ID;
350 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
354 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
355 return InstanceIdentifier.builder(FloatingIpInfo.class)
356 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
359 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
360 return InstanceIdentifier.builder(RouterToVpnMapping.class)
361 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
364 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
365 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
366 .child(Ports.class, new PortsKey(portName)).build();
369 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
371 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
372 .child(Ports.class, new PortsKey(portName))
373 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
376 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
377 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
378 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
379 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
380 .instance.to.vpn.id.VpnInstance.class,
381 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
382 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
386 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
387 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
388 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
389 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
390 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
394 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
396 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
397 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
398 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
401 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
402 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
403 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
406 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
407 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
408 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
413 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
414 String routerName = getRouterName(broker, routerId);
415 if (routerName == null) {
416 LOG.error("getNetworkIdFromRouterId - empty routerName received");
419 return getNetworkIdFromRouterName(broker, routerName);
423 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
424 if (routerName == null) {
425 LOG.error("getNetworkIdFromRouterName - empty routerName received");
428 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
429 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
430 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
433 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
434 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
435 .child(Routers.class, new RoutersKey(routerId)).build();
436 return routerInstanceIndentifier;
439 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
440 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
441 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
446 * Return if SNAT is enabled for the given router.
448 * @param broker The DataBroker
449 * @param routerId The router
450 * @return boolean true if enabled, otherwise false
452 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
453 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
454 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
455 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
459 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
460 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
461 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
462 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
466 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
468 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
469 } catch (InterruptedException | ExecutionException e) {
470 LOG.error("Error reading network VPN id for {}", networkId, e);
476 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
477 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
478 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
479 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
483 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
484 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
486 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
487 } catch (InterruptedException | ExecutionException e) {
488 LOG.error("Error retrieving provider type for {}", networkId, e);
494 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
495 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
496 Optional<Routers> routerData =
497 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
498 LogicalDatastoreType.CONFIGURATION, id);
499 if (routerData.isPresent()) {
500 Uuid networkId = routerData.get().getNetworkId();
501 if (networkId != null) {
502 return networkId.getValue();
505 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
509 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
510 return InstanceIdentifier.builder(ExternalNetworks.class)
511 .child(Networks.class, new NetworksKey(networkId)).build();
515 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
516 // convert routerId to Name
517 String routerName = getRouterName(broker, routerId);
518 if (routerName == null) {
519 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
522 return getPrimaryNaptfromRouterName(broker, routerName);
526 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
527 if (routerName == null) {
528 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
531 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
532 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
533 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
537 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
538 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
539 new RouterToNaptSwitchKey(routerId)).build();
542 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
543 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
544 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
548 public static String getRouterName(DataBroker broker, Long routerId) {
549 return getVpnInstanceFromVpnIdentifier(broker, routerId);
552 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
553 return InstanceIdentifier.builder(VpnInstanceOpData.class)
554 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
557 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
558 return new FlowEntityBuilder()
566 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
567 return new FlowEntityBuilder()
575 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
576 String nextHopIp = null;
577 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
578 InstanceIdentifier.builder(DpnEndpoints.class)
579 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
580 Optional<DPNTEPsInfo> tunnelInfo =
581 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
582 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
583 if (tunnelInfo.isPresent()) {
584 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
585 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
586 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
593 public static String getVpnRd(DataBroker broker, String vpnName) {
594 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
595 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
596 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
597 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
598 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
599 .VpnInstance::getVrfId).orElse(null);
603 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
605 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
606 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
607 .VpnInstance::getVrfId).orElse(null);
608 } catch (InterruptedException | ExecutionException e) {
609 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
615 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
616 String internalPort, NAPTEntryEvent.Protocol protocol) {
617 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
618 InstanceIdentifier<IpPortMap> ipPortMapId =
619 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
620 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
621 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
625 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
627 ProtocolTypes protocolType) {
628 return InstanceIdentifier.builder(IntextIpPortMap.class)
629 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
630 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
631 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
634 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
635 return InstanceIdentifier.builder(VpnInterfaces.class)
636 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
640 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
642 * NodeConnectorId is of form 'openflow:dpnid:portnum'
644 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
645 if (split.length != 3) {
646 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
652 public static BigInteger getDpIdFromInterface(
653 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
654 .state.Interface ifState) {
655 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
656 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
657 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
662 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
663 // returns only router, attached to IPv4 networks
664 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
665 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
666 Optional<VpnMap> optionalVpnMap =
667 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
668 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
669 if (!optionalVpnMap.isPresent()) {
670 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
673 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
674 if (routerIdsList != null && !routerIdsList.isEmpty()) {
675 for (Uuid routerUuid : routerIdsList) {
676 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
677 Optional<Routers> routerData =
678 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
679 LogicalDatastoreType.CONFIGURATION, id);
680 if (routerData.isPresent()) {
681 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
682 for (Uuid subnetUuid : subnetIdsList) {
683 String subnetIp = getSubnetIp(broker, subnetUuid);
684 SubnetUtils subnet = new SubnetUtils(subnetIp);
685 if (subnet.getInfo().isInRange(ipAddress)) {
686 return routerUuid.getValue();
692 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
697 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
698 Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
699 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
700 Optional<VpnMaps> optionalVpnMaps =
701 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
702 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
703 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
704 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap()) {
705 if (routerId.equals(vpnMap.getVpnId().getValue())) {
708 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
709 if (routerIdsList.isEmpty()) {
712 // Skip router vpnId fetching from internet BGP-VPN
713 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
714 // We only need to check the first network; if it’s not an external network there’s no
715 // need to check the rest of the VPN’s network list
716 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
720 if (routerIdsList.contains(new Uuid(routerId))) {
721 return vpnMap.getVpnId();
725 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
729 static long getAssociatedVpn(DataBroker broker, String routerName) {
730 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
731 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
732 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
733 NatConstants.INVALID_ID);
737 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
738 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
739 if (vpnUuid == null) {
740 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
743 return vpnUuid.getValue();
747 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
748 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
749 if (vpnUuid == null) {
750 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
753 return vpnUuid.getValue();
756 // TODO Clean up the exception handling
757 @SuppressWarnings("checkstyle:IllegalCatch")
758 public static void addPrefixToBGP(DataBroker broker,
759 IBgpManager bgpManager,
760 IFibManager fibManager,
765 @Nullable String parentVpnRd,
766 @Nullable String macAddress,
772 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
773 prefix, nextHopIp, label);
774 if (nextHopIp == null) {
775 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
780 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
781 dpId, Prefixes.PrefixCue.Nat);
782 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
783 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
784 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
785 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
786 /* Publish to Bgp only if its an INTERNET VPN */
787 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
788 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
789 null /*gatewayMac*/);
791 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
792 prefix, nextHopIp, label);
793 } catch (Exception e) {
794 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
795 prefix, nextHopIp, label, e);
799 static void addPrefixToInterface(DataBroker broker, long vpnId, @Nullable String interfaceName, String ipPrefix,
800 String networkId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
801 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
802 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
803 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
804 .to._interface.VpnIdsKey(vpnId))
805 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
806 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
807 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
808 prefixBuilder.setNetworkId(new Uuid(networkId));
810 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
811 prefixBuilder.build());
812 } catch (TransactionCommitFailedException e) {
813 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
814 ipPrefix, vpnId, dpId, e);
818 public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
820 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
821 InstanceIdentifier.builder(PrefixToInterface.class)
822 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
823 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
824 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
826 } catch (TransactionCommitFailedException e) {
827 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
832 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
833 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
834 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
838 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
839 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
840 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
841 return routerInstanceIndentifier;
845 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
846 String internalIpAddress, ProtocolTypes protocolType) {
847 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
848 LogicalDatastoreType.CONFIGURATION,
849 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
850 IntIpProtoType::getPorts).orElse(emptyList());
853 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
854 String internalIpAddress,
855 ProtocolTypes protocolType) {
856 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
857 InstanceIdentifier.builder(SnatintIpPortMap.class)
858 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
859 .child(IpPort.class, new IpPortKey(internalIpAddress))
860 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
861 return intIpProtocolTypeId;
864 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
865 String internalIpAddress) {
866 InstanceIdentifier<IpPort> intIpProtocolTypeId =
867 InstanceIdentifier.builder(SnatintIpPortMap.class)
868 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
869 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
870 return intIpProtocolTypeId;
874 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
875 String internalIpAddress) {
876 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
877 LogicalDatastoreType.CONFIGURATION,
878 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
881 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
882 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
883 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
887 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
888 return InstanceIdentifier.create(NaptSwitches.class);
891 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
892 return InstanceIdentifier.create(NaptSwitches.class)
893 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
896 public static String getGroupIdKey(String routerName) {
897 return "snatmiss." + routerName;
900 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
901 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
902 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
905 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
906 RpcResult<AllocateIdOutput> rpcResult = result.get();
907 return rpcResult.getResult().getIdValue();
908 } catch (NullPointerException | InterruptedException | ExecutionException e) {
909 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
914 // TODO Clean up the exception handling
915 @SuppressWarnings("checkstyle:IllegalCatch")
916 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
917 String rd, String prefix, String vpnName, Logger log) {
919 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
920 fibManager.removeFibEntry(rd, prefix, null);
921 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
922 bgpManager.withdrawPrefix(rd, prefix);
924 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
925 } catch (Exception e) {
926 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
927 rd, prefix, vpnName, e);
932 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
933 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
934 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
937 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
938 return InstanceIdentifier.builder(IntextIpPortMap.class)
939 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
942 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
943 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
944 return InstanceIdentifier.builder(IntextIpMap.class)
945 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
946 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
947 .intext.ip.map.IpMappingKey(routerId))
952 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
953 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
954 .ip.map.IpMapping> ipMappingOptional =
955 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
956 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
957 // Ensure there are no duplicates
958 Collection<String> externalIps = new HashSet<>();
959 if (ipMappingOptional.isPresent()) {
960 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
961 externalIps.add(ipMap.getExternalIp());
968 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
969 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
970 if (routerData != null) {
971 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
978 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
979 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
980 .ip.map.IpMapping> ipMappingOptional =
981 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
982 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
983 Map<String, Long> externalIpsLabel = new HashMap<>();
984 if (ipMappingOptional.isPresent()) {
985 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
986 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
989 return externalIpsLabel;
993 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
994 String leastLoadedExternalIp = null;
995 InstanceIdentifier<ExternalCounters> id =
996 InstanceIdentifier.builder(ExternalIpsCounter.class)
997 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
998 Optional<ExternalCounters> externalCountersData =
999 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1000 if (externalCountersData.isPresent()) {
1001 ExternalCounters externalCounter = externalCountersData.get();
1002 short countOfLstLoadExtIp = 32767;
1003 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1004 String curExternalIp = externalIpCounter.getExternalIp();
1005 short countOfCurExtIp = externalIpCounter.getCounter();
1006 if (countOfCurExtIp < countOfLstLoadExtIp) {
1007 countOfLstLoadExtIp = countOfCurExtIp;
1008 leastLoadedExternalIp = curExternalIp;
1012 return leastLoadedExternalIp;
1015 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1017 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1018 String subnetIP = getSubnetIp(dataBroker, subnetId);
1019 if (subnetIP != null) {
1020 return getSubnetIpAndPrefix(subnetIP);
1022 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1027 public static String[] getSubnetIpAndPrefix(String subnetString) {
1028 String[] subnetSplit = subnetString.split("/");
1029 String subnetIp = subnetSplit[0];
1030 String subnetPrefix = "0";
1031 if (subnetSplit.length == 2) {
1032 subnetPrefix = subnetSplit[1];
1034 return new String[] {subnetIp, subnetPrefix};
1038 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1039 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1040 .builder(Subnetmaps.class)
1041 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1043 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1044 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1047 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1048 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1049 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1050 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1051 if (leastLoadedExtIpAddrSplit.length == 2) {
1052 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1054 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1058 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1059 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1060 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1061 Optional<RouterDpnList> routerDpnListData =
1062 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1063 LogicalDatastoreType.OPERATIONAL, id);
1064 List<BigInteger> dpns = new ArrayList<>();
1065 if (routerDpnListData.isPresent()) {
1066 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1067 dpns.add(dpnVpnInterface.getDpnId());
1073 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1074 long bgpVpnId = NatConstants.INVALID_ID;
1075 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1076 if (bgpVpnUuid != null) {
1077 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1082 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1083 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1084 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1085 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1088 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1089 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1090 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1091 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1092 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1093 .RouterInterface.class,
1094 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1095 .RouterInterfaceKey(interfaceName)).build();
1098 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1099 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1101 if (dpId.equals(BigInteger.ZERO)) {
1102 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1103 + "to handle router {} association model", interfaceName, routerName);
1107 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1108 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1109 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1111 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1112 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1113 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1114 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1115 .setInterface(interfaceName).build();
1116 if (optionalDpnVpninterfacesList.isPresent()) {
1117 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1118 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1119 operTx.merge(dpnVpnInterfacesListIdentifier
1120 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1121 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1122 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1124 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1125 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1126 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1127 routerDpnListBuilder.setRouterId(routerName);
1128 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1129 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1130 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1131 routerInterfaces.add(routerInterface);
1132 dpnVpnList.setRouterInterfaces(routerInterfaces);
1133 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1134 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1138 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1139 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1140 if (dpId.equals(BigInteger.ZERO)) {
1141 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1142 + "association model", interfaceName, routerName);
1146 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1147 + "DPNRouters map", dpId, routerName, interfaceName);
1148 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1150 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1152 if (optionalDpnRoutersList.isPresent()) {
1153 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1154 .setRouter(routerName).build();
1155 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1156 if (!routersListFromDs.contains(routersList)) {
1157 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1158 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1159 operTx.merge(dpnRoutersListIdentifier
1160 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1162 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1163 + "DPNRouters map", routerName, dpId);
1166 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1167 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1168 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1169 dpnRoutersListBuilder.setDpnId(dpId);
1170 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1171 routersListBuilder.setRouter(routerName);
1172 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1173 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1177 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1178 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1179 if (dpId.equals(BigInteger.ZERO)) {
1180 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1184 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1185 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1186 if (optionalRouterDpnList.isPresent()) {
1187 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1188 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1189 operTx.delete(routerDpnListIdentifier);
1191 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1192 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1196 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1197 BigInteger dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1198 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1199 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1201 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1202 } catch (InterruptedException | ExecutionException e) {
1203 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1204 optionalRouterDpnList = Optional.absent();
1206 if (optionalRouterDpnList.isPresent()) {
1207 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1208 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1209 optionalRouterDpnList.get().getRouterInterfaces();
1210 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1211 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1212 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1213 .setInterface(vpnInterfaceName).build();
1215 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1216 if (routerInterfaces.isEmpty()) {
1217 operTx.delete(routerDpnListIdentifier);
1219 operTx.delete(routerDpnListIdentifier.child(
1220 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1221 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1222 new RouterInterfacesKey(vpnInterfaceName)));
1228 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1229 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1230 throws ExecutionException, InterruptedException {
1232 1) Get the DpnRoutersList for the DPN.
1233 2) Get the RoutersList identifier for the DPN and router.
1234 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1235 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1236 then remove RouterList.
1239 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1240 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1242 //Get the dpn-routers-list instance for the current DPN.
1243 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1244 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1246 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1247 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1248 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1252 //Get the routers-list instance for the router on the current DPN only
1253 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1254 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1256 if (routersListData == null || !routersListData.isPresent()) {
1257 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1258 + "in the ODL-L3VPN:dpn-routers model",
1263 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1264 + "from the NeutronVPN - router-interfaces-map", routerName);
1265 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1266 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1267 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1268 .RouterInterfaces> routerInterfacesData =
1269 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1270 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1272 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1273 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1274 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1275 curDpnId, routerName, routerName);
1276 operTx.delete(routersListIdentifier);
1280 //Get the VM interfaces for the router on the current DPN only.
1281 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1282 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1283 if (vmInterfaces == null) {
1284 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1285 + "NeutronVPN - router-interfaces-map", routerName);
1289 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1290 // then remove RouterList.
1291 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1292 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1293 String vmInterfaceName = vmInterface.getInterfaceId();
1294 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1295 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1296 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1297 + "the DPN ID {} for the checked interface {}",
1298 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1301 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1302 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1303 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1307 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1308 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1309 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1310 operTx.delete(routersListIdentifier);
1313 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1314 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1315 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1316 .rev150602.RouterInterfacesMap.class)
1317 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1318 .interfaces.map.RouterInterfaces.class,
1319 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1320 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1323 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1324 return InstanceIdentifier.builder(DpnRouters.class)
1325 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1326 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1329 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1330 BigInteger nodeId = BigInteger.ZERO;
1332 GetDpidFromInterfaceInput
1334 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1335 Future<RpcResult<GetDpidFromInterfaceOutput>>
1337 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1338 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1339 if (dpIdResult.isSuccessful()) {
1340 nodeId = dpIdResult.getResult().getDpid();
1342 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1344 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1345 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1351 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1352 ItmRpcService itmRpcService,
1353 IInterfaceManager interfaceManager, String ifName,
1354 Long tunnelKey, boolean internalTunnelInterface) {
1355 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1356 ifName, tunnelKey, 0, internalTunnelInterface);
1360 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1361 ItmRpcService itmRpcService,
1362 IInterfaceManager interfaceManager,
1363 String ifName, @Nullable Long tunnelKey, int pos,
1364 boolean internalTunnelInterface) {
1365 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1366 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1367 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1368 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1369 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1370 if (tunnelKey != null) {
1371 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1372 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1373 } //init builders, ITM/IFM rpc can be called based on type of interface
1376 List<Action> actions = emptyList();
1377 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1378 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1379 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1380 if (!rpcResult.isSuccessful()) {
1381 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1382 + "returned with Errors {}", ifName, rpcResult.getErrors());
1384 actions = rpcResult.getResult().nonnullAction();
1387 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1388 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1389 if (!rpcResult.isSuccessful()) {
1390 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1391 + "returned with Errors {}", ifName, rpcResult.getErrors());
1393 actions = rpcResult.getResult().nonnullAction();
1396 List<ActionInfo> listActionInfo = new ArrayList<>();
1397 for (Action action : actions) {
1398 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1399 actionClass = action.getAction();
1400 if (actionClass instanceof OutputActionCase) {
1401 listActionInfo.add(new ActionOutput(pos++,
1402 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1403 } else if (actionClass instanceof PushVlanActionCase) {
1404 listActionInfo.add(new ActionPushVlan(pos++));
1405 } else if (actionClass instanceof SetFieldCase) {
1406 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1407 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1408 .getVlanId().getValue();
1409 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1411 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1412 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1413 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1414 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1415 NxRegLoad nxRegLoad =
1416 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1417 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1418 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1421 return listActionInfo;
1422 } catch (InterruptedException | ExecutionException e) {
1423 LOG.error("Exception when egress actions for interface {}", ifName, e);
1425 LOG.error("Error when getting egress actions for interface {}", ifName);
1430 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1431 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1435 public static List<Port> getNeutronPorts(DataBroker broker) {
1436 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1437 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1438 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1439 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1441 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1442 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1444 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1445 LOG.error("getNeutronPorts : No neutron ports found");
1449 return portsOptional.get().getPort();
1453 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1454 List<Port> ports = getNeutronPorts(
1457 for (Port port : ports) {
1458 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1459 for (FixedIps ip : port.getFixedIps()) {
1460 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1466 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1471 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1473 LOG.error("getSubnetIdForFloatingIp : port is null");
1476 for (FixedIps ip : port.nonnullFixedIps()) {
1477 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1478 return ip.getSubnetId();
1481 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1486 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1487 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1488 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1489 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1490 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1494 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1495 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1496 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1497 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1498 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1503 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1504 if (subnetId == null) {
1505 LOG.error("getSubnetGwMac : subnetID is null");
1509 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1510 .child(Subnet.class, new SubnetKey(subnetId));
1511 Optional<Subnet> subnetOpt =
1512 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1513 LogicalDatastoreType.CONFIGURATION, subnetInst);
1514 if (!subnetOpt.isPresent()) {
1515 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1519 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1520 if (gatewayIp == null) {
1521 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1525 if (null != gatewayIp.getIpv6Address()) {
1529 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1530 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1532 Optional<VpnPortipToPort> portIpToPortOpt =
1533 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1534 LogicalDatastoreType.CONFIGURATION, portIpInst);
1535 if (portIpToPortOpt.isPresent()) {
1536 return portIpToPortOpt.get().getMacAddress();
1539 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1540 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1542 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1543 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1544 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1545 if (learntIpToPortOpt.isPresent()) {
1546 return learntIpToPortOpt.get().getMacAddress();
1549 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1553 public static boolean isIPv6Subnet(String prefix) {
1554 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1557 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1558 return InstanceIdentifier.builder(DpnRouters.class)
1559 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1562 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1563 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1564 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1565 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1568 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1569 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1570 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1574 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1575 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1576 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1577 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1578 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1582 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1583 Uuid floatingIpId) {
1585 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1586 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1587 } catch (InterruptedException | ExecutionException e) {
1588 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1594 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1595 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1596 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1597 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1598 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1602 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1603 Uuid floatingIpId) {
1605 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1606 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1607 } catch (InterruptedException | ExecutionException e) {
1608 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1613 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1614 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1615 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1619 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1620 InstanceIdentifier<Interface> ifStateId =
1621 buildStateInterfaceId(interfaceName);
1622 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1623 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1626 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1627 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1628 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1629 .interfaces.rev140508.InterfacesState.class)
1630 .child(Interface.class,
1631 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1632 .interfaces.state.InterfaceKey(interfaceName));
1633 return idBuilder.build();
1637 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1638 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1639 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1640 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1644 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1646 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1647 } catch (InterruptedException | ExecutionException e) {
1648 LOG.error("Error reading router {}", routerName, e);
1653 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1654 if (routerId == NatConstants.INVALID_ID) {
1655 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1658 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1659 .setRouterId(routerId).setRouterName(routerName).build();
1660 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1664 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1665 IdManagerService idManager) {
1666 InetAddress defaultIP = null;
1668 defaultIP = InetAddress.getByName("0.0.0.0");
1669 } catch (UnknownHostException e) {
1670 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1671 + "Default Route to NAT.", e);
1675 List<MatchInfo> matches = new ArrayList<>();
1676 matches.add(MatchEthernetType.IPV4);
1677 //add match for vrfid
1678 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1680 List<InstructionInfo> instructions = new ArrayList<>();
1681 List<ActionInfo> actionsInfo = new ArrayList<>();
1682 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1683 actionsInfo.add(new ActionGroup(groupId));
1684 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1685 instructions.add(new InstructionApplyActions(actionsInfo));
1686 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1687 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1688 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1692 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1693 String routerName = getRouterName(broker, routerId);
1694 if (routerName == null) {
1695 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1698 return getExtGwMacAddFromRouterName(broker, routerName);
1702 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1703 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1704 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1705 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1709 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1711 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1712 Routers::getExtGwMacAddress).orElse(null);
1713 } catch (InterruptedException | ExecutionException e) {
1714 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1719 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1720 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1721 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1722 .child(Router.class, new RouterKey(routerUuid));
1723 return routerInstanceIdentifier;
1727 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1728 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1729 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1730 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1735 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1736 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1737 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1738 LogicalDatastoreType.CONFIGURATION,
1739 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1743 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1744 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1745 Optional<ExternalNetworks> externalNwData =
1746 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1747 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1748 if (externalNwData.isPresent()) {
1749 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1750 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1751 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1752 return routerIds != null ? routerIds : emptyList();
1759 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1762 long ipLo = ipToLong(InetAddress.getByName(start));
1763 long ipHi = ipToLong(InetAddress.getByName(end));
1764 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1765 return ipToTest >= ipLo && ipToTest <= ipHi;
1766 } catch (UnknownHostException e) {
1767 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1773 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1774 if (externalIps == null) {
1775 return Collections.emptySet();
1778 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1782 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1783 if (routerName == null) {
1784 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1785 return Collections.emptySet();
1788 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1789 Optional<Routers> routerData =
1790 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1791 LogicalDatastoreType.CONFIGURATION, id);
1792 if (routerData.isPresent()) {
1793 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1795 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1796 return Collections.emptySet();
1801 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1802 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1803 if (subnetId == null) {
1804 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1805 return Optional.absent();
1808 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1809 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1810 InstanceIdentifier.builder(ExternalSubnets.class)
1811 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1812 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1813 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1814 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1818 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1819 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1820 if (subnetId == null) {
1821 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1822 return Optional.absent();
1825 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1826 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1827 InstanceIdentifier.builder(ExternalSubnets.class)
1828 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1829 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1831 return tx.read(subnetsIdentifier).get();
1832 } catch (InterruptedException | ExecutionException e) {
1833 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1834 return Optional.absent();
1838 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1839 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1840 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1842 if (optionalExternalSubnets.isPresent()) {
1843 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1846 return NatConstants.INVALID_ID;
1849 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1850 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1851 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1853 if (optionalExternalSubnets.isPresent()) {
1854 return NatUtil.getVpnId(tx, subnetId.getValue());
1857 return NatConstants.INVALID_ID;
1860 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1862 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1863 if (externalSubnetId != null) {
1864 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1867 return NatConstants.INVALID_ID;
1871 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1872 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1873 for (ExternalIps extIp : router.nonnullExternalIps()) {
1874 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1875 if (extIpString.equals(externalIpAddress)) {
1876 return extIp.getSubnetId();
1879 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1883 private static long ipToLong(InetAddress ip) {
1884 byte[] octets = ip.getAddress();
1886 for (byte octet : octets) {
1888 result |= octet & 0xff;
1894 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1895 if (externalIps == null) {
1899 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1902 // elan-instances config container
1904 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1905 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1906 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1907 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1911 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1913 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1914 } catch (InterruptedException | ExecutionException e) {
1915 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1920 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1921 return InstanceIdentifier.builder(ElanInstances.class)
1922 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1925 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
1926 IElanService elanManager, IdManagerService idManager,
1927 long routerId, String routerName) {
1928 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1929 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1930 return natOverVxlanUtil.getRouterVni(routerName, routerId).longValue();
1932 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1936 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1937 short tableId, TypedWriteTransaction<Configuration> confTx) {
1938 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1939 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1941 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1942 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1943 List<MatchInfo> matches = new ArrayList<>();
1944 matches.add(MatchEthernetType.IPV4);
1945 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1946 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1947 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1948 matches, preDnatToSnatInstructions);
1950 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
1951 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1952 preDnatToSnatTableFlowEntity, naptDpnId);
1955 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
1956 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
1957 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1958 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1959 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1960 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
1961 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1962 flowRef, naptDpnId);
1965 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1966 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1967 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1970 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1971 String vpnName, String externalIp,
1972 Boolean isMoreThanOneFipCheckOnDpn) {
1973 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1974 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1975 if (dpnInVpn.isPresent()) {
1976 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1977 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
1979 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1980 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1981 int floatingIpPresentCount = 0;
1982 for (IpAddresses ipAddress: ipAddressList) {
1983 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
1984 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1985 floatingIpPresentCount++;
1986 //Add tunnel table check
1987 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1990 //Remove tunnel table check
1991 if (!isMoreThanOneFipCheckOnDpn) {
1997 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2001 } catch (NullPointerException e) {
2002 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2003 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2010 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
2011 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2012 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2013 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2017 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2018 throws ExecutionException, InterruptedException {
2019 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2023 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2024 if (vpnInstance == null) {
2027 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2028 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2031 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2032 return InstanceIdentifier.builder(VpnInstances.class)
2033 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2037 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2038 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2039 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2040 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2043 public static String validateAndAddNetworkMask(String ipAddress) {
2044 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2047 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2048 String vpnInterfaceName, String vpnName) {
2049 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2050 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2053 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2054 String routerName, BigInteger dpnId) {
2055 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2056 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2058 if (networkData != null && networkData.isPresent()) {
2059 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2060 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2061 for (Uuid routerUuid : routerUuidList) {
2062 String sharedRouterName = routerUuid.getValue();
2063 if (!routerName.equals(sharedRouterName)) {
2064 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2065 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2066 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2067 + "associated with other active router {} on NAPT switch {}", networkId,
2068 sharedRouterName, switchDpnId);
2078 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2079 String routerName, BigInteger dpnId) {
2080 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2081 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2082 .subnets.Subnets::getRouterIds).orElse(emptyList());
2083 if (!routerUuidList.isEmpty()) {
2084 for (Uuid routerUuid : routerUuidList) {
2085 String sharedRouterName = routerUuid.getValue();
2086 if (!routerName.equals(sharedRouterName)) {
2087 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2088 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2089 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2090 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2091 sharedRouterName, switchDpnId);
2100 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2101 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2102 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2103 List<ExternalIps> externalIps = router.getExternalIps();
2104 List<String> externalIpsSting = new ArrayList<>();
2106 if (externalIps == null || externalIps.isEmpty()) {
2107 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2110 for (ExternalIps externalIp : externalIps) {
2111 externalIpsSting.add(externalIp.getIpAddress());
2113 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2114 if (addOrRemove == NwConstants.ADD_FLOW) {
2115 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2116 router.getNetworkId(), subnetVpnName.getValue(), tx);
2117 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2118 router.getExtGwMacAddress(), primarySwitchId,
2119 router.getNetworkId());
2121 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2122 router.getNetworkId(), subnetVpnName.getValue(), tx);
2123 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2124 router.getExtGwMacAddress(), primarySwitchId,
2125 router.getNetworkId());
2127 }), LOG, "Error installing router gateway flows");
2130 @SuppressWarnings("checkstyle:IllegalCatch")
2131 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2132 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2133 String routerName, long routerId, long routerVpnId,
2134 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2135 throws ExecutionException, InterruptedException {
2136 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2137 //remove miss entry to NAPT switch
2138 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2139 if (extNwProvType == null) {
2142 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2143 Map<String, Long> externalIpLabel;
2144 if (extNwProvType == ProviderTypes.VXLAN) {
2145 externalIpLabel = null;
2147 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2149 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2150 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2151 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2154 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2155 boolean naptStatus =
2156 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2157 externalIpCache, confTx);
2159 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2161 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
2162 FlowEntity flowEntity = null;
2164 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2165 NatConstants.DEL_FLOW);
2166 if (flowEntity == null) {
2167 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2168 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2171 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
2172 mdsalManager.removeFlow(confTx, flowEntity);
2174 } catch (Exception ex) {
2175 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2179 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2183 GroupEntity groupEntity = null;
2185 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2186 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2187 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2188 mdsalManager.removeGroup(groupEntity);
2189 } catch (Exception ex) {
2190 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2193 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2196 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2197 externalIpLabel, confTx);
2198 //remove table 26 flow ppointing to table46
2199 FlowEntity flowEntity = null;
2201 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2202 NatConstants.DEL_FLOW);
2203 if (flowEntity == null) {
2204 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2208 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2209 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2210 mdsalManager.removeFlow(confTx, flowEntity);
2212 } catch (Exception ex) {
2213 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2217 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2220 //best effort to check IntExt model
2221 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2225 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2226 ProviderTypes extNwProvType) {
2227 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2228 || extNwProvType == ProviderTypes.VXLAN)) {
2234 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2235 BigInteger dpnId, DataBroker dataBroker) {
2236 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2237 elanInstanceName, dpnId);
2238 // FIXME: separate this out?
2239 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2242 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2243 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2244 List<String> elanInterfaceList;
2245 DpnInterfaces dpnInterface;
2246 if (!dpnInElanInterfaces.isPresent()) {
2247 elanInterfaceList = new ArrayList<>();
2249 dpnInterface = dpnInElanInterfaces.get();
2250 elanInterfaceList = dpnInterface.getInterfaces();
2252 if (!elanInterfaceList.contains(pseudoPortId)) {
2253 elanInterfaceList.add(pseudoPortId);
2254 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2255 .withKey(new DpnInterfacesKey(dpnId)).build();
2256 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2257 elanDpnInterfaceId, dpnInterface);
2259 } catch (ReadFailedException e) {
2260 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2261 } catch (TransactionCommitFailedException e) {
2262 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2268 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2269 BigInteger dpnId, DataBroker dataBroker) {
2270 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2271 elanInstanceName, dpnId);
2272 // FIXME: separate this out?
2273 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2276 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2277 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2278 List<String> elanInterfaceList;
2279 DpnInterfaces dpnInterface;
2280 if (!dpnInElanInterfaces.isPresent()) {
2281 LOG.info("No interface in any dpn for {}", elanInstanceName);
2285 dpnInterface = dpnInElanInterfaces.get();
2286 elanInterfaceList = dpnInterface.getInterfaces();
2287 if (!elanInterfaceList.contains(pseudoPortId)) {
2288 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2291 elanInterfaceList.remove(pseudoPortId);
2292 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2293 .withKey(new DpnInterfacesKey(dpnId)).build();
2294 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2295 elanDpnInterfaceId, dpnInterface);
2296 } catch (ReadFailedException e) {
2297 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2298 } catch (TransactionCommitFailedException e) {
2299 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2305 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2306 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2307 for (Map.Entry<String,Routers> router : extRouter) {
2308 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2309 .equals(networkid)) {
2317 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2319 return SingleTransactionDataBroker.syncRead(dataBroker,
2320 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2322 catch (ReadFailedException e) {
2323 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2328 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2329 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2330 .builder(LearntVpnVipToPortData.class).build();
2331 return learntVpnVipToPortDataId;
2334 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2336 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2337 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2338 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2341 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2342 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2343 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2344 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2347 public static void createGroupIdPool(IdManagerService idManager) {
2348 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2349 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2350 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2351 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2354 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2355 if (result != null && result.get().isSuccessful()) {
2356 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2358 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2360 } catch (InterruptedException | ExecutionException e) {
2361 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2365 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2366 NodeId nodeId = new NodeId("openflow:" + switchId);
2367 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2368 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2369 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2370 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2371 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2372 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2373 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2374 if (nodeOptional.isPresent()) {
2375 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2378 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2382 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2383 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2384 Optional<Networks> networkData =
2385 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2386 broker, LogicalDatastoreType.CONFIGURATION, id);
2387 return networkData.isPresent();
2391 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2392 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2393 if (null != elanInstance) {
2394 return elanInstance.getPhysicalNetworkName();
2400 public static Map<String, String> getOpenvswitchOtherConfigMap(BigInteger dpnId, DataBroker dataBroker) {
2401 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2402 return getMultiValueMap(otherConfigVal);
2405 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2406 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2407 return Collections.emptyMap();
2410 Map<String, String> valueMap = new HashMap<>();
2411 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2412 for (String keyValue : splitter.split(multiKeyValueStr)) {
2413 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2414 if (split.length == 2) {
2415 valueMap.put(split[0], split[1]);
2422 public static Optional<Node> getBridgeRefInfo(BigInteger dpnId, DataBroker dataBroker) {
2423 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2424 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2426 Optional<BridgeRefEntry> bridgeRefEntry =
2427 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2428 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2429 if (!bridgeRefEntry.isPresent()) {
2430 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2431 return Optional.absent();
2434 InstanceIdentifier<Node> nodeId =
2435 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2437 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2438 LogicalDatastoreType.OPERATIONAL, nodeId);
2442 public static String getProviderMappings(BigInteger dpId, DataBroker dataBroker) {
2443 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2444 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2448 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2449 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2450 if (ovsdbNode == null) {
2451 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2452 if (nodeFromReadOvsdbNode.isPresent()) {
2453 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2457 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2458 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2459 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2460 return openvswitchOtherConfigs.getOtherConfigValue();
2464 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2469 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2470 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2471 if (bridgeAugmentation != null) {
2472 InstanceIdentifier<Node> ovsdbNodeIid =
2473 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2474 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2475 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2477 return Optional.absent();
2482 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2486 return node.augmentation(OvsdbBridgeAugmentation.class);
2489 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
2490 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2493 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2494 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2495 InstanceIdentifier.builder(ExternalSubnets.class)
2498 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2499 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2500 if (optionalExternalSubnets.isPresent()) {
2501 return optionalExternalSubnets.get();
2503 } catch (ReadFailedException e) {
2504 LOG.error("Failed to read the subnets from the datastore.");
2510 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2511 BigInteger dpId, short tableId, String flowId, int priority, String flowName, BigInteger cookie,
2512 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2513 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2514 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2516 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2517 mdsalManager.addFlow(confTx, flowEntity);
2520 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2521 BigInteger dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2522 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2523 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2526 public static String getIpv6FlowRef(BigInteger dpnId, short tableId, long routerID) {
2527 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2528 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2531 public static String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId,
2532 ItmRpcService itmManager) {
2533 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2534 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2536 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2537 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2538 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2539 rpcResult = result.get();
2540 if (!rpcResult.isSuccessful()) {
2541 tunType = TunnelTypeGre.class ;
2542 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2543 .setSourceDpid(srcDpId)
2544 .setDestinationDpid(dstDpId)
2545 .setTunnelType(tunType)
2547 rpcResult = result.get();
2548 if (!rpcResult.isSuccessful()) {
2549 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2550 rpcResult.getErrors());
2552 return rpcResult.getResult().getInterfaceName();
2554 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2555 rpcResult.getErrors());
2557 return rpcResult.getResult().getInterfaceName();
2559 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2560 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2561 + "between {} and {}", srcDpId, dstDpId);
2566 static ReentrantLock lockForNat(final BigInteger dataPath) {
2567 // FIXME: wrap this in an Identifier
2568 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);