2 * Copyright © 2016, 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.natservice.internal;
10 import static java.util.Collections.emptyList;
11 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
12 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import com.google.common.base.Splitter;
17 import com.google.common.base.Strings;
18 import com.google.common.collect.Iterables;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import java.math.BigInteger;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Objects;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.locks.ReentrantLock;
35 import java.util.stream.Collectors;
36 import org.apache.commons.net.util.SubnetUtils;
37 import org.eclipse.jdt.annotation.NonNull;
38 import org.eclipse.jdt.annotation.Nullable;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
42 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
43 import org.opendaylight.controller.sal.common.util.Arguments;
44 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
45 import org.opendaylight.genius.infra.Datastore.Configuration;
46 import org.opendaylight.genius.infra.Datastore.Operational;
47 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
48 import org.opendaylight.genius.infra.TypedReadTransaction;
49 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
50 import org.opendaylight.genius.infra.TypedWriteTransaction;
51 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
52 import org.opendaylight.genius.mdsalutil.ActionInfo;
53 import org.opendaylight.genius.mdsalutil.BucketInfo;
54 import org.opendaylight.genius.mdsalutil.FlowEntity;
55 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
56 import org.opendaylight.genius.mdsalutil.GroupEntity;
57 import org.opendaylight.genius.mdsalutil.InstructionInfo;
58 import org.opendaylight.genius.mdsalutil.MDSALUtil;
59 import org.opendaylight.genius.mdsalutil.MatchInfo;
60 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
61 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
62 import org.opendaylight.genius.mdsalutil.NwConstants;
63 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
64 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
65 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
66 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
67 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
68 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
69 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
70 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
71 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
72 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
73 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
74 import org.opendaylight.genius.utils.JvmGlobalLocks;
75 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
76 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
77 import org.opendaylight.netvirt.elanmanager.api.IElanService;
78 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
79 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
80 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
81 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
82 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
83 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
84 import org.opendaylight.serviceutils.upgrade.UpgradeState;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
87 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
88 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
89 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
90 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
91 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
94 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
95 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdOutput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
262 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
263 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
264 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
265 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
266 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
267 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
268 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
269 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
270 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
271 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
272 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
273 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
274 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
275 import org.opendaylight.yangtools.yang.common.RpcResult;
276 import org.slf4j.Logger;
277 import org.slf4j.LoggerFactory;
279 public final class NatUtil {
281 private static String OF_URI_SEPARATOR = ":";
282 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
283 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
284 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
285 private static final String PROVIDER_MAPPINGS = "provider_mappings";
292 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
295 public static BigInteger getCookieSnatFlow(long routerId) {
296 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
297 BigInteger.valueOf(routerId));
301 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
304 public static BigInteger getCookieNaptFlow(long routerId) {
305 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
306 BigInteger.valueOf(routerId));
310 getVpnId() returns the VPN ID from the VPN name
312 public static long getVpnId(DataBroker broker, @Nullable String vpnName) {
313 if (vpnName == null) {
314 return NatConstants.INVALID_ID;
317 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
318 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
319 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
320 .instance.to.vpn.id.VpnInstance> vpnInstance =
321 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
322 LogicalDatastoreType.CONFIGURATION, id);
324 long vpnId = NatConstants.INVALID_ID;
325 if (vpnInstance.isPresent()) {
326 Long vpnIdAsLong = vpnInstance.get().getVpnId();
327 if (vpnIdAsLong != null) {
334 public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
335 if (vpnName == null) {
336 return NatConstants.INVALID_ID;
340 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
341 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
342 .VpnInstance::getVpnId).orElse(Long.valueOf(NatConstants.INVALID_ID));
343 } catch (InterruptedException | ExecutionException e) {
344 LOG.error("Error retrieving VPN id for {}", vpnName, e);
347 return NatConstants.INVALID_ID;
350 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
351 //Get the external network ID from the ExternalRouter model
352 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
353 if (networkId == null) {
354 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
355 return Long.valueOf(NatConstants.INVALID_ID);
358 //Get the VPN ID from the ExternalNetworks model
359 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
360 if (vpnUuid == null) {
361 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
362 return Long.valueOf(NatConstants.INVALID_ID);
364 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
368 public static Boolean validateIsIntefacePartofRouter(DataBroker broker, String routerName, String interfaceName) {
369 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
370 .map.router.interfaces.Interfaces> vmInterfaceIdentifier = getRoutersInterfacesIdentifier(routerName,
373 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
374 .map.router.interfaces.Interfaces> routerInterfacesData;
376 routerInterfacesData = SingleTransactionDataBroker.syncReadOptional(broker,
377 LogicalDatastoreType.CONFIGURATION, vmInterfaceIdentifier);
378 } catch (ReadFailedException e) {
379 LOG.error("Read Failed Exception While read RouterInterface data for router {}", routerName, e);
380 routerInterfacesData = Optional.absent();
382 if (routerInterfacesData.isPresent()) {
385 return Boolean.FALSE;
389 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
390 .rev150602.router.interfaces
391 .map.router.interfaces.Interfaces> getRoutersInterfacesIdentifier(String routerName, String interfaceName) {
392 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
393 .rev150602.RouterInterfacesMap.class)
394 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
395 .interfaces.map.RouterInterfaces.class,
396 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
397 .interfaces.map.RouterInterfacesKey(new Uuid(routerName)))
398 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
399 .map.router.interfaces.Interfaces.class,
400 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
401 .map.router.interfaces.InterfacesKey(interfaceName)).build();
404 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
405 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
406 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
407 .rev150602.RouterInterfacesMap.class)
408 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
409 .interfaces.map.RouterInterfaces.class,
410 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
411 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
414 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
415 return InstanceIdentifier.builder(FloatingIpInfo.class)
416 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
419 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
420 return InstanceIdentifier.builder(RouterToVpnMapping.class)
421 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
424 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
425 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
426 .child(Ports.class, new PortsKey(portName)).build();
429 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
431 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
432 .child(Ports.class, new PortsKey(portName))
433 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
436 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
437 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
438 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
439 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
440 .instance.to.vpn.id.VpnInstance.class,
441 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
442 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
446 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
447 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
448 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
449 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
450 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
454 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
456 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
457 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
458 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
459 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
462 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
463 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
464 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
465 .append(destPrefix.getHostAddress()).append(NatConstants.FLOWID_SEPARATOR).append(vpnId).toString();
468 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip,
469 int port, String protocol) {
470 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
471 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
472 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).append(NatConstants.FLOWID_SEPARATOR)
473 .append(port).append(NatConstants.FLOWID_SEPARATOR).append(protocol).toString();
477 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
478 String routerName = getRouterName(broker, routerId);
479 if (routerName == null) {
480 LOG.error("getNetworkIdFromRouterId - empty routerName received");
483 return getNetworkIdFromRouterName(broker, routerName);
487 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
488 if (routerName == null) {
489 LOG.error("getNetworkIdFromRouterName - empty routerName received");
492 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
493 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
494 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
497 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
498 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
499 .child(Routers.class, new RoutersKey(routerId)).build();
500 return routerInstanceIndentifier;
503 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
504 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
505 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
510 * Return if SNAT is enabled for the given router.
512 * @param broker The DataBroker
513 * @param routerId The router
514 * @return boolean true if enabled, otherwise false
516 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
517 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
518 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
519 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
523 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
524 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
525 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
526 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
530 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
532 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
533 } catch (InterruptedException | ExecutionException e) {
534 LOG.error("Error reading network VPN id for {}", networkId, e);
540 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
541 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
542 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
543 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
547 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
548 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
550 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
551 } catch (InterruptedException | ExecutionException e) {
552 LOG.error("Error retrieving provider type for {}", networkId, e);
558 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
559 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
560 Optional<Routers> routerData =
561 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
562 LogicalDatastoreType.CONFIGURATION, id);
563 if (routerData.isPresent()) {
564 Uuid networkId = routerData.get().getNetworkId();
565 if (networkId != null) {
566 return networkId.getValue();
569 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
573 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
574 return InstanceIdentifier.builder(ExternalNetworks.class)
575 .child(Networks.class, new NetworksKey(networkId)).build();
579 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
580 // convert routerId to Name
581 String routerName = getRouterName(broker, routerId);
582 if (routerName == null) {
583 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
586 return getPrimaryNaptfromRouterName(broker, routerName);
590 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
591 if (routerName == null) {
592 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
595 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
596 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
597 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
601 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
602 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
603 new RouterToNaptSwitchKey(routerId)).build();
606 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
607 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
608 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
612 public static String getRouterName(DataBroker broker, Long routerId) {
613 return getVpnInstanceFromVpnIdentifier(broker, routerId);
616 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
617 return InstanceIdentifier.builder(VpnInstanceOpData.class)
618 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
621 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
622 return new FlowEntityBuilder()
630 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
631 return new FlowEntityBuilder()
639 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
640 String nextHopIp = null;
641 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
642 InstanceIdentifier.builder(DpnEndpoints.class)
643 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
644 Optional<DPNTEPsInfo> tunnelInfo =
645 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
646 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
647 if (tunnelInfo.isPresent()) {
648 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
649 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
650 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
657 public static String getVpnRd(DataBroker broker, String vpnName) {
658 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
659 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
660 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
661 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
662 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
663 .VpnInstance::getVrfId).orElse(null);
667 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
669 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
670 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
671 .VpnInstance::getVrfId).orElse(null);
672 } catch (InterruptedException | ExecutionException e) {
673 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
679 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
680 String internalPort, NAPTEntryEvent.Protocol protocol) {
681 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
682 InstanceIdentifier<IpPortMap> ipPortMapId =
683 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
684 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
685 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
689 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
691 ProtocolTypes protocolType) {
692 return InstanceIdentifier.builder(IntextIpPortMap.class)
693 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
694 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
695 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
698 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
699 return InstanceIdentifier.builder(VpnInterfaces.class)
700 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
704 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
706 * NodeConnectorId is of form 'openflow:dpnid:portnum'
708 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
709 if (split.length != 3) {
710 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
716 public static BigInteger getDpIdFromInterface(
717 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
718 .state.Interface ifState) {
719 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
720 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
721 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
726 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
727 // returns only router, attached to IPv4 networks
728 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
729 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
730 Optional<VpnMap> optionalVpnMap =
731 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
732 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
733 if (!optionalVpnMap.isPresent()) {
734 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
737 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
738 if (routerIdsList != null && !routerIdsList.isEmpty()) {
739 for (Uuid routerUuid : routerIdsList) {
740 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
741 Optional<Routers> routerData =
742 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
743 LogicalDatastoreType.CONFIGURATION, id);
744 if (routerData.isPresent()) {
745 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
746 for (Uuid subnetUuid : subnetIdsList) {
747 String subnetIp = getSubnetIp(broker, subnetUuid);
748 SubnetUtils subnet = new SubnetUtils(subnetIp);
749 if (subnet.getInfo().isInRange(ipAddress)) {
750 return routerUuid.getValue();
756 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
761 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
762 Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
763 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
764 Optional<VpnMaps> optionalVpnMaps =
765 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
766 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
767 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
768 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap()) {
769 if (routerId.equals(vpnMap.getVpnId().getValue())) {
772 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
773 if (routerIdsList.isEmpty()) {
776 // Skip router vpnId fetching from internet BGP-VPN
777 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
778 // We only need to check the first network; if it’s not an external network there’s no
779 // need to check the rest of the VPN’s network list
780 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
784 if (routerIdsList.contains(new Uuid(routerId))) {
785 return vpnMap.getVpnId();
789 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
793 static long getAssociatedVpn(DataBroker broker, String routerName) {
794 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
795 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
796 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
797 Long.valueOf(NatConstants.INVALID_ID));
801 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
802 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
803 if (vpnUuid == null) {
804 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
807 return vpnUuid.getValue();
811 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
812 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
813 if (vpnUuid == null) {
814 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
817 return vpnUuid.getValue();
820 // TODO Clean up the exception handling
821 @SuppressWarnings("checkstyle:IllegalCatch")
822 public static void addPrefixToBGP(DataBroker broker,
823 IBgpManager bgpManager,
824 IFibManager fibManager,
829 @Nullable String parentVpnRd,
830 @Nullable String macAddress,
836 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
837 prefix, nextHopIp, label);
838 if (nextHopIp == null) {
839 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
844 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
845 dpId, Prefixes.PrefixCue.Nat);
846 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
847 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
848 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
849 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
850 /* Publish to Bgp only if its an INTERNET VPN */
851 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
852 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
853 null /*gatewayMac*/);
855 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
856 prefix, nextHopIp, label);
857 } catch (Exception e) {
858 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
859 prefix, nextHopIp, label, e);
863 static void addPrefixToInterface(DataBroker broker, long vpnId, @Nullable String interfaceName, String ipPrefix,
864 String networkId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
865 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
866 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
867 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
868 .to._interface.VpnIdsKey(vpnId))
869 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
870 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
871 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
872 prefixBuilder.setNetworkId(new Uuid(networkId));
874 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
875 prefixBuilder.build());
876 } catch (TransactionCommitFailedException e) {
877 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
878 ipPrefix, vpnId, dpId, e);
882 public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
884 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
885 InstanceIdentifier.builder(PrefixToInterface.class)
886 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
887 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
888 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
890 } catch (TransactionCommitFailedException e) {
891 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
896 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
897 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
898 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
902 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
903 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
904 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
905 return routerInstanceIndentifier;
909 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
910 String internalIpAddress, ProtocolTypes protocolType) {
911 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
912 LogicalDatastoreType.CONFIGURATION,
913 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
914 IntIpProtoType::getPorts).orElse(emptyList());
917 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
918 String internalIpAddress,
919 ProtocolTypes protocolType) {
920 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
921 InstanceIdentifier.builder(SnatintIpPortMap.class)
922 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
923 .child(IpPort.class, new IpPortKey(internalIpAddress))
924 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
925 return intIpProtocolTypeId;
928 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
929 String internalIpAddress) {
930 InstanceIdentifier<IpPort> intIpProtocolTypeId =
931 InstanceIdentifier.builder(SnatintIpPortMap.class)
932 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
933 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
934 return intIpProtocolTypeId;
938 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
939 String internalIpAddress) {
940 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
941 LogicalDatastoreType.CONFIGURATION,
942 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
945 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
946 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
947 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
951 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
952 return InstanceIdentifier.create(NaptSwitches.class);
955 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
956 return InstanceIdentifier.create(NaptSwitches.class)
957 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
960 public static String getGroupIdKey(String routerName) {
961 return "snatmiss." + routerName;
964 public static int getUniqueId(IdManagerService idManager, String poolName, String idKey) {
966 AllocateIdInput getIdInput = (new AllocateIdInputBuilder()).setPoolName(poolName).setIdKey(idKey).build();
968 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
969 RpcResult<AllocateIdOutput> rpcResult = (RpcResult)result.get();
970 return rpcResult.isSuccessful() ? rpcResult.getResult().getIdValue().intValue() : NatConstants.INVALID_ID;
971 } catch (InterruptedException | ExecutionException e) {
972 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
974 return NatConstants.INVALID_ID;
977 public static Integer releaseId(IdManagerService idManager, String poolName, String idKey) {
978 ReleaseIdInput idInput = new ReleaseIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
980 Future<RpcResult<ReleaseIdOutput>> result = idManager.releaseId(idInput);
981 if (result == null || result.get() == null || !result.get().isSuccessful()) {
982 LOG.error("releaseId: RPC Call to release Id from pool {} with key {} returned with Errors {}",
984 (result != null && result.get() != null) ? result.get().getErrors() : "RpcResult is null");
988 } catch (InterruptedException | ExecutionException e) {
989 LOG.error("releaseId: Exception when releasing Id for key {} from pool {}", idKey, poolName, e);
991 return NatConstants.INVALID_ID;
994 // TODO Clean up the exception handling
995 @SuppressWarnings("checkstyle:IllegalCatch")
996 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
997 String rd, String prefix, String vpnName) {
999 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
1000 fibManager.removeFibEntry(rd, prefix, null);
1001 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
1002 bgpManager.withdrawPrefix(rd, prefix);
1004 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
1005 } catch (Exception e) {
1006 LOG.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
1007 rd, prefix, vpnName, e);
1012 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
1013 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1014 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
1017 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
1018 return InstanceIdentifier.builder(IntextIpPortMap.class)
1019 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
1022 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
1023 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
1024 return InstanceIdentifier.builder(IntextIpMap.class)
1025 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
1026 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
1027 .intext.ip.map.IpMappingKey(routerId))
1032 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
1033 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1034 .ip.map.IpMapping> ipMappingOptional =
1035 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1036 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1037 // Ensure there are no duplicates
1038 Collection<String> externalIps = new HashSet<>();
1039 if (ipMappingOptional.isPresent()) {
1040 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1041 externalIps.add(ipMap.getExternalIp());
1048 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
1049 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1050 if (routerData != null) {
1051 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
1058 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
1059 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1060 .ip.map.IpMapping> ipMappingOptional =
1061 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1062 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1063 Map<String, Long> externalIpsLabel = new HashMap<>();
1064 if (ipMappingOptional.isPresent()) {
1065 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1066 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1069 return externalIpsLabel;
1073 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
1074 String leastLoadedExternalIp = null;
1075 InstanceIdentifier<ExternalCounters> id =
1076 InstanceIdentifier.builder(ExternalIpsCounter.class)
1077 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1078 Optional<ExternalCounters> externalCountersData =
1079 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1080 if (externalCountersData.isPresent()) {
1081 ExternalCounters externalCounter = externalCountersData.get();
1082 short countOfLstLoadExtIp = 32767;
1083 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1084 String curExternalIp = externalIpCounter.getExternalIp();
1085 short countOfCurExtIp = externalIpCounter.getCounter();
1086 if (countOfCurExtIp < countOfLstLoadExtIp) {
1087 countOfLstLoadExtIp = countOfCurExtIp;
1088 leastLoadedExternalIp = curExternalIp;
1092 return leastLoadedExternalIp;
1095 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1097 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1098 String subnetIP = getSubnetIp(dataBroker, subnetId);
1099 if (subnetIP != null) {
1100 return getSubnetIpAndPrefix(subnetIP);
1102 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1107 public static String[] getSubnetIpAndPrefix(String subnetString) {
1108 String[] subnetSplit = subnetString.split("/");
1109 String subnetIp = subnetSplit[0];
1110 String subnetPrefix = "0";
1111 if (subnetSplit.length == 2) {
1112 subnetPrefix = subnetSplit[1];
1114 return new String[] {subnetIp, subnetPrefix};
1118 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1119 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1120 .builder(Subnetmaps.class)
1121 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1123 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1124 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1127 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1128 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1129 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1130 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1131 if (leastLoadedExtIpAddrSplit.length == 2) {
1132 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1134 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1138 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1139 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1140 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1141 Optional<RouterDpnList> routerDpnListData =
1142 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1143 LogicalDatastoreType.OPERATIONAL, id);
1144 List<BigInteger> dpns = new ArrayList<>();
1145 if (routerDpnListData.isPresent()) {
1146 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1147 dpns.add(dpnVpnInterface.getDpnId());
1153 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1154 long bgpVpnId = NatConstants.INVALID_ID;
1155 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1156 if (bgpVpnUuid != null) {
1157 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1162 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1163 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1164 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1165 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1168 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1169 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1170 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1171 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1172 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1173 .RouterInterface.class,
1174 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1175 .RouterInterfaceKey(interfaceName)).build();
1178 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1179 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1181 if (dpId.equals(BigInteger.ZERO)) {
1182 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1183 + "to handle router {} association model", interfaceName, routerName);
1187 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1188 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1189 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1191 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1192 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1193 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1194 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1195 .setInterface(interfaceName).build();
1196 if (optionalDpnVpninterfacesList.isPresent()) {
1197 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1198 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1199 operTx.merge(dpnVpnInterfacesListIdentifier
1200 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1201 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1202 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1204 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1205 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1206 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1207 routerDpnListBuilder.setRouterId(routerName);
1208 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1209 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1210 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1211 routerInterfaces.add(routerInterface);
1212 dpnVpnList.setRouterInterfaces(routerInterfaces);
1213 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1214 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1218 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1219 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1220 if (dpId.equals(BigInteger.ZERO)) {
1221 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1222 + "association model", interfaceName, routerName);
1226 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1227 + "DPNRouters map", dpId, routerName, interfaceName);
1228 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1230 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1232 if (optionalDpnRoutersList.isPresent()) {
1233 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1234 .setRouter(routerName).build();
1235 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1236 if (!routersListFromDs.contains(routersList)) {
1237 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1238 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1239 operTx.merge(dpnRoutersListIdentifier
1240 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1242 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1243 + "DPNRouters map", routerName, dpId);
1246 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1247 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1248 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1249 dpnRoutersListBuilder.setDpnId(dpId);
1250 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1251 routersListBuilder.setRouter(routerName);
1252 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1253 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1257 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1258 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1259 if (dpId.equals(BigInteger.ZERO)) {
1260 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1264 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1265 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1266 if (optionalRouterDpnList.isPresent()) {
1267 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1268 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1269 operTx.delete(routerDpnListIdentifier);
1271 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1272 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1276 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1277 BigInteger dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1278 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1279 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1281 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1282 } catch (InterruptedException | ExecutionException e) {
1283 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1284 optionalRouterDpnList = Optional.absent();
1286 if (optionalRouterDpnList.isPresent()) {
1287 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1288 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1289 optionalRouterDpnList.get().getRouterInterfaces();
1290 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1291 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1292 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1293 .setInterface(vpnInterfaceName).build();
1295 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1296 if (routerInterfaces.isEmpty()) {
1297 operTx.delete(routerDpnListIdentifier);
1299 operTx.delete(routerDpnListIdentifier.child(
1300 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1301 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1302 new RouterInterfacesKey(vpnInterfaceName)));
1308 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1309 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1310 throws ExecutionException, InterruptedException {
1312 1) Get the DpnRoutersList for the DPN.
1313 2) Get the RoutersList identifier for the DPN and router.
1314 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1315 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1316 then remove RouterList.
1319 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1320 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1322 //Get the dpn-routers-list instance for the current DPN.
1323 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1324 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1326 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1327 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1328 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1332 //Get the routers-list instance for the router on the current DPN only
1333 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1334 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1336 if (routersListData == null || !routersListData.isPresent()) {
1337 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1338 + "in the ODL-L3VPN:dpn-routers model",
1343 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1344 + "from the NeutronVPN - router-interfaces-map", routerName);
1345 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1346 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1347 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1348 .RouterInterfaces> routerInterfacesData =
1349 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1350 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1352 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1353 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1354 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1355 curDpnId, routerName, routerName);
1356 operTx.delete(routersListIdentifier);
1360 //Get the VM interfaces for the router on the current DPN only.
1361 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1362 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1363 if (vmInterfaces == null) {
1364 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1365 + "NeutronVPN - router-interfaces-map", routerName);
1369 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1370 // then remove RouterList.
1371 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1372 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1373 String vmInterfaceName = vmInterface.getInterfaceId();
1374 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1375 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1376 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1377 + "the DPN ID {} for the checked interface {}",
1378 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1381 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1382 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1383 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1387 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1388 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1389 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1390 operTx.delete(routersListIdentifier);
1393 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1394 return InstanceIdentifier.builder(DpnRouters.class)
1395 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1396 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1399 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1400 BigInteger nodeId = BigInteger.ZERO;
1402 GetDpidFromInterfaceInput
1404 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1405 Future<RpcResult<GetDpidFromInterfaceOutput>>
1407 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1408 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1409 if (dpIdResult.isSuccessful()) {
1410 nodeId = dpIdResult.getResult().getDpid();
1412 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1414 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1415 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1421 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1422 ItmRpcService itmRpcService,
1423 IInterfaceManager interfaceManager, String ifName,
1424 Long tunnelKey, boolean internalTunnelInterface) {
1425 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1426 ifName, tunnelKey, 0, internalTunnelInterface);
1430 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1431 ItmRpcService itmRpcService,
1432 IInterfaceManager interfaceManager,
1433 String ifName, @Nullable Long tunnelKey, int pos,
1434 boolean internalTunnelInterface) {
1435 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1436 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1437 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1438 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1439 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1440 if (tunnelKey != null) {
1441 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1442 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1443 } //init builders, ITM/IFM rpc can be called based on type of interface
1446 List<Action> actions = emptyList();
1447 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1448 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1449 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1450 if (!rpcResult.isSuccessful()) {
1451 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1452 + "returned with Errors {}", ifName, rpcResult.getErrors());
1454 actions = rpcResult.getResult().nonnullAction();
1457 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1458 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1459 if (!rpcResult.isSuccessful()) {
1460 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1461 + "returned with Errors {}", ifName, rpcResult.getErrors());
1463 actions = rpcResult.getResult().nonnullAction();
1466 List<ActionInfo> listActionInfo = new ArrayList<>();
1467 for (Action action : actions) {
1468 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1469 actionClass = action.getAction();
1470 if (actionClass instanceof OutputActionCase) {
1471 listActionInfo.add(new ActionOutput(pos++,
1472 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1473 } else if (actionClass instanceof PushVlanActionCase) {
1474 listActionInfo.add(new ActionPushVlan(pos++));
1475 } else if (actionClass instanceof SetFieldCase) {
1476 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1477 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1478 .getVlanId().getValue();
1479 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1481 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1482 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1483 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1484 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1485 NxRegLoad nxRegLoad =
1486 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1487 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1488 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1491 return listActionInfo;
1492 } catch (InterruptedException | ExecutionException e) {
1493 LOG.error("Exception when egress actions for interface {}", ifName, e);
1495 LOG.error("Error when getting egress actions for interface {}", ifName);
1500 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1501 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1505 public static List<Port> getNeutronPorts(DataBroker broker) {
1506 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1507 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1508 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1509 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1511 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1512 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1514 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1515 LOG.error("getNeutronPorts : No neutron ports found");
1519 return portsOptional.get().getPort();
1523 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1524 List<Port> ports = getNeutronPorts(
1527 for (Port port : ports) {
1528 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1529 for (FixedIps ip : port.getFixedIps()) {
1530 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1536 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1541 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1543 LOG.error("getSubnetIdForFloatingIp : port is null");
1546 for (FixedIps ip : port.nonnullFixedIps()) {
1547 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1548 return ip.getSubnetId();
1551 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1556 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1557 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1558 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1559 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1560 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1564 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1565 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1566 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1567 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1568 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1573 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1574 if (subnetId == null) {
1575 LOG.error("getSubnetGwMac : subnetID is null");
1579 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1580 .child(Subnet.class, new SubnetKey(subnetId));
1581 Optional<Subnet> subnetOpt =
1582 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1583 LogicalDatastoreType.CONFIGURATION, subnetInst);
1584 if (!subnetOpt.isPresent()) {
1585 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1589 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1590 if (gatewayIp == null) {
1591 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1595 if (null != gatewayIp.getIpv6Address()) {
1599 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1600 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1602 Optional<VpnPortipToPort> portIpToPortOpt =
1603 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1604 LogicalDatastoreType.CONFIGURATION, portIpInst);
1605 if (portIpToPortOpt.isPresent()) {
1606 return portIpToPortOpt.get().getMacAddress();
1609 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1610 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1612 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1613 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1614 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1615 if (learntIpToPortOpt.isPresent()) {
1616 return learntIpToPortOpt.get().getMacAddress();
1619 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1623 public static boolean isIPv6Subnet(String prefix) {
1624 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1627 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1628 return InstanceIdentifier.builder(DpnRouters.class)
1629 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1632 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1633 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1634 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1635 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1638 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1639 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1640 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1644 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1645 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1646 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1647 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1648 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1652 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1653 Uuid floatingIpId) {
1655 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1656 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1657 } catch (InterruptedException | ExecutionException e) {
1658 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1664 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1665 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1666 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1667 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1668 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1672 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1673 Uuid floatingIpId) {
1675 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1676 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1677 } catch (InterruptedException | ExecutionException e) {
1678 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1683 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1684 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1685 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1689 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1690 InstanceIdentifier<Interface> ifStateId =
1691 buildStateInterfaceId(interfaceName);
1692 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1693 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1696 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1697 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1698 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1699 .interfaces.rev140508.InterfacesState.class)
1700 .child(Interface.class,
1701 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1702 .interfaces.state.InterfaceKey(interfaceName));
1703 return idBuilder.build();
1707 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1708 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1709 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1710 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1714 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1716 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1717 } catch (InterruptedException | ExecutionException e) {
1718 LOG.error("Error reading router {}", routerName, e);
1723 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1724 if (routerId == NatConstants.INVALID_ID) {
1725 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1728 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1729 .setRouterId(routerId).setRouterName(routerName).build();
1730 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1734 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1735 IdManagerService idManager) {
1736 InetAddress defaultIP = null;
1738 defaultIP = InetAddress.getByName("0.0.0.0");
1739 } catch (UnknownHostException e) {
1740 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1741 + "Default Route to NAT.", e);
1745 List<MatchInfo> matches = new ArrayList<>();
1746 matches.add(MatchEthernetType.IPV4);
1747 //add match for vrfid
1748 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1750 List<InstructionInfo> instructions = new ArrayList<>();
1751 List<ActionInfo> actionsInfo = new ArrayList<>();
1752 long groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(subnetId));
1753 if (groupId == NatConstants.INVALID_ID) {
1754 LOG.error("Unable to get groupId for subnet {} while building defauly flow entity", subnetId);
1757 actionsInfo.add(new ActionGroup(groupId));
1758 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1759 instructions.add(new InstructionApplyActions(actionsInfo));
1760 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1761 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1762 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1766 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1767 String routerName = getRouterName(broker, routerId);
1768 if (routerName == null) {
1769 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1772 return getExtGwMacAddFromRouterName(broker, routerName);
1776 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1777 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1778 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1779 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1783 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1785 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1786 Routers::getExtGwMacAddress).orElse(null);
1787 } catch (InterruptedException | ExecutionException e) {
1788 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1793 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1794 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1795 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1796 .child(Router.class, new RouterKey(routerUuid));
1797 return routerInstanceIdentifier;
1801 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1802 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1803 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1804 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1809 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1810 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1811 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1812 LogicalDatastoreType.CONFIGURATION,
1813 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1817 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1818 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1819 Optional<ExternalNetworks> externalNwData =
1820 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1821 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1822 if (externalNwData.isPresent()) {
1823 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1824 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1825 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1826 return routerIds != null ? routerIds : emptyList();
1833 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1836 long ipLo = ipToLong(InetAddress.getByName(start));
1837 long ipHi = ipToLong(InetAddress.getByName(end));
1838 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1839 return ipToTest >= ipLo && ipToTest <= ipHi;
1840 } catch (UnknownHostException e) {
1841 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1847 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1848 if (externalIps == null) {
1849 return Collections.emptySet();
1852 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1856 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1857 if (routerName == null) {
1858 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1859 return Collections.emptySet();
1862 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1863 Optional<Routers> routerData =
1864 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1865 LogicalDatastoreType.CONFIGURATION, id);
1866 if (routerData.isPresent()) {
1867 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1869 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1870 return Collections.emptySet();
1875 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1876 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1877 if (subnetId == null) {
1878 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1879 return Optional.absent();
1882 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1883 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1884 InstanceIdentifier.builder(ExternalSubnets.class)
1885 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1886 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1887 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1888 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1892 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1893 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1894 if (subnetId == null) {
1895 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1896 return Optional.absent();
1899 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1900 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1901 InstanceIdentifier.builder(ExternalSubnets.class)
1902 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1903 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1905 return tx.read(subnetsIdentifier).get();
1906 } catch (InterruptedException | ExecutionException e) {
1907 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1908 return Optional.absent();
1912 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1913 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1914 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1916 if (optionalExternalSubnets.isPresent()) {
1917 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1920 return NatConstants.INVALID_ID;
1923 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1924 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1925 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1927 if (optionalExternalSubnets.isPresent()) {
1928 return NatUtil.getVpnId(tx, subnetId.getValue());
1931 return NatConstants.INVALID_ID;
1934 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1936 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1937 if (externalSubnetId != null) {
1938 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1941 return NatConstants.INVALID_ID;
1945 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1946 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1947 for (ExternalIps extIp : router.nonnullExternalIps()) {
1948 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1949 if (extIpString.equals(externalIpAddress)) {
1950 return extIp.getSubnetId();
1953 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1957 private static long ipToLong(InetAddress ip) {
1958 byte[] octets = ip.getAddress();
1960 for (byte octet : octets) {
1962 result |= octet & 0xff;
1968 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1969 if (externalIps == null) {
1973 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1976 // elan-instances config container
1978 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1979 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1980 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1981 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1985 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1987 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1988 } catch (InterruptedException | ExecutionException e) {
1989 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1994 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1995 return InstanceIdentifier.builder(ElanInstances.class)
1996 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1999 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
2000 IElanService elanManager, IdManagerService idManager,
2001 long routerId, String routerName) {
2002 if (elanManager.isOpenStackVniSemanticsEnforced()) {
2003 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
2004 return natOverVxlanUtil.getRouterVni(routerName, routerId).longValue();
2006 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
2010 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
2011 short tableId, TypedWriteTransaction<Configuration> confTx) {
2012 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2013 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
2015 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
2016 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
2017 List<MatchInfo> matches = new ArrayList<>();
2018 matches.add(MatchEthernetType.IPV4);
2019 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2020 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
2021 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
2022 matches, preDnatToSnatInstructions);
2024 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
2025 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
2026 preDnatToSnatTableFlowEntity, naptDpnId);
2029 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
2030 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
2031 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
2032 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
2033 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
2034 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
2035 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
2036 flowRef, naptDpnId);
2039 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
2040 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
2041 + NwConstants.FLOWID_SEPARATOR + uniqueId;
2044 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
2045 String vpnName, String externalIp,
2046 Boolean isMoreThanOneFipCheckOnDpn) {
2047 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
2048 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
2049 if (dpnInVpn.isPresent()) {
2050 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2051 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2053 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2054 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2055 int floatingIpPresentCount = 0;
2056 for (IpAddresses ipAddress: ipAddressList) {
2057 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2058 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2059 floatingIpPresentCount++;
2060 //Add tunnel table check
2061 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2064 //Remove tunnel table check
2065 if (!isMoreThanOneFipCheckOnDpn) {
2071 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2075 } catch (NullPointerException e) {
2076 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2077 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2084 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
2085 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2086 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2087 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2091 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2092 throws ExecutionException, InterruptedException {
2093 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2097 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2098 if (vpnInstance == null) {
2101 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2102 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2105 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2106 return InstanceIdentifier.builder(VpnInstances.class)
2107 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2111 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2112 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2113 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2114 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2117 public static String validateAndAddNetworkMask(String ipAddress) {
2118 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2121 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2122 String vpnInterfaceName, String vpnName) {
2123 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2124 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2127 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2128 String routerName, BigInteger dpnId) {
2129 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2130 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2132 if (networkData != null && networkData.isPresent()) {
2133 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2134 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2135 for (Uuid routerUuid : routerUuidList) {
2136 String sharedRouterName = routerUuid.getValue();
2137 if (!routerName.equals(sharedRouterName)) {
2138 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2139 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2140 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2141 + "associated with other active router {} on NAPT switch {}", networkId,
2142 sharedRouterName, switchDpnId);
2152 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2153 String routerName, BigInteger dpnId) {
2154 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2155 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2156 .subnets.Subnets::getRouterIds).orElse(emptyList());
2157 if (!routerUuidList.isEmpty()) {
2158 for (Uuid routerUuid : routerUuidList) {
2159 String sharedRouterName = routerUuid.getValue();
2160 if (!routerName.equals(sharedRouterName)) {
2161 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2162 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2163 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2164 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2165 sharedRouterName, switchDpnId);
2174 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2175 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2176 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2177 List<ExternalIps> externalIps = router.getExternalIps();
2178 List<String> externalIpsSting = new ArrayList<>();
2180 if (externalIps == null || externalIps.isEmpty()) {
2181 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2184 for (ExternalIps externalIp : externalIps) {
2185 externalIpsSting.add(externalIp.getIpAddress());
2187 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2188 if (addOrRemove == NwConstants.ADD_FLOW) {
2189 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2190 router.getNetworkId(), subnetVpnName.getValue(), tx);
2191 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2192 router.getExtGwMacAddress(), primarySwitchId,
2193 router.getNetworkId());
2195 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2196 router.getNetworkId(), subnetVpnName.getValue(), tx);
2197 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2198 router.getExtGwMacAddress(), primarySwitchId,
2199 router.getNetworkId());
2201 }), LOG, "Error installing router gateway flows");
2204 @SuppressWarnings("checkstyle:IllegalCatch")
2205 public static void handleSNATForDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2206 IdManagerService idManager, NaptSwitchHA naptSwitchHA,
2207 BigInteger dpnId, Routers extRouters, long routerId, Long routerVpnId,
2208 TypedReadWriteTransaction<Configuration> confTx,
2209 ProviderTypes extNwProvType, UpgradeState upgradeState) {
2210 //Check if primary and secondary switch are selected, If not select the role
2211 //Install select group to NAPT switch
2212 //Install default miss entry to NAPT switch
2213 BigInteger naptSwitch;
2214 String routerName = extRouters.getRouterName();
2215 Boolean upgradeInProgress = false;
2216 if (upgradeState != null) {
2217 upgradeInProgress = upgradeState.isUpgradeInProgress();
2219 BigInteger naptId = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2220 if (naptId == null || naptId.equals(BigInteger.ZERO)
2221 || (!NatUtil.getSwitchStatus(dataBroker, naptId) && (upgradeInProgress == false))) {
2222 LOG.debug("handleSNATForDPN : NaptSwitch is down or not selected for router {},naptId {}",
2223 routerName, naptId);
2225 boolean naptstatus = naptSwitchHA.updateNaptSwitch(routerName, naptSwitch);
2227 LOG.error("handleSNATForDPN : Failed to update newNaptSwitch {} for routername {}",
2228 naptSwitch, routerName);
2231 LOG.debug("handleSNATForDPN : Switch {} is elected as NaptSwitch for router {}", dpnId, routerName);
2233 String externalVpnName = null;
2234 NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
2235 naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
2236 Uuid extNwUuid = extRouters.getNetworkId();
2237 externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNwUuid);
2238 if (externalVpnName != null) {
2239 naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, extNwUuid,
2240 externalVpnName, confTx);
2242 // Install miss entry (table 26) pointing to table 46
2243 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
2244 routerVpnId, NatConstants.ADD_FLOW);
2245 if (flowEntity == null) {
2246 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}",
2250 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
2251 mdsalManager.addFlow(confTx, flowEntity);
2252 //Removing primary flows from old napt switch
2253 if (naptId != null && !naptId.equals(BigInteger.ZERO)) {
2254 LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
2255 naptId, routerName);
2257 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptId, null,
2258 externalVpnName, confTx);
2259 } catch (Exception e) {
2260 LOG.error("Exception while removing SnatFlows form OldNaptSwitch {}", naptId, e);
2263 naptSwitchHA.updateNaptSwitchBucketStatus(routerName, routerId, naptSwitch);
2264 } else if (naptId.equals(dpnId)) {
2265 LOG.error("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
2267 naptSwitch = naptId;
2268 LOG.debug("handleSNATForDPN : Napt switch with Id {} is already elected for router {}",
2269 naptId, routerName);
2272 List<BucketInfo> bucketInfo = naptSwitchHA.handleGroupInNeighborSwitches(dpnId,
2273 routerName, routerId, naptSwitch);
2274 naptSwitchHA.installSnatGroupEntry(dpnId, bucketInfo, routerName);
2276 // Install miss entry (table 26) pointing to group
2277 long groupId = NatUtil.getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME,
2278 NatUtil.getGroupIdKey(routerName));
2279 if (groupId != NatConstants.INVALID_ID) {
2280 FlowEntity flowEntity =
2281 naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId,
2282 routerVpnId, NatConstants.ADD_FLOW);
2283 if (flowEntity == null) {
2284 LOG.error("handleSNATForDPN : Failed to populate flowentity for router {} with dpnId {}"
2285 + " groupId {}", routerName, dpnId, groupId);
2288 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
2289 dpnId, routerName, groupId);
2290 mdsalManager.addFlow(confTx, flowEntity);
2292 LOG.error("handleSNATForDPN: Unable to get groupId for router:{}", routerName);
2297 @SuppressWarnings("checkstyle:IllegalCatch")
2298 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2299 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2300 String routerName, long routerId, long routerVpnId, Uuid extNetworkId,
2301 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2302 throws ExecutionException, InterruptedException {
2303 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2304 //remove miss entry to NAPT switch
2305 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2306 if (extNwProvType == null) {
2309 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2310 Map<String, Long> externalIpLabel;
2311 if (extNwProvType == ProviderTypes.VXLAN) {
2312 externalIpLabel = null;
2314 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2316 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2317 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2318 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2321 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2322 boolean naptStatus =
2323 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2324 externalIpCache, confTx);
2326 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2328 long groupId = getUniqueId(idManager, NatConstants.SNAT_IDPOOL_NAME, NatUtil.getGroupIdKey(routerName));
2329 FlowEntity flowEntity = null;
2331 if (groupId != NatConstants.INVALID_ID) {
2332 flowEntity = naptSwitchHA
2333 .buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2334 NatConstants.DEL_FLOW);
2335 if (flowEntity == null) {
2336 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2337 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2340 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}",
2342 mdsalManager.removeFlow(confTx, flowEntity);
2344 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2347 } catch (Exception ex) {
2348 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2352 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2356 GroupEntity groupEntity = null;
2358 if (groupId != NatConstants.INVALID_ID) {
2359 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2360 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2361 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2362 mdsalManager.removeGroup(groupEntity);
2364 LOG.error("removeSNATFromDPN: Unable to get groupId for router:{}", routerName);
2366 } catch (Exception ex) {
2367 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2370 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2373 String externalVpnName = NatUtil.getAssociatedVPN(dataBroker, extNetworkId);
2374 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2375 externalIpLabel, externalVpnName, confTx);
2376 //remove table 26 flow ppointing to table46
2377 FlowEntity flowEntity = null;
2379 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2380 NatConstants.DEL_FLOW);
2381 if (flowEntity == null) {
2382 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2386 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2387 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2388 mdsalManager.removeFlow(confTx, flowEntity);
2390 } catch (Exception ex) {
2391 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2395 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2398 //best effort to check IntExt model
2399 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2403 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2404 ProviderTypes extNwProvType) {
2405 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2406 || extNwProvType == ProviderTypes.VXLAN)) {
2412 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2413 BigInteger dpnId, DataBroker dataBroker) {
2414 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2415 elanInstanceName, dpnId);
2416 // FIXME: separate this out?
2417 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2420 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2421 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2422 List<String> elanInterfaceList;
2423 DpnInterfaces dpnInterface;
2424 if (!dpnInElanInterfaces.isPresent()) {
2425 elanInterfaceList = new ArrayList<>();
2427 dpnInterface = dpnInElanInterfaces.get();
2428 elanInterfaceList = dpnInterface.getInterfaces();
2430 if (!elanInterfaceList.contains(pseudoPortId)) {
2431 elanInterfaceList.add(pseudoPortId);
2432 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2433 .withKey(new DpnInterfacesKey(dpnId)).build();
2434 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2435 elanDpnInterfaceId, dpnInterface);
2437 } catch (ReadFailedException e) {
2438 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2439 } catch (TransactionCommitFailedException e) {
2440 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2446 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2447 BigInteger dpnId, DataBroker dataBroker) {
2448 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2449 elanInstanceName, dpnId);
2450 // FIXME: separate this out?
2451 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2454 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2455 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2456 List<String> elanInterfaceList;
2457 DpnInterfaces dpnInterface;
2458 if (!dpnInElanInterfaces.isPresent()) {
2459 LOG.info("No interface in any dpn for {}", elanInstanceName);
2463 dpnInterface = dpnInElanInterfaces.get();
2464 elanInterfaceList = dpnInterface.getInterfaces();
2465 if (!elanInterfaceList.contains(pseudoPortId)) {
2466 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2469 elanInterfaceList.remove(pseudoPortId);
2470 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2471 .withKey(new DpnInterfacesKey(dpnId)).build();
2472 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2473 elanDpnInterfaceId, dpnInterface);
2474 } catch (ReadFailedException e) {
2475 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2476 } catch (TransactionCommitFailedException e) {
2477 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2483 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2484 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2485 for (Map.Entry<String,Routers> router : extRouter) {
2486 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2487 .equals(networkid)) {
2495 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2497 return SingleTransactionDataBroker.syncRead(dataBroker,
2498 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2500 catch (ReadFailedException e) {
2501 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2506 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2507 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2508 .builder(LearntVpnVipToPortData.class).build();
2509 return learntVpnVipToPortDataId;
2512 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2514 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2515 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2516 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2519 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2520 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2521 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2522 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2525 public static void createGroupIdPool(IdManagerService idManager) {
2526 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2527 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2528 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2529 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2532 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2533 if (result != null && result.get().isSuccessful()) {
2534 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2536 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2538 } catch (InterruptedException | ExecutionException e) {
2539 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2543 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2544 NodeId nodeId = new NodeId("openflow:" + switchId);
2545 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2546 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2547 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2548 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2549 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2550 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2551 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2552 if (nodeOptional.isPresent()) {
2553 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2556 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2560 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2561 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2562 Optional<Networks> networkData =
2563 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2564 broker, LogicalDatastoreType.CONFIGURATION, id);
2565 return networkData.isPresent();
2569 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2570 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2571 if (null != elanInstance) {
2572 return elanInstance.getPhysicalNetworkName();
2578 public static Map<String, String> getOpenvswitchOtherConfigMap(BigInteger dpnId, DataBroker dataBroker) {
2579 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2580 return getMultiValueMap(otherConfigVal);
2583 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2584 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2585 return Collections.emptyMap();
2588 Map<String, String> valueMap = new HashMap<>();
2589 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2590 for (String keyValue : splitter.split(multiKeyValueStr)) {
2591 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2592 if (split.length == 2) {
2593 valueMap.put(split[0], split[1]);
2600 public static Optional<Node> getBridgeRefInfo(BigInteger dpnId, DataBroker dataBroker) {
2601 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2602 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2604 Optional<BridgeRefEntry> bridgeRefEntry =
2605 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2606 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2607 if (!bridgeRefEntry.isPresent()) {
2608 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2609 return Optional.absent();
2612 InstanceIdentifier<Node> nodeId =
2613 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2615 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2616 LogicalDatastoreType.OPERATIONAL, nodeId);
2620 public static String getProviderMappings(BigInteger dpId, DataBroker dataBroker) {
2621 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2622 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2626 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2627 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2628 if (ovsdbNode == null) {
2629 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2630 if (nodeFromReadOvsdbNode.isPresent()) {
2631 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2635 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2636 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2637 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2638 return openvswitchOtherConfigs.getOtherConfigValue();
2642 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2647 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2648 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2649 if (bridgeAugmentation != null) {
2650 InstanceIdentifier<Node> ovsdbNodeIid =
2651 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2652 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2653 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2655 return Optional.absent();
2660 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2664 return node.augmentation(OvsdbBridgeAugmentation.class);
2667 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
2668 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2671 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2672 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2673 InstanceIdentifier.builder(ExternalSubnets.class)
2676 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2677 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2678 if (optionalExternalSubnets.isPresent()) {
2679 return optionalExternalSubnets.get();
2681 } catch (ReadFailedException e) {
2682 LOG.error("Failed to read the subnets from the datastore.");
2688 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2689 BigInteger dpId, short tableId, String flowId, int priority, String flowName, BigInteger cookie,
2690 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2691 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2692 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2694 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2695 mdsalManager.addFlow(confTx, flowEntity);
2698 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2699 BigInteger dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2700 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2701 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2704 public static String getIpv6FlowRef(BigInteger dpnId, short tableId, long routerID) {
2705 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2706 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2709 public static String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId,
2710 ItmRpcService itmManager) {
2711 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2712 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2714 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2715 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2716 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2717 rpcResult = result.get();
2718 if (!rpcResult.isSuccessful()) {
2719 tunType = TunnelTypeGre.class ;
2720 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2721 .setSourceDpid(srcDpId)
2722 .setDestinationDpid(dstDpId)
2723 .setTunnelType(tunType)
2725 rpcResult = result.get();
2726 if (!rpcResult.isSuccessful()) {
2727 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2728 rpcResult.getErrors());
2730 return rpcResult.getResult().getInterfaceName();
2732 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2733 rpcResult.getErrors());
2735 return rpcResult.getResult().getInterfaceName();
2737 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2738 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2739 + "between {} and {}", srcDpId, dstDpId);
2744 public static Boolean isRouterInterfacePort(DataBroker broker, String ifaceName) {
2745 Port neutronPort = getNeutronPort(broker, ifaceName);
2746 if (neutronPort == null) {
2747 return Boolean.TRUE;
2749 return (NatConstants.NETWORK_ROUTER_INTERFACE.equalsIgnoreCase(neutronPort.getDeviceOwner()) ? Boolean.TRUE
2754 private static Port getNeutronPort(DataBroker broker, String ifaceName) {
2755 InstanceIdentifier<Port>
2756 portsIdentifier = InstanceIdentifier.create(Neutron.class)
2757 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class)
2758 .child(Port.class, new PortKey(new Uuid(ifaceName)));
2759 Optional<Port> portsOptional;
2761 portsOptional = SingleTransactionDataBroker
2762 .syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
2763 } catch (ReadFailedException e) {
2764 LOG.error("Read Failed Exception While Reading Neutron Port for {}", ifaceName, e);
2765 portsOptional = Optional.absent();
2767 if (!portsOptional.isPresent()) {
2768 LOG.error("getNeutronPort : No neutron ports found for interface {}", ifaceName);
2771 return portsOptional.get();
2774 static ReentrantLock lockForNat(final BigInteger dataPath) {
2775 // FIXME: wrap this in an Identifier
2776 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
2779 public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
2780 IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
2781 String interfaceName, String routerName) {
2782 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
2783 if (routerId == NatConstants.INVALID_ID) {
2784 LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
2787 BigInteger naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
2788 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2789 LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
2790 + "with Id {}", routerName, routerId);
2793 //getInternalIp for port
2794 List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
2795 if (fixedIps == null) {
2796 LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
2797 interfaceName, routerName, routerId);
2800 List<ProtocolTypes> protocolTypesList = getPortocolList();
2801 for (String internalIp : fixedIps) {
2802 LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
2803 interfaceName, internalIp, routerId);
2804 for (ProtocolTypes protocol : protocolTypesList) {
2805 List<Integer> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
2806 if (portList != null) {
2807 for (Integer portnum : portList) {
2808 //build and remove the flow in outbound table
2809 removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
2810 routerId, internalIp, portnum, protocol.getName());
2812 //build and remove the flow in inboundtable
2814 removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
2815 internalIp, portnum, protocol.getName());
2817 //Get the external IP address and the port from the model
2819 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
2820 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
2821 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
2822 internalIp, String.valueOf(portnum), proto);
2823 if (ipPortExternal == null) {
2824 LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
2825 + "with port {} is not found in "
2826 + "router with Id {}", internalIp, portnum, routerId);
2829 String externalIpAddress = ipPortExternal.getIpAddress();
2830 String internalIpPort = internalIp + ":" + portnum;
2831 // delete the entry from IntExtIpPortMap DS
2833 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
2834 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
2838 LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
2839 + "in router with id {}",
2840 protocol, interfaceName, internalIp, routerId);
2843 // delete the entry from SnatIntIpPortMap DS
2844 LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
2845 internalIp, routerId);
2846 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
2850 private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
2851 LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
2853 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
2854 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
2855 .setPortId(new Uuid(interfname)).build());
2857 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
2858 if (!rpcResult.isSuccessful()) {
2859 LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
2860 rpcResult.getErrors());
2862 return rpcResult.getResult().getFixedIPs();
2864 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
2865 LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
2870 private static List<ProtocolTypes> getPortocolList() {
2871 List<ProtocolTypes> protocollist = new ArrayList<>();
2872 protocollist.add(ProtocolTypes.TCP);
2873 protocollist.add(ProtocolTypes.UDP);
2874 return protocollist;
2877 private static void removeNatFlow(IMdsalApiManager mdsalManager, BigInteger dpnId, short tableId, Long routerId,
2878 String ipAddress, int ipPort, String protocol) {
2880 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
2882 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
2884 mdsalManager.removeFlow(snatFlowEntity);
2885 LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
2886 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
2889 public static String getDpnFromNodeRef(NodeRef node) {
2890 PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
2891 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
2892 InstanceIdentifier.IdentifiableItem.class);
2893 NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
2894 String dpnKey = key.getId().getValue();
2895 String dpnID = null;
2896 if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
2897 dpnID = new BigInteger(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();