2 * Copyright © 2016, 2018 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.natservice.internal;
11 import static java.util.Collections.emptyList;
12 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
13 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
15 import com.google.common.base.Optional;
16 import com.google.common.base.Preconditions;
17 import com.google.common.base.Splitter;
18 import com.google.common.base.Strings;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import java.math.BigInteger;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Objects;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.locks.ReentrantLock;
35 import java.util.stream.Collectors;
36 import org.apache.commons.net.util.SubnetUtils;
37 import org.eclipse.jdt.annotation.NonNull;
38 import org.eclipse.jdt.annotation.Nullable;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.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());
1104 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1105 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1106 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1107 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1110 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1111 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1112 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1113 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1114 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1115 .RouterInterface.class,
1116 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1117 .RouterInterfaceKey(interfaceName)).build();
1120 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1121 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1123 if (dpId.equals(BigInteger.ZERO)) {
1124 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1125 + "to handle router {} association model", interfaceName, routerName);
1129 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1130 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1131 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1133 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1134 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1135 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1136 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1137 .setInterface(interfaceName).build();
1138 if (optionalDpnVpninterfacesList.isPresent()) {
1139 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1140 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1141 operTx.merge(dpnVpnInterfacesListIdentifier
1142 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1143 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1144 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1146 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1147 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1148 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1149 routerDpnListBuilder.setRouterId(routerName);
1150 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1151 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1152 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1153 routerInterfaces.add(routerInterface);
1154 dpnVpnList.setRouterInterfaces(routerInterfaces);
1155 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1156 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1160 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1161 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1162 if (dpId.equals(BigInteger.ZERO)) {
1163 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1164 + "association model", interfaceName, routerName);
1168 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1169 + "DPNRouters map", dpId, routerName, interfaceName);
1170 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1172 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1174 if (optionalDpnRoutersList.isPresent()) {
1175 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1176 .setRouter(routerName).build();
1177 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1178 if (!routersListFromDs.contains(routersList)) {
1179 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1180 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1181 operTx.merge(dpnRoutersListIdentifier
1182 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1184 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1185 + "DPNRouters map", routerName, dpId);
1188 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1189 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1190 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1191 dpnRoutersListBuilder.setDpnId(dpId);
1192 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1193 routersListBuilder.setRouter(routerName);
1194 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1195 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1199 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1200 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1201 if (dpId.equals(BigInteger.ZERO)) {
1202 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1206 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1207 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1208 if (optionalRouterDpnList.isPresent()) {
1209 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1210 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1211 operTx.delete(routerDpnListIdentifier);
1213 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1214 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1218 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1219 BigInteger dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1220 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1221 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1223 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1224 } catch (InterruptedException | ExecutionException e) {
1225 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1226 optionalRouterDpnList = Optional.absent();
1228 if (optionalRouterDpnList.isPresent()) {
1229 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1230 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1231 optionalRouterDpnList.get().getRouterInterfaces();
1232 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1233 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1234 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1235 .setInterface(vpnInterfaceName).build();
1237 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1238 if (routerInterfaces.isEmpty()) {
1239 operTx.delete(routerDpnListIdentifier);
1241 operTx.delete(routerDpnListIdentifier.child(
1242 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1243 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1244 new RouterInterfacesKey(vpnInterfaceName)));
1250 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1251 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1252 throws ExecutionException, InterruptedException {
1254 1) Get the DpnRoutersList for the DPN.
1255 2) Get the RoutersList identifier for the DPN and router.
1256 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1257 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1258 then remove RouterList.
1261 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1262 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1264 //Get the dpn-routers-list instance for the current DPN.
1265 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1266 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1268 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1269 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1270 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1274 //Get the routers-list instance for the router on the current DPN only
1275 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1276 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1278 if (routersListData == null || !routersListData.isPresent()) {
1279 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1280 + "in the ODL-L3VPN:dpn-routers model",
1285 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1286 + "from the NeutronVPN - router-interfaces-map", routerName);
1287 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1288 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1289 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1290 .RouterInterfaces> routerInterfacesData =
1291 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1292 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1294 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1295 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1296 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1297 curDpnId, routerName, routerName);
1298 operTx.delete(routersListIdentifier);
1302 //Get the VM interfaces for the router on the current DPN only.
1303 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1304 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1305 if (vmInterfaces == null) {
1306 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1307 + "NeutronVPN - router-interfaces-map", routerName);
1311 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1312 // then remove RouterList.
1313 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1314 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1315 String vmInterfaceName = vmInterface.getInterfaceId();
1316 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1317 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1318 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1319 + "the DPN ID {} for the checked interface {}",
1320 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1323 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1324 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1325 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1329 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1330 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1331 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1332 operTx.delete(routersListIdentifier);
1335 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1336 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1337 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1338 .rev150602.RouterInterfacesMap.class)
1339 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1340 .interfaces.map.RouterInterfaces.class,
1341 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1342 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1345 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1346 return InstanceIdentifier.builder(DpnRouters.class)
1347 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1348 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1351 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1352 BigInteger nodeId = BigInteger.ZERO;
1354 GetDpidFromInterfaceInput
1356 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1357 Future<RpcResult<GetDpidFromInterfaceOutput>>
1359 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1360 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1361 if (dpIdResult.isSuccessful()) {
1362 nodeId = dpIdResult.getResult().getDpid();
1364 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1366 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1367 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1373 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1374 ItmRpcService itmRpcService,
1375 IInterfaceManager interfaceManager, String ifName,
1376 Long tunnelKey, boolean internalTunnelInterface) {
1377 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1378 ifName, tunnelKey, 0, internalTunnelInterface);
1382 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1383 ItmRpcService itmRpcService,
1384 IInterfaceManager interfaceManager,
1385 String ifName, @Nullable Long tunnelKey, int pos,
1386 boolean internalTunnelInterface) {
1387 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1388 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1389 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1390 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1391 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1392 if (tunnelKey != null) {
1393 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1394 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1395 } //init builders, ITM/IFM rpc can be called based on type of interface
1398 List<Action> actions = emptyList();
1399 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1400 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1401 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1402 if (!rpcResult.isSuccessful()) {
1403 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1404 + "returned with Errors {}", ifName, rpcResult.getErrors());
1406 actions = rpcResult.getResult().nonnullAction();
1409 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1410 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1411 if (!rpcResult.isSuccessful()) {
1412 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1413 + "returned with Errors {}", ifName, rpcResult.getErrors());
1415 actions = rpcResult.getResult().nonnullAction();
1418 List<ActionInfo> listActionInfo = new ArrayList<>();
1419 for (Action action : actions) {
1420 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1421 actionClass = action.getAction();
1422 if (actionClass instanceof OutputActionCase) {
1423 listActionInfo.add(new ActionOutput(pos++,
1424 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1425 } else if (actionClass instanceof PushVlanActionCase) {
1426 listActionInfo.add(new ActionPushVlan(pos++));
1427 } else if (actionClass instanceof SetFieldCase) {
1428 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1429 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1430 .getVlanId().getValue();
1431 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1433 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1434 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1435 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1436 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1437 NxRegLoad nxRegLoad =
1438 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1439 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1440 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1443 return listActionInfo;
1444 } catch (InterruptedException | ExecutionException e) {
1445 LOG.error("Exception when egress actions for interface {}", ifName, e);
1447 LOG.error("Error when getting egress actions for interface {}", ifName);
1452 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1453 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1457 public static List<Port> getNeutronPorts(DataBroker broker) {
1458 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1459 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1460 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1461 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1463 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1464 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1466 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1467 LOG.error("getNeutronPorts : No neutron ports found");
1471 return portsOptional.get().getPort();
1475 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1476 List<Port> ports = getNeutronPorts(
1479 for (Port port : ports) {
1480 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1481 for (FixedIps ip : port.getFixedIps()) {
1482 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1488 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1493 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1495 LOG.error("getSubnetIdForFloatingIp : port is null");
1498 for (FixedIps ip : port.nonnullFixedIps()) {
1499 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1500 return ip.getSubnetId();
1503 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1508 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1509 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1510 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1511 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1512 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1516 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1517 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1518 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1519 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1520 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1525 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1526 if (subnetId == null) {
1527 LOG.error("getSubnetGwMac : subnetID is null");
1531 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1532 .child(Subnet.class, new SubnetKey(subnetId));
1533 Optional<Subnet> subnetOpt =
1534 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1535 LogicalDatastoreType.CONFIGURATION, subnetInst);
1536 if (!subnetOpt.isPresent()) {
1537 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1541 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1542 if (gatewayIp == null) {
1543 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1547 if (null != gatewayIp.getIpv6Address()) {
1551 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1552 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1554 Optional<VpnPortipToPort> portIpToPortOpt =
1555 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1556 LogicalDatastoreType.CONFIGURATION, portIpInst);
1557 if (portIpToPortOpt.isPresent()) {
1558 return portIpToPortOpt.get().getMacAddress();
1561 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1562 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1564 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1565 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1566 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1567 if (learntIpToPortOpt.isPresent()) {
1568 return learntIpToPortOpt.get().getMacAddress();
1571 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1575 public static boolean isIPv6Subnet(String prefix) {
1576 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1579 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1580 return InstanceIdentifier.builder(DpnRouters.class)
1581 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1584 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1585 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1586 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1587 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1590 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1591 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1592 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1596 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1597 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1598 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1599 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1600 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1604 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1605 Uuid floatingIpId) {
1607 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1608 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1609 } catch (InterruptedException | ExecutionException e) {
1610 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1616 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1617 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1618 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1619 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1620 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1624 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1625 Uuid floatingIpId) {
1627 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1628 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1629 } catch (InterruptedException | ExecutionException e) {
1630 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1635 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1636 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1637 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1641 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1642 InstanceIdentifier<Interface> ifStateId =
1643 buildStateInterfaceId(interfaceName);
1644 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1645 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1648 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1649 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1650 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1651 .interfaces.rev140508.InterfacesState.class)
1652 .child(Interface.class,
1653 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1654 .interfaces.state.InterfaceKey(interfaceName));
1655 return idBuilder.build();
1659 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1660 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1661 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1662 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1666 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1668 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1669 } catch (InterruptedException | ExecutionException e) {
1670 LOG.error("Error reading router {}", routerName, e);
1675 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1676 if (routerId == NatConstants.INVALID_ID) {
1677 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1680 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1681 .setRouterId(routerId).setRouterName(routerName).build();
1682 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1686 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1687 IdManagerService idManager) {
1688 InetAddress defaultIP = null;
1690 defaultIP = InetAddress.getByName("0.0.0.0");
1691 } catch (UnknownHostException e) {
1692 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1693 + "Default Route to NAT.", e);
1697 List<MatchInfo> matches = new ArrayList<>();
1698 matches.add(MatchEthernetType.IPV4);
1699 //add match for vrfid
1700 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1702 List<InstructionInfo> instructions = new ArrayList<>();
1703 List<ActionInfo> actionsInfo = new ArrayList<>();
1704 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1705 actionsInfo.add(new ActionGroup(groupId));
1706 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1707 instructions.add(new InstructionApplyActions(actionsInfo));
1708 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1709 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1710 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1714 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1715 String routerName = getRouterName(broker, routerId);
1716 if (routerName == null) {
1717 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1720 return getExtGwMacAddFromRouterName(broker, routerName);
1724 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1725 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1726 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1727 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1731 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1733 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1734 Routers::getExtGwMacAddress).orElse(null);
1735 } catch (InterruptedException | ExecutionException e) {
1736 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1741 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1742 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1743 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1744 .child(Router.class, new RouterKey(routerUuid));
1745 return routerInstanceIdentifier;
1749 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1750 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1751 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1752 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1757 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1758 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1759 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1760 LogicalDatastoreType.CONFIGURATION,
1761 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1765 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1766 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1767 Optional<ExternalNetworks> externalNwData =
1768 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1769 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1770 if (externalNwData.isPresent()) {
1771 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1772 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1773 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1774 return routerIds != null ? routerIds : emptyList();
1781 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1784 long ipLo = ipToLong(InetAddress.getByName(start));
1785 long ipHi = ipToLong(InetAddress.getByName(end));
1786 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1787 return ipToTest >= ipLo && ipToTest <= ipHi;
1788 } catch (UnknownHostException e) {
1789 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1795 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1796 if (externalIps == null) {
1797 return Collections.emptySet();
1800 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1804 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1805 if (routerName == null) {
1806 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1807 return Collections.emptySet();
1810 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1811 Optional<Routers> routerData =
1812 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1813 LogicalDatastoreType.CONFIGURATION, id);
1814 if (routerData.isPresent()) {
1815 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1817 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1818 return Collections.emptySet();
1823 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1824 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1825 if (subnetId == null) {
1826 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1827 return Optional.absent();
1830 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1831 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1832 InstanceIdentifier.builder(ExternalSubnets.class)
1833 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1834 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1835 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1836 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1840 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1841 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1842 if (subnetId == null) {
1843 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1844 return Optional.absent();
1847 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1848 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1849 InstanceIdentifier.builder(ExternalSubnets.class)
1850 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1851 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1853 return tx.read(subnetsIdentifier).get();
1854 } catch (InterruptedException | ExecutionException e) {
1855 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1856 return Optional.absent();
1860 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1861 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1862 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1864 if (optionalExternalSubnets.isPresent()) {
1865 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1868 return NatConstants.INVALID_ID;
1871 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1872 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1873 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1875 if (optionalExternalSubnets.isPresent()) {
1876 return NatUtil.getVpnId(tx, subnetId.getValue());
1879 return NatConstants.INVALID_ID;
1882 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1884 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1885 if (externalSubnetId != null) {
1886 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1889 return NatConstants.INVALID_ID;
1893 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1894 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1895 for (ExternalIps extIp : router.nonnullExternalIps()) {
1896 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1897 if (extIpString.equals(externalIpAddress)) {
1898 return extIp.getSubnetId();
1901 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1905 private static long ipToLong(InetAddress ip) {
1906 byte[] octets = ip.getAddress();
1908 for (byte octet : octets) {
1910 result |= octet & 0xff;
1916 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1917 if (externalIps == null) {
1921 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1924 // elan-instances config container
1926 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1927 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1928 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1929 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1933 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1935 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1936 } catch (InterruptedException | ExecutionException e) {
1937 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1942 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1943 return InstanceIdentifier.builder(ElanInstances.class)
1944 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1947 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
1948 IElanService elanManager, IdManagerService idManager,
1949 long routerId, String routerName) {
1950 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1951 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1952 return natOverVxlanUtil.getRouterVni(routerName, routerId).longValue();
1954 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1958 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1959 short tableId, TypedWriteTransaction<Configuration> confTx) {
1960 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1961 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1963 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1964 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1965 List<MatchInfo> matches = new ArrayList<>();
1966 matches.add(MatchEthernetType.IPV4);
1967 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1968 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1969 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1970 matches, preDnatToSnatInstructions);
1972 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
1973 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1974 preDnatToSnatTableFlowEntity, naptDpnId);
1977 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
1978 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
1979 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1980 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1981 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1982 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
1983 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1984 flowRef, naptDpnId);
1987 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1988 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1989 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1992 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1993 String vpnName, String externalIp,
1994 Boolean isMoreThanOneFipCheckOnDpn) {
1995 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1996 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1997 if (dpnInVpn.isPresent()) {
1998 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1999 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2001 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2002 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2003 int floatingIpPresentCount = 0;
2004 for (IpAddresses ipAddress: ipAddressList) {
2005 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2006 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2007 floatingIpPresentCount++;
2008 //Add tunnel table check
2009 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2012 //Remove tunnel table check
2013 if (!isMoreThanOneFipCheckOnDpn) {
2019 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2023 } catch (NullPointerException e) {
2024 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2025 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2032 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
2033 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2034 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2035 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2039 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2040 throws ExecutionException, InterruptedException {
2041 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2044 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
2045 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
2046 Optional<VpnInstance> vpnInstance =
2047 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2048 LogicalDatastoreType.CONFIGURATION, id);
2049 if (vpnInstance.isPresent()) {
2050 return getPrimaryRd(vpnInstance.get());
2056 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2057 if (vpnInstance == null) {
2060 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2061 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2064 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2065 return InstanceIdentifier.builder(VpnInstances.class)
2066 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2070 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2071 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2072 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2073 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2076 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
2077 if (routerName != null) {
2078 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
2079 if (extRouter != null) {
2080 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
2084 return NatConstants.INVALID_ID;
2087 public static String validateAndAddNetworkMask(String ipAddress) {
2088 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2091 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2092 String vpnInterfaceName, String vpnName) {
2093 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2094 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2098 public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
2099 InstanceIdentifier<VpnInstanceOpDataEntry> id = NatUtil.getVpnInstanceOpDataIdentifier(rd);
2100 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2101 broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
2104 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2105 String routerName, BigInteger dpnId) {
2106 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2107 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2109 if (networkData != null && networkData.isPresent()) {
2110 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2111 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2112 for (Uuid routerUuid : routerUuidList) {
2113 String sharedRouterName = routerUuid.getValue();
2114 if (!routerName.equals(sharedRouterName)) {
2115 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2116 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2117 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2118 + "associated with other active router {} on NAPT switch {}", networkId,
2119 sharedRouterName, switchDpnId);
2129 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2130 String routerName, BigInteger dpnId) {
2131 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2132 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2133 .subnets.Subnets::getRouterIds).orElse(emptyList());
2134 if (!routerUuidList.isEmpty()) {
2135 for (Uuid routerUuid : routerUuidList) {
2136 String sharedRouterName = routerUuid.getValue();
2137 if (!routerName.equals(sharedRouterName)) {
2138 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2139 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2140 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2141 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2142 sharedRouterName, switchDpnId);
2151 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2152 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2153 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2154 List<ExternalIps> externalIps = router.getExternalIps();
2155 List<String> externalIpsSting = new ArrayList<>();
2157 if (externalIps == null || externalIps.isEmpty()) {
2158 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2161 for (ExternalIps externalIp : externalIps) {
2162 externalIpsSting.add(externalIp.getIpAddress());
2164 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2165 if (addOrRemove == NwConstants.ADD_FLOW) {
2166 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2167 router.getNetworkId(), subnetVpnName.getValue(), tx);
2168 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2169 router.getExtGwMacAddress(), primarySwitchId,
2170 router.getNetworkId());
2172 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2173 router.getNetworkId(), subnetVpnName.getValue(), tx);
2174 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2175 router.getExtGwMacAddress(), primarySwitchId,
2176 router.getNetworkId());
2178 }), LOG, "Error installing router gateway flows");
2181 @SuppressWarnings("checkstyle:IllegalCatch")
2182 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2183 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2184 String routerName, long routerId, long routerVpnId,
2185 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2186 throws ExecutionException, InterruptedException {
2187 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2188 //remove miss entry to NAPT switch
2189 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2190 if (extNwProvType == null) {
2193 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2194 Map<String, Long> externalIpLabel;
2195 if (extNwProvType == ProviderTypes.VXLAN) {
2196 externalIpLabel = null;
2198 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2200 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2201 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2202 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2205 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2206 boolean naptStatus =
2207 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2208 externalIpCache, confTx);
2210 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2212 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
2213 FlowEntity flowEntity = null;
2215 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2216 NatConstants.DEL_FLOW);
2217 if (flowEntity == null) {
2218 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2219 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2222 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
2223 mdsalManager.removeFlow(confTx, flowEntity);
2225 } catch (Exception ex) {
2226 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2230 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2234 GroupEntity groupEntity = null;
2236 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2237 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2238 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2239 mdsalManager.removeGroup(groupEntity);
2240 } catch (Exception ex) {
2241 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2244 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2247 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2248 externalIpLabel, confTx);
2249 //remove table 26 flow ppointing to table46
2250 FlowEntity flowEntity = null;
2252 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2253 NatConstants.DEL_FLOW);
2254 if (flowEntity == null) {
2255 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2259 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2260 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2261 mdsalManager.removeFlow(confTx, flowEntity);
2263 } catch (Exception ex) {
2264 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2268 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2271 //best effort to check IntExt model
2272 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2276 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2277 ProviderTypes extNwProvType) {
2278 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2279 || extNwProvType == ProviderTypes.VXLAN)) {
2285 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2286 BigInteger dpnId, DataBroker dataBroker) {
2287 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2288 elanInstanceName, dpnId);
2289 // FIXME: separate this out?
2290 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2293 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2294 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2295 List<String> elanInterfaceList;
2296 DpnInterfaces dpnInterface;
2297 if (!dpnInElanInterfaces.isPresent()) {
2298 elanInterfaceList = new ArrayList<>();
2300 dpnInterface = dpnInElanInterfaces.get();
2301 elanInterfaceList = dpnInterface.getInterfaces();
2303 if (!elanInterfaceList.contains(pseudoPortId)) {
2304 elanInterfaceList.add(pseudoPortId);
2305 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2306 .withKey(new DpnInterfacesKey(dpnId)).build();
2307 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2308 elanDpnInterfaceId, dpnInterface);
2310 } catch (ReadFailedException e) {
2311 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2312 } catch (TransactionCommitFailedException e) {
2313 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2319 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2320 BigInteger dpnId, DataBroker dataBroker) {
2321 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2322 elanInstanceName, dpnId);
2323 // FIXME: separate this out?
2324 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2327 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2328 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2329 List<String> elanInterfaceList;
2330 DpnInterfaces dpnInterface;
2331 if (!dpnInElanInterfaces.isPresent()) {
2332 LOG.info("No interface in any dpn for {}", elanInstanceName);
2336 dpnInterface = dpnInElanInterfaces.get();
2337 elanInterfaceList = dpnInterface.getInterfaces();
2338 if (!elanInterfaceList.contains(pseudoPortId)) {
2339 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2342 elanInterfaceList.remove(pseudoPortId);
2343 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2344 .withKey(new DpnInterfacesKey(dpnId)).build();
2345 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2346 elanDpnInterfaceId, dpnInterface);
2347 } catch (ReadFailedException e) {
2348 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2349 } catch (TransactionCommitFailedException e) {
2350 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2356 public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId,
2357 DataBroker broker) {
2358 InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId =
2359 getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
2360 DpnInterfaces dpnInterfaces = null;
2362 dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL,
2363 elanDpnInterfacesId);
2365 catch (ReadFailedException e) {
2366 LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
2368 return dpnInterfaces;
2371 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
2372 InstanceIdentifier<T> path) {
2373 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
2374 return tx.read(datastoreType, path).get();
2375 } catch (InterruptedException | ExecutionException e) {
2376 throw new RuntimeException(e);
2380 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2381 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2382 for (Map.Entry<String,Routers> router : extRouter) {
2383 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2384 .equals(networkid)) {
2391 public static InstanceIdentifier<ExtRouters> buildExtRouters() {
2392 InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
2394 return extRouterInstanceIndentifier;
2398 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2400 return SingleTransactionDataBroker.syncRead(dataBroker,
2401 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2403 catch (ReadFailedException e) {
2404 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2409 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2410 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2411 .builder(LearntVpnVipToPortData.class).build();
2412 return learntVpnVipToPortDataId;
2415 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2417 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2418 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2419 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2422 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2423 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2424 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2425 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2428 public static void createGroupIdPool(IdManagerService idManager) {
2429 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2430 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2431 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2432 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2435 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2436 if (result != null && result.get().isSuccessful()) {
2437 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2439 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2441 } catch (InterruptedException | ExecutionException e) {
2442 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2446 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2447 NodeId nodeId = new NodeId("openflow:" + switchId);
2448 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2449 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2450 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2451 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2452 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2453 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2454 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2455 if (nodeOptional.isPresent()) {
2456 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2459 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2463 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2464 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2465 Optional<Networks> networkData =
2466 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2467 broker, LogicalDatastoreType.CONFIGURATION, id);
2468 return networkData.isPresent();
2472 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2473 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2474 if (null != elanInstance) {
2475 return elanInstance.getPhysicalNetworkName();
2481 public static Map<String, String> getOpenvswitchOtherConfigMap(BigInteger dpnId, DataBroker dataBroker) {
2482 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2483 return getMultiValueMap(otherConfigVal);
2486 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2487 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2488 return Collections.emptyMap();
2491 Map<String, String> valueMap = new HashMap<>();
2492 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2493 for (String keyValue : splitter.split(multiKeyValueStr)) {
2494 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2495 if (split.length == 2) {
2496 valueMap.put(split[0], split[1]);
2503 public static Optional<Node> getBridgeRefInfo(BigInteger dpnId, DataBroker dataBroker) {
2504 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2505 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2507 Optional<BridgeRefEntry> bridgeRefEntry =
2508 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2509 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2510 if (!bridgeRefEntry.isPresent()) {
2511 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2512 return Optional.absent();
2515 InstanceIdentifier<Node> nodeId =
2516 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2518 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2519 LogicalDatastoreType.OPERATIONAL, nodeId);
2523 public static String getProviderMappings(BigInteger dpId, DataBroker dataBroker) {
2524 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2525 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2529 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2530 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2531 if (ovsdbNode == null) {
2532 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2533 if (nodeFromReadOvsdbNode.isPresent()) {
2534 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2538 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2539 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2540 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2541 return openvswitchOtherConfigs.getOtherConfigValue();
2545 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2550 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2551 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2552 if (bridgeAugmentation != null) {
2553 InstanceIdentifier<Node> ovsdbNodeIid =
2554 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2555 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2556 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2558 return Optional.absent();
2563 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2567 return node.augmentation(OvsdbBridgeAugmentation.class);
2570 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
2571 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2574 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2575 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2576 InstanceIdentifier.builder(ExternalSubnets.class)
2579 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2580 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2581 if (optionalExternalSubnets.isPresent()) {
2582 return optionalExternalSubnets.get();
2584 } catch (ReadFailedException e) {
2585 LOG.error("Failed to read the subnets from the datastore.");
2591 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2592 BigInteger dpId, short tableId, String flowId, int priority, String flowName, BigInteger cookie,
2593 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2594 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2595 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2597 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2598 mdsalManager.addFlow(confTx, flowEntity);
2601 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2602 BigInteger dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2603 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2604 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2607 public static String getIpv6FlowRef(BigInteger dpnId, short tableId, long routerID) {
2608 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2609 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2612 public static String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId,
2613 ItmRpcService itmManager) {
2614 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2615 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2617 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2618 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2619 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2620 rpcResult = result.get();
2621 if (!rpcResult.isSuccessful()) {
2622 tunType = TunnelTypeGre.class ;
2623 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2624 .setSourceDpid(srcDpId)
2625 .setDestinationDpid(dstDpId)
2626 .setTunnelType(tunType)
2628 rpcResult = result.get();
2629 if (!rpcResult.isSuccessful()) {
2630 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2631 rpcResult.getErrors());
2633 return rpcResult.getResult().getInterfaceName();
2635 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2636 rpcResult.getErrors());
2638 return rpcResult.getResult().getInterfaceName();
2640 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2641 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2642 + "between {} and {}", srcDpId, dstDpId);
2647 public static String getIpv6JobKey(String routerName) {
2648 return "Ipv6." + routerName;
2651 static ReentrantLock lockForNat(final BigInteger dataPath) {
2652 // FIXME: wrap this in an Identifier
2653 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);