2 * Copyright © 2016, 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.natservice.internal;
11 import static java.util.Collections.emptyList;
12 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
13 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
15 import com.google.common.base.Optional;
16 import com.google.common.base.Preconditions;
17 import com.google.common.base.Splitter;
18 import com.google.common.base.Strings;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import java.math.BigInteger;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Objects;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.locks.ReentrantLock;
35 import java.util.stream.Collectors;
36 import javax.annotation.Nonnull;
37 import javax.annotation.Nullable;
38 import org.apache.commons.net.util.SubnetUtils;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
41 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
42 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
43 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
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.FlowEntity;
54 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
55 import org.opendaylight.genius.mdsalutil.GroupEntity;
56 import org.opendaylight.genius.mdsalutil.InstructionInfo;
57 import org.opendaylight.genius.mdsalutil.MDSALUtil;
58 import org.opendaylight.genius.mdsalutil.MatchInfo;
59 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
60 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
61 import org.opendaylight.genius.mdsalutil.NwConstants;
62 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
63 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
64 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
65 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
66 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
67 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
68 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
69 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
70 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
71 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
72 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
73 import org.opendaylight.genius.utils.JvmGlobalLocks;
74 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
75 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
76 import org.opendaylight.netvirt.elanmanager.api.IElanService;
77 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
78 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
79 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
80 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
81 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
82 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
83 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
84 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
87 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
88 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
89 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
221 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;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
257 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;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
262 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
263 import org.opendaylight.yangtools.yang.binding.DataObject;
264 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
265 import org.opendaylight.yangtools.yang.common.RpcResult;
266 import org.slf4j.Logger;
267 import org.slf4j.LoggerFactory;
269 public final class NatUtil {
271 private static String OF_URI_SEPARATOR = ":";
272 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
273 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
274 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
275 private static final String PROVIDER_MAPPINGS = "provider_mappings";
277 private NatUtil() { }
280 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
283 public static BigInteger getCookieSnatFlow(long routerId) {
284 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
285 BigInteger.valueOf(routerId));
289 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
292 public static BigInteger getCookieNaptFlow(long routerId) {
293 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
294 BigInteger.valueOf(routerId));
298 getVpnId() returns the VPN ID from the VPN name
300 public static long getVpnId(DataBroker broker, @Nullable String vpnName) {
301 if (vpnName == null) {
302 return NatConstants.INVALID_ID;
305 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
306 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
307 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
308 .instance.to.vpn.id.VpnInstance> vpnInstance =
309 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
310 LogicalDatastoreType.CONFIGURATION, id);
312 long vpnId = NatConstants.INVALID_ID;
313 if (vpnInstance.isPresent()) {
314 Long vpnIdAsLong = vpnInstance.get().getVpnId();
315 if (vpnIdAsLong != null) {
322 public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
323 if (vpnName == null) {
324 return NatConstants.INVALID_ID;
328 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
329 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
330 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
331 } catch (InterruptedException | ExecutionException e) {
332 LOG.error("Error retrieving VPN id for {}", vpnName, e);
335 return NatConstants.INVALID_ID;
338 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
339 //Get the external network ID from the ExternalRouter model
340 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
341 if (networkId == null) {
342 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
343 return NatConstants.INVALID_ID;
346 //Get the VPN ID from the ExternalNetworks model
347 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
348 if (vpnUuid == null) {
349 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
350 return NatConstants.INVALID_ID;
352 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
356 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
357 return InstanceIdentifier.builder(FloatingIpInfo.class)
358 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
361 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
362 return InstanceIdentifier.builder(RouterToVpnMapping.class)
363 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
366 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
367 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
368 .child(Ports.class, new PortsKey(portName)).build();
371 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
373 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
374 .child(Ports.class, new PortsKey(portName))
375 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
378 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
379 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
380 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
381 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
382 .instance.to.vpn.id.VpnInstance.class,
383 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
384 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
388 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
389 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
390 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
391 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
392 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
396 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
398 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
399 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
400 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
403 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
404 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
405 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
408 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
409 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
410 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
415 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
416 String routerName = getRouterName(broker, routerId);
417 if (routerName == null) {
418 LOG.error("getNetworkIdFromRouterId - empty routerName received");
421 return getNetworkIdFromRouterName(broker, routerName);
425 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
426 if (routerName == null) {
427 LOG.error("getNetworkIdFromRouterName - empty routerName received");
430 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
431 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
432 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
435 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
436 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
437 .child(Routers.class, new RoutersKey(routerId)).build();
438 return routerInstanceIndentifier;
441 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
442 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
443 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
448 * Return if SNAT is enabled for the given router.
450 * @param broker The DataBroker
451 * @param routerId The router
452 * @return boolean true if enabled, otherwise false
454 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
455 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
456 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
457 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
461 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
462 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
463 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
464 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
468 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
470 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
471 } catch (InterruptedException | ExecutionException e) {
472 LOG.error("Error reading network VPN id for {}", networkId, e);
478 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
479 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
480 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
481 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
485 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
486 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
488 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
489 } catch (InterruptedException | ExecutionException e) {
490 LOG.error("Error retrieving provider type for {}", networkId, e);
496 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
497 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
498 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
499 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse(
504 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
505 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
506 Optional<Routers> routerData =
507 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
508 LogicalDatastoreType.CONFIGURATION, id);
509 if (routerData.isPresent()) {
510 Uuid networkId = routerData.get().getNetworkId();
511 if (networkId != null) {
512 return networkId.getValue();
515 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
519 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
520 return InstanceIdentifier.builder(ExternalNetworks.class)
521 .child(Networks.class, new NetworksKey(networkId)).build();
525 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
526 // convert routerId to Name
527 String routerName = getRouterName(broker, routerId);
528 if (routerName == null) {
529 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
532 return getPrimaryNaptfromRouterName(broker, routerName);
536 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
537 if (routerName == null) {
538 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
541 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
542 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
543 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
547 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
548 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
549 new RouterToNaptSwitchKey(routerId)).build();
552 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
553 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
554 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
558 public static String getRouterName(DataBroker broker, Long routerId) {
559 return getVpnInstanceFromVpnIdentifier(broker, routerId);
562 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
563 return InstanceIdentifier.builder(VpnInstanceOpData.class)
564 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
567 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
568 return new FlowEntityBuilder()
576 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
577 return new FlowEntityBuilder()
584 public static long getIpAddress(byte[] rawIpAddress) {
585 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
586 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
590 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
591 String nextHopIp = null;
592 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
593 InstanceIdentifier.builder(DpnEndpoints.class)
594 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
595 Optional<DPNTEPsInfo> tunnelInfo =
596 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
597 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
598 if (tunnelInfo.isPresent()) {
599 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
600 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
601 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
608 public static String getVpnRd(DataBroker broker, String vpnName) {
609 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
610 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
611 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
612 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
613 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
614 .VpnInstance::getVrfId).orElse(null);
618 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
620 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
621 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
622 .VpnInstance::getVrfId).orElse(null);
623 } catch (InterruptedException | ExecutionException e) {
624 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
630 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
631 String internalPort, NAPTEntryEvent.Protocol protocol) {
632 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
633 InstanceIdentifier<IpPortMap> ipPortMapId =
634 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
635 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
636 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
640 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
642 ProtocolTypes protocolType) {
643 return InstanceIdentifier.builder(IntextIpPortMap.class)
644 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
645 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
646 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
649 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
650 return InstanceIdentifier.builder(VpnInterfaces.class)
651 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
655 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
656 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
657 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
658 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
662 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
664 * NodeConnectorId is of form 'openflow:dpnid:portnum'
666 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
667 if (split.length != 3) {
668 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
674 public static BigInteger getDpIdFromInterface(
675 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
676 .state.Interface ifState) {
677 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
678 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
679 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
684 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
685 // returns only router, attached to IPv4 networks
686 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
687 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
688 Optional<VpnMap> optionalVpnMap =
689 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
690 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
691 if (!optionalVpnMap.isPresent()) {
692 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
695 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
696 if (routerIdsList != null && !routerIdsList.isEmpty()) {
697 for (Uuid routerUuid : routerIdsList) {
698 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
699 Optional<Routers> routerData =
700 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
701 LogicalDatastoreType.CONFIGURATION, id);
702 if (routerData.isPresent()) {
703 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
704 for (Uuid subnetUuid : subnetIdsList) {
705 String subnetIp = getSubnetIp(broker, subnetUuid);
706 SubnetUtils subnet = new SubnetUtils(subnetIp);
707 if (subnet.getInfo().isInRange(ipAddress)) {
708 return routerUuid.getValue();
714 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
719 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
720 Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
721 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
722 Optional<VpnMaps> optionalVpnMaps =
723 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
724 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
725 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
726 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap()) {
727 if (routerId.equals(vpnMap.getVpnId().getValue())) {
730 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
731 if (routerIdsList.isEmpty()) {
734 // Skip router vpnId fetching from internet BGP-VPN
735 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
736 // We only need to check the first network; if it’s not an external network there’s no
737 // need to check the rest of the VPN’s network list
738 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
742 if (routerIdsList.contains(new Uuid(routerId))) {
743 return vpnMap.getVpnId();
747 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
751 static long getAssociatedVpn(DataBroker broker, String routerName) {
752 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
753 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
754 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
755 NatConstants.INVALID_ID);
759 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
760 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
761 if (vpnUuid == null) {
762 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
765 return vpnUuid.getValue();
769 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
770 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
771 if (vpnUuid == null) {
772 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
775 return vpnUuid.getValue();
778 // TODO Clean up the exception handling
779 @SuppressWarnings("checkstyle:IllegalCatch")
780 public static void addPrefixToBGP(DataBroker broker,
781 IBgpManager bgpManager,
782 IFibManager fibManager,
787 @Nullable String parentVpnRd,
788 @Nullable String macAddress,
794 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
795 prefix, nextHopIp, label);
796 if (nextHopIp == null) {
797 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
802 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
803 dpId, Prefixes.PrefixCue.Nat);
804 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
805 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
806 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
807 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
808 /* Publish to Bgp only if its an INTERNET VPN */
809 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
810 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
811 null /*gatewayMac*/);
813 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
814 prefix, nextHopIp, label);
815 } catch (Exception e) {
816 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
817 prefix, nextHopIp, label, e);
821 static void addPrefixToInterface(DataBroker broker, long vpnId, @Nullable String interfaceName, String ipPrefix,
822 String networkId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
823 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
824 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
825 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
826 .to._interface.VpnIdsKey(vpnId))
827 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
828 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
829 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
830 prefixBuilder.setNetworkId(new Uuid(networkId));
832 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
833 prefixBuilder.build());
834 } catch (TransactionCommitFailedException e) {
835 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
836 ipPrefix, vpnId, dpId, e);
840 public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
842 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
843 InstanceIdentifier.builder(PrefixToInterface.class)
844 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
845 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
846 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
848 } catch (TransactionCommitFailedException e) {
849 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
854 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
855 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
856 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
860 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
861 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
862 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
863 return routerInstanceIndentifier;
867 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
868 String internalIpAddress, ProtocolTypes protocolType) {
869 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
870 LogicalDatastoreType.CONFIGURATION,
871 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
872 IntIpProtoType::getPorts).orElse(emptyList());
875 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
876 String internalIpAddress,
877 ProtocolTypes protocolType) {
878 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
879 InstanceIdentifier.builder(SnatintIpPortMap.class)
880 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
881 .child(IpPort.class, new IpPortKey(internalIpAddress))
882 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
883 return intIpProtocolTypeId;
886 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
887 String internalIpAddress) {
888 InstanceIdentifier<IpPort> intIpProtocolTypeId =
889 InstanceIdentifier.builder(SnatintIpPortMap.class)
890 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
891 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
892 return intIpProtocolTypeId;
896 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
897 String internalIpAddress) {
898 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
899 LogicalDatastoreType.CONFIGURATION,
900 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
903 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
904 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
905 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
909 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
910 return InstanceIdentifier.create(NaptSwitches.class);
913 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
914 return InstanceIdentifier.create(NaptSwitches.class)
915 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
918 public static String getGroupIdKey(String routerName) {
919 return "snatmiss." + routerName;
922 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
923 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
924 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
927 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
928 RpcResult<AllocateIdOutput> rpcResult = result.get();
929 return rpcResult.getResult().getIdValue();
930 } catch (NullPointerException | InterruptedException | ExecutionException e) {
931 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
936 // TODO Clean up the exception handling
937 @SuppressWarnings("checkstyle:IllegalCatch")
938 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
939 String rd, String prefix, String vpnName, Logger log) {
941 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
942 fibManager.removeFibEntry(rd, prefix, null);
943 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
944 bgpManager.withdrawPrefix(rd, prefix);
946 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
947 } catch (Exception e) {
948 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
949 rd, prefix, vpnName, e);
954 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
955 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
956 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
959 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
960 return InstanceIdentifier.builder(IntextIpPortMap.class)
961 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
964 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
965 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
966 return InstanceIdentifier.builder(IntextIpMap.class)
967 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
968 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
969 .intext.ip.map.IpMappingKey(routerId))
974 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
975 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
976 .ip.map.IpMapping> ipMappingOptional =
977 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
978 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
979 // Ensure there are no duplicates
980 Collection<String> externalIps = new HashSet<>();
981 if (ipMappingOptional.isPresent()) {
982 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
983 externalIps.add(ipMap.getExternalIp());
990 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
991 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
992 if (routerData != null) {
993 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
1000 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
1001 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1002 .ip.map.IpMapping> ipMappingOptional =
1003 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1004 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1005 Map<String, Long> externalIpsLabel = new HashMap<>();
1006 if (ipMappingOptional.isPresent()) {
1007 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
1008 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1011 return externalIpsLabel;
1015 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
1016 String leastLoadedExternalIp = null;
1017 InstanceIdentifier<ExternalCounters> id =
1018 InstanceIdentifier.builder(ExternalIpsCounter.class)
1019 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1020 Optional<ExternalCounters> externalCountersData =
1021 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1022 if (externalCountersData.isPresent()) {
1023 ExternalCounters externalCounter = externalCountersData.get();
1024 short countOfLstLoadExtIp = 32767;
1025 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1026 String curExternalIp = externalIpCounter.getExternalIp();
1027 short countOfCurExtIp = externalIpCounter.getCounter();
1028 if (countOfCurExtIp < countOfLstLoadExtIp) {
1029 countOfLstLoadExtIp = countOfCurExtIp;
1030 leastLoadedExternalIp = curExternalIp;
1034 return leastLoadedExternalIp;
1037 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1039 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1040 String subnetIP = getSubnetIp(dataBroker, subnetId);
1041 if (subnetIP != null) {
1042 return getSubnetIpAndPrefix(subnetIP);
1044 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1049 public static String[] getSubnetIpAndPrefix(String subnetString) {
1050 String[] subnetSplit = subnetString.split("/");
1051 String subnetIp = subnetSplit[0];
1052 String subnetPrefix = "0";
1053 if (subnetSplit.length == 2) {
1054 subnetPrefix = subnetSplit[1];
1056 return new String[] {subnetIp, subnetPrefix};
1060 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1061 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1062 .builder(Subnetmaps.class)
1063 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1065 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1066 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1069 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1070 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1071 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1072 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1073 if (leastLoadedExtIpAddrSplit.length == 2) {
1074 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1076 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1080 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1081 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1082 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1083 Optional<RouterDpnList> routerDpnListData =
1084 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1085 LogicalDatastoreType.OPERATIONAL, id);
1086 List<BigInteger> dpns = new ArrayList<>();
1087 if (routerDpnListData.isPresent()) {
1088 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1089 dpns.add(dpnVpnInterface.getDpnId());
1095 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1096 long bgpVpnId = NatConstants.INVALID_ID;
1097 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1098 if (bgpVpnUuid != null) {
1099 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1105 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1106 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1107 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1108 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1111 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1112 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1113 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1114 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1115 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1116 .RouterInterface.class,
1117 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1118 .RouterInterfaceKey(interfaceName)).build();
1121 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1122 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1124 if (dpId.equals(BigInteger.ZERO)) {
1125 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1126 + "to handle router {} association model", interfaceName, routerName);
1130 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1131 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1132 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1134 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1135 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1136 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1137 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1138 .setInterface(interfaceName).build();
1139 if (optionalDpnVpninterfacesList.isPresent()) {
1140 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1141 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1142 operTx.merge(dpnVpnInterfacesListIdentifier
1143 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1144 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1145 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1147 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1148 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1149 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1150 routerDpnListBuilder.setRouterId(routerName);
1151 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1152 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1153 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1154 routerInterfaces.add(routerInterface);
1155 dpnVpnList.setRouterInterfaces(routerInterfaces);
1156 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1157 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1161 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1162 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1163 if (dpId.equals(BigInteger.ZERO)) {
1164 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1165 + "association model", interfaceName, routerName);
1169 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1170 + "DPNRouters map", dpId, routerName, interfaceName);
1171 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1173 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1175 if (optionalDpnRoutersList.isPresent()) {
1176 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1177 .setRouter(routerName).build();
1178 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1179 if (!routersListFromDs.contains(routersList)) {
1180 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1181 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1182 operTx.merge(dpnRoutersListIdentifier
1183 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1185 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1186 + "DPNRouters map", routerName, dpId);
1189 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1190 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1191 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1192 dpnRoutersListBuilder.setDpnId(dpId);
1193 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1194 routersListBuilder.setRouter(routerName);
1195 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1196 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1200 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1201 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1202 if (dpId.equals(BigInteger.ZERO)) {
1203 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1207 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1208 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1209 if (optionalRouterDpnList.isPresent()) {
1210 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1211 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1212 operTx.delete(routerDpnListIdentifier);
1214 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1215 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1219 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1220 BigInteger dpId, @Nonnull TypedReadWriteTransaction<Operational> operTx) {
1221 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1222 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1224 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1225 } catch (InterruptedException | ExecutionException e) {
1226 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1227 optionalRouterDpnList = Optional.absent();
1229 if (optionalRouterDpnList.isPresent()) {
1230 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1231 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1232 optionalRouterDpnList.get().getRouterInterfaces();
1233 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1234 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1235 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1236 .setInterface(vpnInterfaceName).build();
1238 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1239 if (routerInterfaces.isEmpty()) {
1240 operTx.delete(routerDpnListIdentifier);
1242 operTx.delete(routerDpnListIdentifier.child(
1243 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1244 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1245 new RouterInterfacesKey(vpnInterfaceName)));
1251 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1252 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1253 throws ExecutionException, InterruptedException {
1255 1) Get the DpnRoutersList for the DPN.
1256 2) Get the RoutersList identifier for the DPN and router.
1257 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1258 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1259 then remove RouterList.
1262 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1263 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1265 //Get the dpn-routers-list instance for the current DPN.
1266 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1267 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1269 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1270 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1271 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1275 //Get the routers-list instance for the router on the current DPN only
1276 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1277 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1279 if (routersListData == null || !routersListData.isPresent()) {
1280 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1281 + "in the ODL-L3VPN:dpn-routers model",
1286 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1287 + "from the NeutronVPN - router-interfaces-map", routerName);
1288 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1289 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1290 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1291 .RouterInterfaces> routerInterfacesData =
1292 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1293 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1295 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1296 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1297 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1298 curDpnId, routerName, routerName);
1299 operTx.delete(routersListIdentifier);
1303 //Get the VM interfaces for the router on the current DPN only.
1304 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1305 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1306 if (vmInterfaces == null) {
1307 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1308 + "NeutronVPN - router-interfaces-map", routerName);
1312 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1313 // then remove RouterList.
1314 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1315 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1316 String vmInterfaceName = vmInterface.getInterfaceId();
1317 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1318 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1319 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1320 + "the DPN ID {} for the checked interface {}",
1321 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1324 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1325 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1326 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1330 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1331 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1332 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1333 operTx.delete(routersListIdentifier);
1336 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1337 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1338 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1339 .rev150602.RouterInterfacesMap.class)
1340 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1341 .interfaces.map.RouterInterfaces.class,
1342 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1343 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1346 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1347 return InstanceIdentifier.builder(DpnRouters.class)
1348 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1349 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1352 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1353 BigInteger nodeId = BigInteger.ZERO;
1355 GetDpidFromInterfaceInput
1357 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1358 Future<RpcResult<GetDpidFromInterfaceOutput>>
1360 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1361 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1362 if (dpIdResult.isSuccessful()) {
1363 nodeId = dpIdResult.getResult().getDpid();
1365 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1367 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1368 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1374 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1375 ItmRpcService itmRpcService,
1376 IInterfaceManager interfaceManager, String ifName,
1377 Long tunnelKey, boolean internalTunnelInterface) {
1378 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1379 ifName, tunnelKey, 0, internalTunnelInterface);
1383 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1384 ItmRpcService itmRpcService,
1385 IInterfaceManager interfaceManager,
1386 String ifName, @Nullable Long tunnelKey, int pos,
1387 boolean internalTunnelInterface) {
1388 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1389 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1390 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1391 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1392 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1393 if (tunnelKey != null) {
1394 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1395 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1396 } //init builders, ITM/IFM rpc can be called based on type of interface
1399 List<Action> actions = emptyList();
1400 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1401 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1402 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1403 if (!rpcResult.isSuccessful()) {
1404 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1405 + "returned with Errors {}", ifName, rpcResult.getErrors());
1407 actions = rpcResult.getResult().nonnullAction();
1410 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1411 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1412 if (!rpcResult.isSuccessful()) {
1413 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1414 + "returned with Errors {}", ifName, rpcResult.getErrors());
1416 actions = rpcResult.getResult().nonnullAction();
1419 List<ActionInfo> listActionInfo = new ArrayList<>();
1420 for (Action action : actions) {
1421 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1422 actionClass = action.getAction();
1423 if (actionClass instanceof OutputActionCase) {
1424 listActionInfo.add(new ActionOutput(pos++,
1425 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1426 } else if (actionClass instanceof PushVlanActionCase) {
1427 listActionInfo.add(new ActionPushVlan(pos++));
1428 } else if (actionClass instanceof SetFieldCase) {
1429 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1430 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1431 .getVlanId().getValue();
1432 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1434 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1435 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1436 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1437 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1438 NxRegLoad nxRegLoad =
1439 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1440 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1441 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1444 return listActionInfo;
1445 } catch (InterruptedException | ExecutionException e) {
1446 LOG.error("Exception when egress actions for interface {}", ifName, e);
1448 LOG.error("Error when getting egress actions for interface {}", ifName);
1453 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1454 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1458 public static List<Port> getNeutronPorts(DataBroker broker) {
1459 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1460 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1461 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1462 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1464 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1465 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1467 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1468 LOG.error("getNeutronPorts : No neutron ports found");
1472 return portsOptional.get().getPort();
1476 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1477 List<Port> ports = getNeutronPorts(
1480 for (Port port : ports) {
1481 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1482 for (FixedIps ip : port.getFixedIps()) {
1483 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1489 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1494 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1496 LOG.error("getSubnetIdForFloatingIp : port is null");
1499 for (FixedIps ip : port.nonnullFixedIps()) {
1500 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1501 return ip.getSubnetId();
1504 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1509 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1510 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1511 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1512 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1513 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1517 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1518 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1519 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1520 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1521 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1526 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1527 if (subnetId == null) {
1528 LOG.error("getSubnetGwMac : subnetID is null");
1532 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1533 .child(Subnet.class, new SubnetKey(subnetId));
1534 Optional<Subnet> subnetOpt =
1535 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1536 LogicalDatastoreType.CONFIGURATION, subnetInst);
1537 if (!subnetOpt.isPresent()) {
1538 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1542 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1543 if (gatewayIp == null) {
1544 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1548 if (null != gatewayIp.getIpv6Address()) {
1552 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1553 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1555 Optional<VpnPortipToPort> portIpToPortOpt =
1556 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1557 LogicalDatastoreType.CONFIGURATION, portIpInst);
1558 if (portIpToPortOpt.isPresent()) {
1559 return portIpToPortOpt.get().getMacAddress();
1562 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1563 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1565 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1566 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1567 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1568 if (learntIpToPortOpt.isPresent()) {
1569 return learntIpToPortOpt.get().getMacAddress();
1572 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1576 public static boolean isIPv6Subnet(String prefix) {
1577 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1580 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1581 return InstanceIdentifier.builder(DpnRouters.class)
1582 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1585 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1586 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1587 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1588 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1591 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1592 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1593 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1597 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1598 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1599 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1600 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1601 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1605 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1606 Uuid floatingIpId) {
1608 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1609 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1610 } catch (InterruptedException | ExecutionException e) {
1611 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1617 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1618 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1619 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1620 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1621 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1625 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1626 Uuid floatingIpId) {
1628 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1629 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1630 } catch (InterruptedException | ExecutionException e) {
1631 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1636 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1637 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1638 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1642 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1643 InstanceIdentifier<Interface> ifStateId =
1644 buildStateInterfaceId(interfaceName);
1645 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1646 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1649 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1650 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1651 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1652 .interfaces.rev140508.InterfacesState.class)
1653 .child(Interface.class,
1654 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1655 .interfaces.state.InterfaceKey(interfaceName));
1656 return idBuilder.build();
1660 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1661 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1662 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1663 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1667 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1669 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1670 } catch (InterruptedException | ExecutionException e) {
1671 LOG.error("Error reading router {}", routerName, e);
1676 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1677 if (routerId == NatConstants.INVALID_ID) {
1678 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1681 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1682 .setRouterId(routerId).setRouterName(routerName).build();
1683 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1687 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1688 IdManagerService idManager) {
1689 InetAddress defaultIP = null;
1691 defaultIP = InetAddress.getByName("0.0.0.0");
1692 } catch (UnknownHostException e) {
1693 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1694 + "Default Route to NAT.", e);
1698 List<MatchInfo> matches = new ArrayList<>();
1699 matches.add(MatchEthernetType.IPV4);
1700 //add match for vrfid
1701 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1703 List<InstructionInfo> instructions = new ArrayList<>();
1704 List<ActionInfo> actionsInfo = new ArrayList<>();
1705 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1706 actionsInfo.add(new ActionGroup(groupId));
1707 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1708 instructions.add(new InstructionApplyActions(actionsInfo));
1709 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1710 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1711 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1715 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1716 String routerName = getRouterName(broker, routerId);
1717 if (routerName == null) {
1718 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1721 return getExtGwMacAddFromRouterName(broker, routerName);
1725 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1726 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1727 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1728 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1732 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1734 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1735 Routers::getExtGwMacAddress).orElse(null);
1736 } catch (InterruptedException | ExecutionException e) {
1737 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1742 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1743 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1744 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1745 .child(Router.class, new RouterKey(routerUuid));
1746 return routerInstanceIdentifier;
1750 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1751 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1752 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1753 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1758 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1759 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1760 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1761 LogicalDatastoreType.CONFIGURATION,
1762 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1766 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1767 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1768 Optional<ExternalNetworks> externalNwData =
1769 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1770 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1771 if (externalNwData.isPresent()) {
1772 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1773 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1774 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1775 return routerIds != null ? routerIds : emptyList();
1782 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1785 long ipLo = ipToLong(InetAddress.getByName(start));
1786 long ipHi = ipToLong(InetAddress.getByName(end));
1787 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1788 return ipToTest >= ipLo && ipToTest <= ipHi;
1789 } catch (UnknownHostException e) {
1790 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1796 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1797 if (externalIps == null) {
1798 return Collections.emptySet();
1801 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1805 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1806 if (routerName == null) {
1807 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1808 return Collections.emptySet();
1811 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1812 Optional<Routers> routerData =
1813 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1814 LogicalDatastoreType.CONFIGURATION, id);
1815 if (routerData.isPresent()) {
1816 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1818 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1819 return Collections.emptySet();
1824 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1825 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1826 if (subnetId == null) {
1827 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1828 return Optional.absent();
1831 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1832 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1833 InstanceIdentifier.builder(ExternalSubnets.class)
1834 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1835 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1836 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1837 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1841 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1842 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1843 if (subnetId == null) {
1844 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1845 return Optional.absent();
1848 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1849 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1850 InstanceIdentifier.builder(ExternalSubnets.class)
1851 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1852 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1854 return tx.read(subnetsIdentifier).get();
1855 } catch (InterruptedException | ExecutionException e) {
1856 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1857 return Optional.absent();
1861 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1862 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1863 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1865 if (optionalExternalSubnets.isPresent()) {
1866 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1869 return NatConstants.INVALID_ID;
1872 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1873 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1874 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1876 if (optionalExternalSubnets.isPresent()) {
1877 return NatUtil.getVpnId(tx, subnetId.getValue());
1880 return NatConstants.INVALID_ID;
1883 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1885 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1886 if (externalSubnetId != null) {
1887 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1890 return NatConstants.INVALID_ID;
1894 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1895 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1896 for (ExternalIps extIp : router.nonnullExternalIps()) {
1897 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1898 if (extIpString.equals(externalIpAddress)) {
1899 return extIp.getSubnetId();
1902 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1906 private static long ipToLong(InetAddress ip) {
1907 byte[] octets = ip.getAddress();
1909 for (byte octet : octets) {
1911 result |= octet & 0xff;
1917 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1918 if (externalIps == null) {
1922 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1925 // elan-instances config container
1927 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1928 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1929 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1930 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1934 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1936 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1937 } catch (InterruptedException | ExecutionException e) {
1938 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1943 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1944 return InstanceIdentifier.builder(ElanInstances.class)
1945 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1948 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
1949 IElanService elanManager, IdManagerService idManager,
1950 long routerId, String routerName) {
1951 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1952 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1953 return natOverVxlanUtil.getRouterVni(routerName, routerId).longValue();
1955 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1959 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1960 short tableId, TypedWriteTransaction<Configuration> confTx) {
1961 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1962 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1964 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1965 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1966 List<MatchInfo> matches = new ArrayList<>();
1967 matches.add(MatchEthernetType.IPV4);
1968 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1969 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1970 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1971 matches, preDnatToSnatInstructions);
1973 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
1974 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1975 preDnatToSnatTableFlowEntity, naptDpnId);
1978 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
1979 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
1980 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1981 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1982 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1983 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
1984 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1985 flowRef, naptDpnId);
1988 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1989 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1990 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1993 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1994 String vpnName, String externalIp,
1995 Boolean isMoreThanOneFipCheckOnDpn) {
1996 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1997 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1998 if (dpnInVpn.isPresent()) {
1999 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2000 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2002 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2003 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2004 int floatingIpPresentCount = 0;
2005 for (IpAddresses ipAddress: ipAddressList) {
2006 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2007 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2008 floatingIpPresentCount++;
2009 //Add tunnel table check
2010 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2013 //Remove tunnel table check
2014 if (!isMoreThanOneFipCheckOnDpn) {
2020 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2024 } catch (NullPointerException e) {
2025 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2026 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2033 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
2034 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2035 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2036 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2040 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2041 throws ExecutionException, InterruptedException {
2042 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2045 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
2046 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
2047 Optional<VpnInstance> vpnInstance =
2048 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2049 LogicalDatastoreType.CONFIGURATION, id);
2050 if (vpnInstance.isPresent()) {
2051 return getPrimaryRd(vpnInstance.get());
2057 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2058 if (vpnInstance == null) {
2061 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2062 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2065 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2066 return InstanceIdentifier.builder(VpnInstances.class)
2067 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2071 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2072 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2073 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2074 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2077 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
2078 if (routerName != null) {
2079 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
2080 if (extRouter != null) {
2081 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
2085 return NatConstants.INVALID_ID;
2088 public static String validateAndAddNetworkMask(String ipAddress) {
2089 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2092 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2093 String vpnInterfaceName, String vpnName) {
2094 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2095 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2099 public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
2100 InstanceIdentifier<VpnInstanceOpDataEntry> id = NatUtil.getVpnInstanceOpDataIdentifier(rd);
2101 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2102 broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
2105 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2106 String routerName, BigInteger dpnId) {
2107 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2108 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2110 if (networkData != null && networkData.isPresent()) {
2111 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2112 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2113 for (Uuid routerUuid : routerUuidList) {
2114 String sharedRouterName = routerUuid.getValue();
2115 if (!routerName.equals(sharedRouterName)) {
2116 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2117 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2118 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2119 + "associated with other active router {} on NAPT switch {}", networkId,
2120 sharedRouterName, switchDpnId);
2130 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2131 String routerName, BigInteger dpnId) {
2132 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2133 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2134 .subnets.Subnets::getRouterIds).orElse(emptyList());
2135 if (!routerUuidList.isEmpty()) {
2136 for (Uuid routerUuid : routerUuidList) {
2137 String sharedRouterName = routerUuid.getValue();
2138 if (!routerName.equals(sharedRouterName)) {
2139 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2140 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2141 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2142 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2143 sharedRouterName, switchDpnId);
2152 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2153 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2154 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2155 List<ExternalIps> externalIps = router.getExternalIps();
2156 List<String> externalIpsSting = new ArrayList<>();
2158 if (externalIps == null || externalIps.isEmpty()) {
2159 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2162 for (ExternalIps externalIp : externalIps) {
2163 externalIpsSting.add(externalIp.getIpAddress());
2165 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2166 if (addOrRemove == NwConstants.ADD_FLOW) {
2167 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2168 router.getNetworkId(), subnetVpnName.getValue(), tx);
2169 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2170 router.getExtGwMacAddress(), primarySwitchId,
2171 router.getNetworkId());
2173 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2174 router.getNetworkId(), subnetVpnName.getValue(), tx);
2175 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2176 router.getExtGwMacAddress(), primarySwitchId,
2177 router.getNetworkId());
2179 }), LOG, "Error installing router gateway flows");
2182 @SuppressWarnings("checkstyle:IllegalCatch")
2183 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2184 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2185 String routerName, long routerId, long routerVpnId,
2186 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2187 throws ExecutionException, InterruptedException {
2188 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2189 //remove miss entry to NAPT switch
2190 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2191 if (extNwProvType == null) {
2194 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2195 Map<String, Long> externalIpLabel;
2196 if (extNwProvType == ProviderTypes.VXLAN) {
2197 externalIpLabel = null;
2199 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2201 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2202 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2203 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2206 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2207 boolean naptStatus =
2208 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2209 externalIpCache, confTx);
2211 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2213 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
2214 FlowEntity flowEntity = null;
2216 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2217 NatConstants.DEL_FLOW);
2218 if (flowEntity == null) {
2219 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2220 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2223 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
2224 mdsalManager.removeFlow(confTx, flowEntity);
2226 } catch (Exception ex) {
2227 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2231 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2235 GroupEntity groupEntity = null;
2237 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2238 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2239 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2240 mdsalManager.removeGroup(groupEntity);
2241 } catch (Exception ex) {
2242 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2245 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2248 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2249 externalIpLabel, confTx);
2250 //remove table 26 flow ppointing to table46
2251 FlowEntity flowEntity = null;
2253 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2254 NatConstants.DEL_FLOW);
2255 if (flowEntity == null) {
2256 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2260 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2261 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2262 mdsalManager.removeFlow(confTx, flowEntity);
2264 } catch (Exception ex) {
2265 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2269 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2272 //best effort to check IntExt model
2273 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2277 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2278 ProviderTypes extNwProvType) {
2279 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2280 || extNwProvType == ProviderTypes.VXLAN)) {
2286 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2287 BigInteger dpnId, DataBroker dataBroker) {
2288 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2289 elanInstanceName, dpnId);
2290 // FIXME: separate this out?
2291 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2294 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2295 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2296 List<String> elanInterfaceList;
2297 DpnInterfaces dpnInterface;
2298 if (!dpnInElanInterfaces.isPresent()) {
2299 elanInterfaceList = new ArrayList<>();
2301 dpnInterface = dpnInElanInterfaces.get();
2302 elanInterfaceList = dpnInterface.getInterfaces();
2304 if (!elanInterfaceList.contains(pseudoPortId)) {
2305 elanInterfaceList.add(pseudoPortId);
2306 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2307 .withKey(new DpnInterfacesKey(dpnId)).build();
2308 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2309 elanDpnInterfaceId, dpnInterface);
2311 } catch (ReadFailedException e) {
2312 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2313 } catch (TransactionCommitFailedException e) {
2314 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2320 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2321 BigInteger dpnId, DataBroker dataBroker) {
2322 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2323 elanInstanceName, dpnId);
2324 // FIXME: separate this out?
2325 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2328 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2329 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2330 List<String> elanInterfaceList;
2331 DpnInterfaces dpnInterface;
2332 if (!dpnInElanInterfaces.isPresent()) {
2333 LOG.info("No interface in any dpn for {}", elanInstanceName);
2337 dpnInterface = dpnInElanInterfaces.get();
2338 elanInterfaceList = dpnInterface.getInterfaces();
2339 if (!elanInterfaceList.contains(pseudoPortId)) {
2340 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2343 elanInterfaceList.remove(pseudoPortId);
2344 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2345 .withKey(new DpnInterfacesKey(dpnId)).build();
2346 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2347 elanDpnInterfaceId, dpnInterface);
2348 } catch (ReadFailedException e) {
2349 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2350 } catch (TransactionCommitFailedException e) {
2351 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2357 public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId,
2358 DataBroker broker) {
2359 InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId =
2360 getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
2361 DpnInterfaces dpnInterfaces = null;
2363 dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL,
2364 elanDpnInterfacesId);
2366 catch (ReadFailedException e) {
2367 LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
2369 return dpnInterfaces;
2372 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
2373 InstanceIdentifier<T> path) {
2374 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
2375 return tx.read(datastoreType, path).get();
2376 } catch (InterruptedException | ExecutionException e) {
2377 throw new RuntimeException(e);
2381 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2382 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2383 for (Map.Entry<String,Routers> router : extRouter) {
2384 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2385 .equals(networkid)) {
2392 public static InstanceIdentifier<ExtRouters> buildExtRouters() {
2393 InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
2395 return extRouterInstanceIndentifier;
2399 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2401 return SingleTransactionDataBroker.syncRead(dataBroker,
2402 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2404 catch (ReadFailedException e) {
2405 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2410 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2411 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2412 .builder(LearntVpnVipToPortData.class).build();
2413 return learntVpnVipToPortDataId;
2416 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2418 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2419 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2420 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2423 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2424 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2425 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2426 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2429 public static void createGroupIdPool(IdManagerService idManager) {
2430 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2431 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2432 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2433 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2436 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2437 if (result != null && result.get().isSuccessful()) {
2438 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2440 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2442 } catch (InterruptedException | ExecutionException e) {
2443 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2447 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2448 NodeId nodeId = new NodeId("openflow:" + switchId);
2449 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2450 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2451 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2452 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2453 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2454 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2455 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2456 if (nodeOptional.isPresent()) {
2457 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2460 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2464 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2465 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2466 Optional<Networks> networkData =
2467 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2468 broker, LogicalDatastoreType.CONFIGURATION, id);
2469 return networkData.isPresent();
2473 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2474 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2475 if (null != elanInstance) {
2476 return elanInstance.getPhysicalNetworkName();
2482 public static Map<String, String> getOpenvswitchOtherConfigMap(BigInteger dpnId, DataBroker dataBroker) {
2483 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2484 return getMultiValueMap(otherConfigVal);
2487 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2488 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2489 return Collections.emptyMap();
2492 Map<String, String> valueMap = new HashMap<>();
2493 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2494 for (String keyValue : splitter.split(multiKeyValueStr)) {
2495 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2496 if (split.length == 2) {
2497 valueMap.put(split[0], split[1]);
2504 public static Optional<Node> getBridgeRefInfo(BigInteger dpnId, DataBroker dataBroker) {
2505 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2506 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2508 Optional<BridgeRefEntry> bridgeRefEntry =
2509 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2510 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2511 if (!bridgeRefEntry.isPresent()) {
2512 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2513 return Optional.absent();
2516 InstanceIdentifier<Node> nodeId =
2517 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2519 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2520 LogicalDatastoreType.OPERATIONAL, nodeId);
2524 public static String getProviderMappings(BigInteger dpId, DataBroker dataBroker) {
2525 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2526 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2530 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2531 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2532 if (ovsdbNode == null) {
2533 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2534 if (nodeFromReadOvsdbNode.isPresent()) {
2535 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2539 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2540 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2541 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2542 return openvswitchOtherConfigs.getOtherConfigValue();
2546 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2551 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2552 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2553 if (bridgeAugmentation != null) {
2554 InstanceIdentifier<Node> ovsdbNodeIid =
2555 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2556 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2557 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2559 return Optional.absent();
2564 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2568 return node.augmentation(OvsdbBridgeAugmentation.class);
2571 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
2572 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2575 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2576 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2577 InstanceIdentifier.builder(ExternalSubnets.class)
2580 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2581 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2582 if (optionalExternalSubnets.isPresent()) {
2583 return optionalExternalSubnets.get();
2585 } catch (ReadFailedException e) {
2586 LOG.error("Failed to read the subnets from the datastore.");
2592 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2593 BigInteger dpId, short tableId, String flowId, int priority, String flowName, BigInteger cookie,
2594 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2595 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2596 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2598 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2599 mdsalManager.addFlow(confTx, flowEntity);
2602 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2603 BigInteger dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2604 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2605 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2608 public static String getIpv6FlowRef(BigInteger dpnId, short tableId, long routerID) {
2609 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2610 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2613 public static String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId,
2614 ItmRpcService itmManager) {
2615 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2616 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2618 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2619 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2620 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2621 rpcResult = result.get();
2622 if (!rpcResult.isSuccessful()) {
2623 tunType = TunnelTypeGre.class ;
2624 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2625 .setSourceDpid(srcDpId)
2626 .setDestinationDpid(dstDpId)
2627 .setTunnelType(tunType)
2629 rpcResult = result.get();
2630 if (!rpcResult.isSuccessful()) {
2631 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2632 rpcResult.getErrors());
2634 return rpcResult.getResult().getInterfaceName();
2636 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2637 rpcResult.getErrors());
2639 return rpcResult.getResult().getInterfaceName();
2641 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2642 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2643 + "between {} and {}", srcDpId, dstDpId);
2648 public static String getIpv6JobKey(String routerName) {
2649 return "Ipv6." + routerName;
2652 static ReentrantLock lockForNat(final BigInteger dataPath) {
2653 // FIXME: wrap this in an Identifier
2654 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);