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 com.google.common.collect.Iterables;
20 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21 import java.math.BigInteger;
22 import java.net.InetAddress;
23 import java.net.UnknownHostException;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
31 import java.util.Objects;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.Future;
35 import java.util.concurrent.locks.ReentrantLock;
36 import java.util.stream.Collectors;
37 import org.apache.commons.net.util.SubnetUtils;
38 import org.eclipse.jdt.annotation.NonNull;
39 import org.eclipse.jdt.annotation.Nullable;
40 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
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.controller.sal.common.util.Arguments;
45 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
46 import org.opendaylight.genius.infra.Datastore.Configuration;
47 import org.opendaylight.genius.infra.Datastore.Operational;
48 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
49 import org.opendaylight.genius.infra.TypedReadTransaction;
50 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
51 import org.opendaylight.genius.infra.TypedWriteTransaction;
52 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
53 import org.opendaylight.genius.mdsalutil.ActionInfo;
54 import org.opendaylight.genius.mdsalutil.FlowEntity;
55 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
56 import org.opendaylight.genius.mdsalutil.GroupEntity;
57 import org.opendaylight.genius.mdsalutil.InstructionInfo;
58 import org.opendaylight.genius.mdsalutil.MDSALUtil;
59 import org.opendaylight.genius.mdsalutil.MatchInfo;
60 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
61 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
62 import org.opendaylight.genius.mdsalutil.NwConstants;
63 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
64 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
65 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
66 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
67 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
68 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
69 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
70 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
71 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
72 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
73 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
74 import org.opendaylight.genius.utils.JvmGlobalLocks;
75 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
76 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
77 import org.opendaylight.netvirt.elanmanager.api.IElanService;
78 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
79 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
80 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
81 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
82 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
83 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
84 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
87 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
88 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
89 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
90 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
93 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
94 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
184 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;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
223 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;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortInputBuilder;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetFixedIPsForNeutronPortOutput;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronvpnService;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
262 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;
263 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
264 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
265 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
266 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
267 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
268 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
269 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
270 import org.opendaylight.yangtools.yang.common.RpcResult;
271 import org.slf4j.Logger;
272 import org.slf4j.LoggerFactory;
274 public final class NatUtil {
276 private static String OF_URI_SEPARATOR = ":";
277 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
278 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
279 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
280 private static final String PROVIDER_MAPPINGS = "provider_mappings";
282 private NatUtil() { }
285 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
288 public static BigInteger getCookieSnatFlow(long routerId) {
289 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
290 BigInteger.valueOf(routerId));
294 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
297 public static BigInteger getCookieNaptFlow(long routerId) {
298 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
299 BigInteger.valueOf(routerId));
303 getVpnId() returns the VPN ID from the VPN name
305 public static long getVpnId(DataBroker broker, @Nullable String vpnName) {
306 if (vpnName == null) {
307 return NatConstants.INVALID_ID;
310 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
311 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
312 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
313 .instance.to.vpn.id.VpnInstance> vpnInstance =
314 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
315 LogicalDatastoreType.CONFIGURATION, id);
317 long vpnId = NatConstants.INVALID_ID;
318 if (vpnInstance.isPresent()) {
319 Long vpnIdAsLong = vpnInstance.get().getVpnId();
320 if (vpnIdAsLong != null) {
327 public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
328 if (vpnName == null) {
329 return NatConstants.INVALID_ID;
333 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
334 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
335 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
336 } catch (InterruptedException | ExecutionException e) {
337 LOG.error("Error retrieving VPN id for {}", vpnName, e);
340 return NatConstants.INVALID_ID;
343 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
344 //Get the external network ID from the ExternalRouter model
345 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
346 if (networkId == null) {
347 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
348 return NatConstants.INVALID_ID;
351 //Get the VPN ID from the ExternalNetworks model
352 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
353 if (vpnUuid == null) {
354 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
355 return NatConstants.INVALID_ID;
357 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
361 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
362 return InstanceIdentifier.builder(FloatingIpInfo.class)
363 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
366 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
367 return InstanceIdentifier.builder(RouterToVpnMapping.class)
368 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
371 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
372 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
373 .child(Ports.class, new PortsKey(portName)).build();
376 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
378 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
379 .child(Ports.class, new PortsKey(portName))
380 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
383 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
384 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
385 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
386 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
387 .instance.to.vpn.id.VpnInstance.class,
388 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
389 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
393 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
394 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
395 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
396 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
397 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
401 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
403 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
404 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
405 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
406 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
409 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
410 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
411 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
412 .append(destPrefix.getHostAddress()).append(NatConstants.FLOWID_SEPARATOR).append(vpnId).toString();
415 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip,
416 int port, String protocol) {
417 return new StringBuilder().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId)
418 .append(NatConstants.FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR)
419 .append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).append(NatConstants.FLOWID_SEPARATOR)
420 .append(port).append(NatConstants.FLOWID_SEPARATOR).append(protocol).toString();
424 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
425 String routerName = getRouterName(broker, routerId);
426 if (routerName == null) {
427 LOG.error("getNetworkIdFromRouterId - empty routerName received");
430 return getNetworkIdFromRouterName(broker, routerName);
434 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
435 if (routerName == null) {
436 LOG.error("getNetworkIdFromRouterName - empty routerName received");
439 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
440 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
441 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
444 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
445 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
446 .child(Routers.class, new RoutersKey(routerId)).build();
447 return routerInstanceIndentifier;
450 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
451 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
452 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
457 * Return if SNAT is enabled for the given router.
459 * @param broker The DataBroker
460 * @param routerId The router
461 * @return boolean true if enabled, otherwise false
463 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
464 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
465 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
466 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
470 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
471 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
472 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
473 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
477 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
479 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
480 } catch (InterruptedException | ExecutionException e) {
481 LOG.error("Error reading network VPN id for {}", networkId, e);
487 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
488 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
489 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
490 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
494 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
495 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
497 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
498 } catch (InterruptedException | ExecutionException e) {
499 LOG.error("Error retrieving provider type for {}", networkId, e);
505 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
506 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
507 Optional<Routers> routerData =
508 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
509 LogicalDatastoreType.CONFIGURATION, id);
510 if (routerData.isPresent()) {
511 Uuid networkId = routerData.get().getNetworkId();
512 if (networkId != null) {
513 return networkId.getValue();
516 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
520 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
521 return InstanceIdentifier.builder(ExternalNetworks.class)
522 .child(Networks.class, new NetworksKey(networkId)).build();
526 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
527 // convert routerId to Name
528 String routerName = getRouterName(broker, routerId);
529 if (routerName == null) {
530 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
533 return getPrimaryNaptfromRouterName(broker, routerName);
537 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
538 if (routerName == null) {
539 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
542 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
543 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
544 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
548 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
549 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
550 new RouterToNaptSwitchKey(routerId)).build();
553 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
554 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
555 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
559 public static String getRouterName(DataBroker broker, Long routerId) {
560 return getVpnInstanceFromVpnIdentifier(broker, routerId);
563 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
564 return InstanceIdentifier.builder(VpnInstanceOpData.class)
565 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
568 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
569 return new FlowEntityBuilder()
577 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
578 return new FlowEntityBuilder()
586 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
587 String nextHopIp = null;
588 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
589 InstanceIdentifier.builder(DpnEndpoints.class)
590 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
591 Optional<DPNTEPsInfo> tunnelInfo =
592 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
593 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
594 if (tunnelInfo.isPresent()) {
595 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
596 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
597 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
604 public static String getVpnRd(DataBroker broker, String vpnName) {
605 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
606 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
607 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
608 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
609 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
610 .VpnInstance::getVrfId).orElse(null);
614 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
616 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
617 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
618 .VpnInstance::getVrfId).orElse(null);
619 } catch (InterruptedException | ExecutionException e) {
620 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
626 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
627 String internalPort, NAPTEntryEvent.Protocol protocol) {
628 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
629 InstanceIdentifier<IpPortMap> ipPortMapId =
630 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
631 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
632 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
636 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
638 ProtocolTypes protocolType) {
639 return InstanceIdentifier.builder(IntextIpPortMap.class)
640 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
641 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
642 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
645 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
646 return InstanceIdentifier.builder(VpnInterfaces.class)
647 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
651 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
653 * NodeConnectorId is of form 'openflow:dpnid:portnum'
655 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
656 if (split.length != 3) {
657 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
663 public static BigInteger getDpIdFromInterface(
664 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
665 .state.Interface ifState) {
666 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
667 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
668 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
673 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName, String ipAddress) {
674 // returns only router, attached to IPv4 networks
675 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
676 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
677 Optional<VpnMap> optionalVpnMap =
678 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
679 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
680 if (!optionalVpnMap.isPresent()) {
681 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
684 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
685 if (routerIdsList != null && !routerIdsList.isEmpty()) {
686 for (Uuid routerUuid : routerIdsList) {
687 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerUuid.getValue());
688 Optional<Routers> routerData =
689 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
690 LogicalDatastoreType.CONFIGURATION, id);
691 if (routerData.isPresent()) {
692 List<Uuid> subnetIdsList = routerData.get().getSubnetIds();
693 for (Uuid subnetUuid : subnetIdsList) {
694 String subnetIp = getSubnetIp(broker, subnetUuid);
695 SubnetUtils subnet = new SubnetUtils(subnetIp);
696 if (subnet.getInfo().isInRange(ipAddress)) {
697 return routerUuid.getValue();
703 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
708 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
709 Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
710 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
711 Optional<VpnMaps> optionalVpnMaps =
712 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
713 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
714 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
715 for (VpnMap vpnMap : optionalVpnMaps.get().nonnullVpnMap()) {
716 if (routerId.equals(vpnMap.getVpnId().getValue())) {
719 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
720 if (routerIdsList.isEmpty()) {
723 // Skip router vpnId fetching from internet BGP-VPN
724 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
725 // We only need to check the first network; if it’s not an external network there’s no
726 // need to check the rest of the VPN’s network list
727 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
731 if (routerIdsList.contains(new Uuid(routerId))) {
732 return vpnMap.getVpnId();
736 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
740 static long getAssociatedVpn(DataBroker broker, String routerName) {
741 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
742 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
743 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
744 NatConstants.INVALID_ID);
748 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
749 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
750 if (vpnUuid == null) {
751 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
754 return vpnUuid.getValue();
758 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
759 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
760 if (vpnUuid == null) {
761 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
764 return vpnUuid.getValue();
767 // TODO Clean up the exception handling
768 @SuppressWarnings("checkstyle:IllegalCatch")
769 public static void addPrefixToBGP(DataBroker broker,
770 IBgpManager bgpManager,
771 IFibManager fibManager,
776 @Nullable String parentVpnRd,
777 @Nullable String macAddress,
783 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
784 prefix, nextHopIp, label);
785 if (nextHopIp == null) {
786 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
791 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
792 dpId, Prefixes.PrefixCue.Nat);
793 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
794 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
795 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
796 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
797 /* Publish to Bgp only if its an INTERNET VPN */
798 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
799 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
800 null /*gatewayMac*/);
802 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
803 prefix, nextHopIp, label);
804 } catch (Exception e) {
805 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
806 prefix, nextHopIp, label, e);
810 static void addPrefixToInterface(DataBroker broker, long vpnId, @Nullable String interfaceName, String ipPrefix,
811 String networkId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
812 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
813 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
814 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
815 .to._interface.VpnIdsKey(vpnId))
816 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
817 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
818 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
819 prefixBuilder.setNetworkId(new Uuid(networkId));
821 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
822 prefixBuilder.build());
823 } catch (TransactionCommitFailedException e) {
824 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
825 ipPrefix, vpnId, dpId, e);
829 public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
831 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
832 InstanceIdentifier.builder(PrefixToInterface.class)
833 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
834 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
835 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
837 } catch (TransactionCommitFailedException e) {
838 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
843 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
844 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
845 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
849 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
850 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
851 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
852 return routerInstanceIndentifier;
856 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
857 String internalIpAddress, ProtocolTypes protocolType) {
858 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
859 LogicalDatastoreType.CONFIGURATION,
860 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
861 IntIpProtoType::getPorts).orElse(emptyList());
864 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
865 String internalIpAddress,
866 ProtocolTypes protocolType) {
867 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
868 InstanceIdentifier.builder(SnatintIpPortMap.class)
869 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
870 .child(IpPort.class, new IpPortKey(internalIpAddress))
871 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
872 return intIpProtocolTypeId;
875 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
876 String internalIpAddress) {
877 InstanceIdentifier<IpPort> intIpProtocolTypeId =
878 InstanceIdentifier.builder(SnatintIpPortMap.class)
879 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
880 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
881 return intIpProtocolTypeId;
885 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
886 String internalIpAddress) {
887 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
888 LogicalDatastoreType.CONFIGURATION,
889 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
892 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
893 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
894 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
898 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
899 return InstanceIdentifier.create(NaptSwitches.class);
902 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
903 return InstanceIdentifier.create(NaptSwitches.class)
904 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
907 public static String getGroupIdKey(String routerName) {
908 return "snatmiss." + routerName;
911 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
912 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
913 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
916 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
917 RpcResult<AllocateIdOutput> rpcResult = result.get();
918 return rpcResult.getResult().getIdValue();
919 } catch (NullPointerException | InterruptedException | ExecutionException e) {
920 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
925 // TODO Clean up the exception handling
926 @SuppressWarnings("checkstyle:IllegalCatch")
927 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
928 String rd, String prefix, String vpnName, Logger log) {
930 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
931 fibManager.removeFibEntry(rd, prefix, null);
932 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
933 bgpManager.withdrawPrefix(rd, prefix);
935 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
936 } catch (Exception e) {
937 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
938 rd, prefix, vpnName, e);
943 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
944 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
945 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
948 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
949 return InstanceIdentifier.builder(IntextIpPortMap.class)
950 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
953 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
954 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
955 return InstanceIdentifier.builder(IntextIpMap.class)
956 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
957 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
958 .intext.ip.map.IpMappingKey(routerId))
963 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
964 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
965 .ip.map.IpMapping> ipMappingOptional =
966 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
967 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
968 // Ensure there are no duplicates
969 Collection<String> externalIps = new HashSet<>();
970 if (ipMappingOptional.isPresent()) {
971 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
972 externalIps.add(ipMap.getExternalIp());
979 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
980 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
981 if (routerData != null) {
982 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
989 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
990 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
991 .ip.map.IpMapping> ipMappingOptional =
992 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
993 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
994 Map<String, Long> externalIpsLabel = new HashMap<>();
995 if (ipMappingOptional.isPresent()) {
996 for (IpMap ipMap : ipMappingOptional.get().nonnullIpMap()) {
997 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1000 return externalIpsLabel;
1004 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
1005 String leastLoadedExternalIp = null;
1006 InstanceIdentifier<ExternalCounters> id =
1007 InstanceIdentifier.builder(ExternalIpsCounter.class)
1008 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1009 Optional<ExternalCounters> externalCountersData =
1010 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1011 if (externalCountersData.isPresent()) {
1012 ExternalCounters externalCounter = externalCountersData.get();
1013 short countOfLstLoadExtIp = 32767;
1014 for (ExternalIpCounter externalIpCounter : externalCounter.nonnullExternalIpCounter()) {
1015 String curExternalIp = externalIpCounter.getExternalIp();
1016 short countOfCurExtIp = externalIpCounter.getCounter();
1017 if (countOfCurExtIp < countOfLstLoadExtIp) {
1018 countOfLstLoadExtIp = countOfCurExtIp;
1019 leastLoadedExternalIp = curExternalIp;
1023 return leastLoadedExternalIp;
1026 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1028 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1029 String subnetIP = getSubnetIp(dataBroker, subnetId);
1030 if (subnetIP != null) {
1031 return getSubnetIpAndPrefix(subnetIP);
1033 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1038 public static String[] getSubnetIpAndPrefix(String subnetString) {
1039 String[] subnetSplit = subnetString.split("/");
1040 String subnetIp = subnetSplit[0];
1041 String subnetPrefix = "0";
1042 if (subnetSplit.length == 2) {
1043 subnetPrefix = subnetSplit[1];
1045 return new String[] {subnetIp, subnetPrefix};
1049 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1050 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1051 .builder(Subnetmaps.class)
1052 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1054 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1055 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1058 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1059 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1060 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1061 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1062 if (leastLoadedExtIpAddrSplit.length == 2) {
1063 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1065 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1069 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1070 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1071 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1072 Optional<RouterDpnList> routerDpnListData =
1073 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1074 LogicalDatastoreType.OPERATIONAL, id);
1075 List<BigInteger> dpns = new ArrayList<>();
1076 if (routerDpnListData.isPresent()) {
1077 for (DpnVpninterfacesList dpnVpnInterface : routerDpnListData.get().nonnullDpnVpninterfacesList()) {
1078 dpns.add(dpnVpnInterface.getDpnId());
1084 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1085 long bgpVpnId = NatConstants.INVALID_ID;
1086 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1087 if (bgpVpnUuid != null) {
1088 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1093 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1094 .@Nullable RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1095 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1096 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1099 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1100 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1101 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1102 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1103 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1104 .RouterInterface.class,
1105 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1106 .RouterInterfaceKey(interfaceName)).build();
1109 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1110 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1112 if (dpId.equals(BigInteger.ZERO)) {
1113 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1114 + "to handle router {} association model", interfaceName, routerName);
1118 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1119 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1120 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1122 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1123 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1124 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1125 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1126 .setInterface(interfaceName).build();
1127 if (optionalDpnVpninterfacesList.isPresent()) {
1128 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1129 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1130 operTx.merge(dpnVpnInterfacesListIdentifier
1131 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1132 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1133 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1135 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1136 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1137 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1138 routerDpnListBuilder.setRouterId(routerName);
1139 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1140 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1141 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1142 routerInterfaces.add(routerInterface);
1143 dpnVpnList.setRouterInterfaces(routerInterfaces);
1144 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1145 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1149 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1150 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1151 if (dpId.equals(BigInteger.ZERO)) {
1152 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1153 + "association model", interfaceName, routerName);
1157 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1158 + "DPNRouters map", dpId, routerName, interfaceName);
1159 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1161 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1163 if (optionalDpnRoutersList.isPresent()) {
1164 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1165 .setRouter(routerName).build();
1166 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().nonnullRoutersList();
1167 if (!routersListFromDs.contains(routersList)) {
1168 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1169 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1170 operTx.merge(dpnRoutersListIdentifier
1171 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1173 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1174 + "DPNRouters map", routerName, dpId);
1177 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1178 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1179 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1180 dpnRoutersListBuilder.setDpnId(dpId);
1181 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1182 routersListBuilder.setRouter(routerName);
1183 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1184 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1188 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1189 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1190 if (dpId.equals(BigInteger.ZERO)) {
1191 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1195 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1196 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1197 if (optionalRouterDpnList.isPresent()) {
1198 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1199 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1200 operTx.delete(routerDpnListIdentifier);
1202 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1203 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1207 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1208 BigInteger dpId, @NonNull TypedReadWriteTransaction<Operational> operTx) {
1209 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1210 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1212 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1213 } catch (InterruptedException | ExecutionException e) {
1214 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1215 optionalRouterDpnList = Optional.absent();
1217 if (optionalRouterDpnList.isPresent()) {
1218 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1219 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1220 optionalRouterDpnList.get().getRouterInterfaces();
1221 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1222 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1223 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1224 .setInterface(vpnInterfaceName).build();
1226 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1227 if (routerInterfaces.isEmpty()) {
1228 operTx.delete(routerDpnListIdentifier);
1230 operTx.delete(routerDpnListIdentifier.child(
1231 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1232 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1233 new RouterInterfacesKey(vpnInterfaceName)));
1239 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1240 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1241 throws ExecutionException, InterruptedException {
1243 1) Get the DpnRoutersList for the DPN.
1244 2) Get the RoutersList identifier for the DPN and router.
1245 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1246 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1247 then remove RouterList.
1250 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1251 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1253 //Get the dpn-routers-list instance for the current DPN.
1254 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1255 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1257 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1258 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1259 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1263 //Get the routers-list instance for the router on the current DPN only
1264 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1265 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1267 if (routersListData == null || !routersListData.isPresent()) {
1268 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1269 + "in the ODL-L3VPN:dpn-routers model",
1274 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1275 + "from the NeutronVPN - router-interfaces-map", routerName);
1276 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1277 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1278 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1279 .RouterInterfaces> routerInterfacesData =
1280 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1281 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1283 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1284 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1285 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1286 curDpnId, routerName, routerName);
1287 operTx.delete(routersListIdentifier);
1291 //Get the VM interfaces for the router on the current DPN only.
1292 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1293 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1294 if (vmInterfaces == null) {
1295 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1296 + "NeutronVPN - router-interfaces-map", routerName);
1300 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1301 // then remove RouterList.
1302 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1303 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1304 String vmInterfaceName = vmInterface.getInterfaceId();
1305 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1306 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1307 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1308 + "the DPN ID {} for the checked interface {}",
1309 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1312 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1313 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1314 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1318 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1319 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1320 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1321 operTx.delete(routersListIdentifier);
1324 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1325 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1326 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1327 .rev150602.RouterInterfacesMap.class)
1328 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1329 .interfaces.map.RouterInterfaces.class,
1330 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1331 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1334 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1335 return InstanceIdentifier.builder(DpnRouters.class)
1336 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1337 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1340 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1341 BigInteger nodeId = BigInteger.ZERO;
1343 GetDpidFromInterfaceInput
1345 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1346 Future<RpcResult<GetDpidFromInterfaceOutput>>
1348 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1349 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1350 if (dpIdResult.isSuccessful()) {
1351 nodeId = dpIdResult.getResult().getDpid();
1353 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1355 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1356 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1362 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1363 ItmRpcService itmRpcService,
1364 IInterfaceManager interfaceManager, String ifName,
1365 Long tunnelKey, boolean internalTunnelInterface) {
1366 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1367 ifName, tunnelKey, 0, internalTunnelInterface);
1371 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1372 ItmRpcService itmRpcService,
1373 IInterfaceManager interfaceManager,
1374 String ifName, @Nullable Long tunnelKey, int pos,
1375 boolean internalTunnelInterface) {
1376 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1377 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1378 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1379 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1380 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1381 if (tunnelKey != null) {
1382 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1383 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1384 } //init builders, ITM/IFM rpc can be called based on type of interface
1387 List<Action> actions = emptyList();
1388 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1389 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1390 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1391 if (!rpcResult.isSuccessful()) {
1392 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1393 + "returned with Errors {}", ifName, rpcResult.getErrors());
1395 actions = rpcResult.getResult().nonnullAction();
1398 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1399 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1400 if (!rpcResult.isSuccessful()) {
1401 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1402 + "returned with Errors {}", ifName, rpcResult.getErrors());
1404 actions = rpcResult.getResult().nonnullAction();
1407 List<ActionInfo> listActionInfo = new ArrayList<>();
1408 for (Action action : actions) {
1409 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1410 actionClass = action.getAction();
1411 if (actionClass instanceof OutputActionCase) {
1412 listActionInfo.add(new ActionOutput(pos++,
1413 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1414 } else if (actionClass instanceof PushVlanActionCase) {
1415 listActionInfo.add(new ActionPushVlan(pos++));
1416 } else if (actionClass instanceof SetFieldCase) {
1417 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1418 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1419 .getVlanId().getValue();
1420 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1422 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1423 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1424 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1425 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1426 NxRegLoad nxRegLoad =
1427 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1428 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1429 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1432 return listActionInfo;
1433 } catch (InterruptedException | ExecutionException e) {
1434 LOG.error("Exception when egress actions for interface {}", ifName, e);
1436 LOG.error("Error when getting egress actions for interface {}", ifName);
1441 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1442 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1446 public static List<Port> getNeutronPorts(DataBroker broker) {
1447 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1448 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1449 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1450 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1452 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1453 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1455 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1456 LOG.error("getNeutronPorts : No neutron ports found");
1460 return portsOptional.get().getPort();
1464 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1465 List<Port> ports = getNeutronPorts(
1468 for (Port port : ports) {
1469 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1470 for (FixedIps ip : port.getFixedIps()) {
1471 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1477 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1482 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1484 LOG.error("getSubnetIdForFloatingIp : port is null");
1487 for (FixedIps ip : port.nonnullFixedIps()) {
1488 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1489 return ip.getSubnetId();
1492 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1497 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1498 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1499 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1500 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1501 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1505 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1506 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1507 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1508 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1509 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1514 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1515 if (subnetId == null) {
1516 LOG.error("getSubnetGwMac : subnetID is null");
1520 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1521 .child(Subnet.class, new SubnetKey(subnetId));
1522 Optional<Subnet> subnetOpt =
1523 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1524 LogicalDatastoreType.CONFIGURATION, subnetInst);
1525 if (!subnetOpt.isPresent()) {
1526 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1530 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1531 if (gatewayIp == null) {
1532 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1536 if (null != gatewayIp.getIpv6Address()) {
1540 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1541 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1543 Optional<VpnPortipToPort> portIpToPortOpt =
1544 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1545 LogicalDatastoreType.CONFIGURATION, portIpInst);
1546 if (portIpToPortOpt.isPresent()) {
1547 return portIpToPortOpt.get().getMacAddress();
1550 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1551 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1553 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1554 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1555 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1556 if (learntIpToPortOpt.isPresent()) {
1557 return learntIpToPortOpt.get().getMacAddress();
1560 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1564 public static boolean isIPv6Subnet(String prefix) {
1565 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1568 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1569 return InstanceIdentifier.builder(DpnRouters.class)
1570 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1573 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1574 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1575 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1576 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1579 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1580 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1581 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1585 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1586 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1587 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1588 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1589 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1593 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1594 Uuid floatingIpId) {
1596 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1597 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1598 } catch (InterruptedException | ExecutionException e) {
1599 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1605 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1606 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1607 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1608 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1609 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1613 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1614 Uuid floatingIpId) {
1616 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1617 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1618 } catch (InterruptedException | ExecutionException e) {
1619 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1624 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1625 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1626 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1630 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1631 InstanceIdentifier<Interface> ifStateId =
1632 buildStateInterfaceId(interfaceName);
1633 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1634 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1637 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1638 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1639 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1640 .interfaces.rev140508.InterfacesState.class)
1641 .child(Interface.class,
1642 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1643 .interfaces.state.InterfaceKey(interfaceName));
1644 return idBuilder.build();
1648 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1649 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1650 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1651 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1655 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1657 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1658 } catch (InterruptedException | ExecutionException e) {
1659 LOG.error("Error reading router {}", routerName, e);
1664 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1665 if (routerId == NatConstants.INVALID_ID) {
1666 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1669 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1670 .setRouterId(routerId).setRouterName(routerName).build();
1671 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1675 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1676 IdManagerService idManager) {
1677 InetAddress defaultIP = null;
1679 defaultIP = InetAddress.getByName("0.0.0.0");
1680 } catch (UnknownHostException e) {
1681 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1682 + "Default Route to NAT.", e);
1686 List<MatchInfo> matches = new ArrayList<>();
1687 matches.add(MatchEthernetType.IPV4);
1688 //add match for vrfid
1689 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1691 List<InstructionInfo> instructions = new ArrayList<>();
1692 List<ActionInfo> actionsInfo = new ArrayList<>();
1693 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1694 actionsInfo.add(new ActionGroup(groupId));
1695 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1696 instructions.add(new InstructionApplyActions(actionsInfo));
1697 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1698 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1699 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1703 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1704 String routerName = getRouterName(broker, routerId);
1705 if (routerName == null) {
1706 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1709 return getExtGwMacAddFromRouterName(broker, routerName);
1713 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1714 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1715 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1716 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1720 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1722 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1723 Routers::getExtGwMacAddress).orElse(null);
1724 } catch (InterruptedException | ExecutionException e) {
1725 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1730 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1731 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1732 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1733 .child(Router.class, new RouterKey(routerUuid));
1734 return routerInstanceIdentifier;
1738 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1739 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1740 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1741 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1746 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1747 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1748 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1749 LogicalDatastoreType.CONFIGURATION,
1750 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1754 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1755 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1756 Optional<ExternalNetworks> externalNwData =
1757 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1758 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1759 if (externalNwData.isPresent()) {
1760 for (Networks externalNw : externalNwData.get().nonnullNetworks()) {
1761 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1762 @Nullable List<Uuid> routerIds = externalNw.getRouterIds();
1763 return routerIds != null ? routerIds : emptyList();
1770 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1773 long ipLo = ipToLong(InetAddress.getByName(start));
1774 long ipHi = ipToLong(InetAddress.getByName(end));
1775 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1776 return ipToTest >= ipLo && ipToTest <= ipHi;
1777 } catch (UnknownHostException e) {
1778 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1784 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1785 if (externalIps == null) {
1786 return Collections.emptySet();
1789 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1793 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1794 if (routerName == null) {
1795 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1796 return Collections.emptySet();
1799 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1800 Optional<Routers> routerData =
1801 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1802 LogicalDatastoreType.CONFIGURATION, id);
1803 if (routerData.isPresent()) {
1804 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1806 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1807 return Collections.emptySet();
1812 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1813 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1814 if (subnetId == null) {
1815 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1816 return Optional.absent();
1819 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1820 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1821 InstanceIdentifier.builder(ExternalSubnets.class)
1822 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1823 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1824 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1825 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1829 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1830 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1831 if (subnetId == null) {
1832 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1833 return Optional.absent();
1836 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1837 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1838 InstanceIdentifier.builder(ExternalSubnets.class)
1839 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1840 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1842 return tx.read(subnetsIdentifier).get();
1843 } catch (InterruptedException | ExecutionException e) {
1844 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1845 return Optional.absent();
1849 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1850 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1851 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1853 if (optionalExternalSubnets.isPresent()) {
1854 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1857 return NatConstants.INVALID_ID;
1860 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1861 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1862 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1864 if (optionalExternalSubnets.isPresent()) {
1865 return NatUtil.getVpnId(tx, subnetId.getValue());
1868 return NatConstants.INVALID_ID;
1871 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1873 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1874 if (externalSubnetId != null) {
1875 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1878 return NatConstants.INVALID_ID;
1882 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1883 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1884 for (ExternalIps extIp : router.nonnullExternalIps()) {
1885 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1886 if (extIpString.equals(externalIpAddress)) {
1887 return extIp.getSubnetId();
1890 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1894 private static long ipToLong(InetAddress ip) {
1895 byte[] octets = ip.getAddress();
1897 for (byte octet : octets) {
1899 result |= octet & 0xff;
1905 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1906 if (externalIps == null) {
1910 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1913 // elan-instances config container
1915 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1916 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1917 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1918 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1922 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1924 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1925 } catch (InterruptedException | ExecutionException e) {
1926 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1931 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1932 return InstanceIdentifier.builder(ElanInstances.class)
1933 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1936 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
1937 IElanService elanManager, IdManagerService idManager,
1938 long routerId, String routerName) {
1939 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1940 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1941 return natOverVxlanUtil.getRouterVni(routerName, routerId).longValue();
1943 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1947 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1948 short tableId, TypedWriteTransaction<Configuration> confTx) {
1949 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1950 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1952 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1953 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1954 List<MatchInfo> matches = new ArrayList<>();
1955 matches.add(MatchEthernetType.IPV4);
1956 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1957 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1958 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1959 matches, preDnatToSnatInstructions);
1961 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
1962 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1963 preDnatToSnatTableFlowEntity, naptDpnId);
1966 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
1967 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
1968 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1969 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1970 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1971 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
1972 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1973 flowRef, naptDpnId);
1976 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1977 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1978 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1981 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1982 String vpnName, String externalIp,
1983 Boolean isMoreThanOneFipCheckOnDpn) {
1984 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1985 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1986 if (dpnInVpn.isPresent()) {
1987 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1988 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
1990 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1991 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1992 int floatingIpPresentCount = 0;
1993 for (IpAddresses ipAddress: ipAddressList) {
1994 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
1995 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1996 floatingIpPresentCount++;
1997 //Add tunnel table check
1998 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2001 //Remove tunnel table check
2002 if (!isMoreThanOneFipCheckOnDpn) {
2008 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2012 } catch (NullPointerException e) {
2013 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2014 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2021 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
2022 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2023 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2024 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2028 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2029 throws ExecutionException, InterruptedException {
2030 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2034 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2035 if (vpnInstance == null) {
2038 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2039 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2042 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2043 return InstanceIdentifier.builder(VpnInstances.class)
2044 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2048 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2049 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2050 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2051 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2054 public static String validateAndAddNetworkMask(String ipAddress) {
2055 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2058 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2059 String vpnInterfaceName, String vpnName) {
2060 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2061 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2064 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2065 String routerName, BigInteger dpnId) {
2066 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2067 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2069 if (networkData != null && networkData.isPresent()) {
2070 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2071 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2072 for (Uuid routerUuid : routerUuidList) {
2073 String sharedRouterName = routerUuid.getValue();
2074 if (!routerName.equals(sharedRouterName)) {
2075 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2076 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2077 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2078 + "associated with other active router {} on NAPT switch {}", networkId,
2079 sharedRouterName, switchDpnId);
2089 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2090 String routerName, BigInteger dpnId) {
2091 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2092 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2093 .subnets.Subnets::getRouterIds).orElse(emptyList());
2094 if (!routerUuidList.isEmpty()) {
2095 for (Uuid routerUuid : routerUuidList) {
2096 String sharedRouterName = routerUuid.getValue();
2097 if (!routerName.equals(sharedRouterName)) {
2098 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2099 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2100 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2101 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2102 sharedRouterName, switchDpnId);
2111 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2112 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2113 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2114 List<ExternalIps> externalIps = router.getExternalIps();
2115 List<String> externalIpsSting = new ArrayList<>();
2117 if (externalIps == null || externalIps.isEmpty()) {
2118 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2121 for (ExternalIps externalIp : externalIps) {
2122 externalIpsSting.add(externalIp.getIpAddress());
2124 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2125 if (addOrRemove == NwConstants.ADD_FLOW) {
2126 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2127 router.getNetworkId(), subnetVpnName.getValue(), tx);
2128 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2129 router.getExtGwMacAddress(), primarySwitchId,
2130 router.getNetworkId());
2132 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2133 router.getNetworkId(), subnetVpnName.getValue(), tx);
2134 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2135 router.getExtGwMacAddress(), primarySwitchId,
2136 router.getNetworkId());
2138 }), LOG, "Error installing router gateway flows");
2141 @SuppressWarnings("checkstyle:IllegalCatch")
2142 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2143 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2144 String routerName, long routerId, long routerVpnId,
2145 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2146 throws ExecutionException, InterruptedException {
2147 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2148 //remove miss entry to NAPT switch
2149 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2150 if (extNwProvType == null) {
2153 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2154 Map<String, Long> externalIpLabel;
2155 if (extNwProvType == ProviderTypes.VXLAN) {
2156 externalIpLabel = null;
2158 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2160 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2161 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2162 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2165 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2166 boolean naptStatus =
2167 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2168 externalIpCache, confTx);
2170 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2172 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
2173 FlowEntity flowEntity = null;
2175 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2176 NatConstants.DEL_FLOW);
2177 if (flowEntity == null) {
2178 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2179 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2182 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
2183 mdsalManager.removeFlow(confTx, flowEntity);
2185 } catch (Exception ex) {
2186 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2190 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2194 GroupEntity groupEntity = null;
2196 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2197 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2198 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2199 mdsalManager.removeGroup(groupEntity);
2200 } catch (Exception ex) {
2201 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2204 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2207 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2208 externalIpLabel, confTx);
2209 //remove table 26 flow ppointing to table46
2210 FlowEntity flowEntity = null;
2212 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2213 NatConstants.DEL_FLOW);
2214 if (flowEntity == null) {
2215 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2219 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2220 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2221 mdsalManager.removeFlow(confTx, flowEntity);
2223 } catch (Exception ex) {
2224 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2228 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2231 //best effort to check IntExt model
2232 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2236 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2237 ProviderTypes extNwProvType) {
2238 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2239 || extNwProvType == ProviderTypes.VXLAN)) {
2245 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2246 BigInteger dpnId, DataBroker dataBroker) {
2247 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2248 elanInstanceName, dpnId);
2249 // FIXME: separate this out?
2250 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2253 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2254 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2255 List<String> elanInterfaceList;
2256 DpnInterfaces dpnInterface;
2257 if (!dpnInElanInterfaces.isPresent()) {
2258 elanInterfaceList = new ArrayList<>();
2260 dpnInterface = dpnInElanInterfaces.get();
2261 elanInterfaceList = dpnInterface.getInterfaces();
2263 if (!elanInterfaceList.contains(pseudoPortId)) {
2264 elanInterfaceList.add(pseudoPortId);
2265 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2266 .withKey(new DpnInterfacesKey(dpnId)).build();
2267 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2268 elanDpnInterfaceId, dpnInterface);
2270 } catch (ReadFailedException e) {
2271 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2272 } catch (TransactionCommitFailedException e) {
2273 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2279 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2280 BigInteger dpnId, DataBroker dataBroker) {
2281 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2282 elanInstanceName, dpnId);
2283 // FIXME: separate this out?
2284 final ReentrantLock lock = JvmGlobalLocks.getLockForString(elanInstanceName);
2287 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2288 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2289 List<String> elanInterfaceList;
2290 DpnInterfaces dpnInterface;
2291 if (!dpnInElanInterfaces.isPresent()) {
2292 LOG.info("No interface in any dpn for {}", elanInstanceName);
2296 dpnInterface = dpnInElanInterfaces.get();
2297 elanInterfaceList = dpnInterface.getInterfaces();
2298 if (!elanInterfaceList.contains(pseudoPortId)) {
2299 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2302 elanInterfaceList.remove(pseudoPortId);
2303 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2304 .withKey(new DpnInterfacesKey(dpnId)).build();
2305 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2306 elanDpnInterfaceId, dpnInterface);
2307 } catch (ReadFailedException e) {
2308 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2309 } catch (TransactionCommitFailedException e) {
2310 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2316 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2317 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2318 for (Map.Entry<String,Routers> router : extRouter) {
2319 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2320 .equals(networkid)) {
2328 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2330 return SingleTransactionDataBroker.syncRead(dataBroker,
2331 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2333 catch (ReadFailedException e) {
2334 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2339 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2340 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2341 .builder(LearntVpnVipToPortData.class).build();
2342 return learntVpnVipToPortDataId;
2345 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2347 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2348 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2349 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2352 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2353 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2354 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2355 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2358 public static void createGroupIdPool(IdManagerService idManager) {
2359 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2360 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2361 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2362 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2365 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2366 if (result != null && result.get().isSuccessful()) {
2367 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2369 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2371 } catch (InterruptedException | ExecutionException e) {
2372 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2376 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2377 NodeId nodeId = new NodeId("openflow:" + switchId);
2378 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2379 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2380 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2381 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2382 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2383 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2384 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2385 if (nodeOptional.isPresent()) {
2386 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2389 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2393 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2394 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2395 Optional<Networks> networkData =
2396 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2397 broker, LogicalDatastoreType.CONFIGURATION, id);
2398 return networkData.isPresent();
2402 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2403 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2404 if (null != elanInstance) {
2405 return elanInstance.getPhysicalNetworkName();
2411 public static Map<String, String> getOpenvswitchOtherConfigMap(BigInteger dpnId, DataBroker dataBroker) {
2412 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2413 return getMultiValueMap(otherConfigVal);
2416 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2417 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2418 return Collections.emptyMap();
2421 Map<String, String> valueMap = new HashMap<>();
2422 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2423 for (String keyValue : splitter.split(multiKeyValueStr)) {
2424 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2425 if (split.length == 2) {
2426 valueMap.put(split[0], split[1]);
2433 public static Optional<Node> getBridgeRefInfo(BigInteger dpnId, DataBroker dataBroker) {
2434 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2435 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2437 Optional<BridgeRefEntry> bridgeRefEntry =
2438 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2439 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2440 if (!bridgeRefEntry.isPresent()) {
2441 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2442 return Optional.absent();
2445 InstanceIdentifier<Node> nodeId =
2446 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2448 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2449 LogicalDatastoreType.OPERATIONAL, nodeId);
2453 public static String getProviderMappings(BigInteger dpId, DataBroker dataBroker) {
2454 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2455 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2459 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2460 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2461 if (ovsdbNode == null) {
2462 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2463 if (nodeFromReadOvsdbNode.isPresent()) {
2464 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2468 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2469 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2470 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2471 return openvswitchOtherConfigs.getOtherConfigValue();
2475 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2480 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2481 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2482 if (bridgeAugmentation != null) {
2483 InstanceIdentifier<Node> ovsdbNodeIid =
2484 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2485 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2486 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2488 return Optional.absent();
2493 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2497 return node.augmentation(OvsdbBridgeAugmentation.class);
2500 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
2501 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2504 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2505 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2506 InstanceIdentifier.builder(ExternalSubnets.class)
2509 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2510 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2511 if (optionalExternalSubnets.isPresent()) {
2512 return optionalExternalSubnets.get();
2514 } catch (ReadFailedException e) {
2515 LOG.error("Failed to read the subnets from the datastore.");
2521 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2522 BigInteger dpId, short tableId, String flowId, int priority, String flowName, BigInteger cookie,
2523 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2524 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2525 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2527 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2528 mdsalManager.addFlow(confTx, flowEntity);
2531 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2532 BigInteger dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2533 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2534 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2537 public static String getIpv6FlowRef(BigInteger dpnId, short tableId, long routerID) {
2538 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2539 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2542 public static String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId,
2543 ItmRpcService itmManager) {
2544 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2545 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2547 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2548 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2549 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2550 rpcResult = result.get();
2551 if (!rpcResult.isSuccessful()) {
2552 tunType = TunnelTypeGre.class ;
2553 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2554 .setSourceDpid(srcDpId)
2555 .setDestinationDpid(dstDpId)
2556 .setTunnelType(tunType)
2558 rpcResult = result.get();
2559 if (!rpcResult.isSuccessful()) {
2560 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2561 rpcResult.getErrors());
2563 return rpcResult.getResult().getInterfaceName();
2565 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2566 rpcResult.getErrors());
2568 return rpcResult.getResult().getInterfaceName();
2570 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2571 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2572 + "between {} and {}", srcDpId, dstDpId);
2577 static ReentrantLock lockForNat(final BigInteger dataPath) {
2578 // FIXME: wrap this in an Identifier
2579 return JvmGlobalLocks.getLockForString(NatConstants.NAT_DJC_PREFIX + dataPath);
2582 public static void removeSnatEntriesForPort(DataBroker dataBroker, NaptManager naptManager,
2583 IMdsalApiManager mdsalManager, NeutronvpnService neutronVpnService,
2584 String interfaceName, String routerName) {
2585 Long routerId = NatUtil.getVpnId(dataBroker, routerName);
2586 if (routerId == NatConstants.INVALID_ID) {
2587 LOG.error("removeSnatEntriesForPort: routerId not found for routername {}", routerName);
2590 BigInteger naptSwitch = getPrimaryNaptfromRouterName(dataBroker, routerName);
2591 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2592 LOG.error("removeSnatEntriesForPort: NaptSwitch is not elected for router {}"
2593 + "with Id {}", routerName, routerId);
2596 //getInternalIp for port
2597 List<String> fixedIps = getFixedIpsForPort(neutronVpnService, interfaceName);
2598 if (fixedIps == null) {
2599 LOG.error("removeSnatEntriesForPort: Internal Ips not found for InterfaceName {} in router {} with id {}",
2600 interfaceName, routerName, routerId);
2603 List<ProtocolTypes> protocolTypesList = getPortocolList();
2604 for (String internalIp : fixedIps) {
2605 LOG.debug("removeSnatEntriesForPort: Internal Ip retrieved for interface {} is {} in router with Id {}",
2606 interfaceName, internalIp, routerId);
2607 for (ProtocolTypes protocol : protocolTypesList) {
2608 List<Integer> portList = NatUtil.getInternalIpPortListInfo(dataBroker, routerId, internalIp, protocol);
2609 if (portList != null) {
2610 for (Integer portnum : portList) {
2611 //build and remove the flow in outbound table
2612 removeNatFlow(mdsalManager, naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
2613 routerId, internalIp, portnum, protocol.getName());
2615 //build and remove the flow in inboundtable
2617 removeNatFlow(mdsalManager, naptSwitch, NwConstants.INBOUND_NAPT_TABLE, routerId,
2618 internalIp, portnum, protocol.getName());
2620 //Get the external IP address and the port from the model
2622 NAPTEntryEvent.Protocol proto = protocol.toString().equals(ProtocolTypes.TCP.toString())
2623 ? NAPTEntryEvent.Protocol.TCP : NAPTEntryEvent.Protocol.UDP;
2624 IpPortExternal ipPortExternal = NatUtil.getExternalIpPortMap(dataBroker, routerId,
2625 internalIp, String.valueOf(portnum), proto);
2626 if (ipPortExternal == null) {
2627 LOG.error("removeSnatEntriesForPort: Mapping for internalIp {} "
2628 + "with port {} is not found in "
2629 + "router with Id {}", internalIp, portnum, routerId);
2632 String externalIpAddress = ipPortExternal.getIpAddress();
2633 String internalIpPort = internalIp + ":" + portnum;
2634 // delete the entry from IntExtIpPortMap DS
2636 naptManager.removeFromIpPortMapDS(routerId, internalIpPort, proto);
2637 naptManager.removePortFromPool(internalIpPort, externalIpAddress);
2641 LOG.debug("removeSnatEntriesForPort: No {} session for interface {} with internalIP {} "
2642 + "in router with id {}",
2643 protocol, interfaceName, internalIp, routerId);
2646 // delete the entry from SnatIntIpPortMap DS
2647 LOG.debug("removeSnatEntriesForPort: Removing InternalIp :{} of router {} from snatint-ip-port-map",
2648 internalIp, routerId);
2649 naptManager.removeFromSnatIpPortDS(routerId, internalIp);
2653 private static List<String> getFixedIpsForPort(NeutronvpnService neutronVpnService, String interfname) {
2654 LOG.debug("getFixedIpsForPort: getFixedIpsForPort method is called for interface {}", interfname);
2656 Future<RpcResult<GetFixedIPsForNeutronPortOutput>> result =
2657 neutronVpnService.getFixedIPsForNeutronPort(new GetFixedIPsForNeutronPortInputBuilder()
2658 .setPortId(new Uuid(interfname)).build());
2660 RpcResult<GetFixedIPsForNeutronPortOutput> rpcResult = result.get();
2661 if (!rpcResult.isSuccessful()) {
2662 LOG.error("getFixedIpsForPort: RPC Call to GetFixedIPsForNeutronPortOutput returned with Errors {}",
2663 rpcResult.getErrors());
2665 return rpcResult.getResult().getFixedIPs();
2667 } catch (InterruptedException | ExecutionException | NullPointerException ex) {
2668 LOG.error("getFixedIpsForPort: Exception while receiving fixedIps for port {}", interfname, ex);
2673 private static List<ProtocolTypes> getPortocolList() {
2674 List<ProtocolTypes> protocollist = new ArrayList<>();
2675 protocollist.add(ProtocolTypes.TCP);
2676 protocollist.add(ProtocolTypes.UDP);
2677 return protocollist;
2680 private static void removeNatFlow(IMdsalApiManager mdsalManager, BigInteger dpnId, short tableId, Long routerId,
2681 String ipAddress, int ipPort, String protocol) {
2683 String switchFlowRef = NatUtil.getNaptFlowRef(dpnId, tableId, String.valueOf(routerId), ipAddress, ipPort,
2685 FlowEntity snatFlowEntity = NatUtil.buildFlowEntity(dpnId, tableId, switchFlowRef);
2687 mdsalManager.removeFlow(snatFlowEntity);
2688 LOG.debug("removeNatFlow: Removed the flow in table {} for the switch with the DPN ID {} for "
2689 + "router {} ip {} port {}", tableId, dpnId, routerId, ipAddress, ipPort);
2692 public static String getDpnFromNodeRef(NodeRef node) {
2693 PathArgument pathArgument = Iterables.get(node.getValue().getPathArguments(), 1);
2694 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
2695 InstanceIdentifier.IdentifiableItem.class);
2696 NodeKey key = Arguments.checkInstanceOf(item.getKey(), NodeKey.class);
2697 String dpnKey = key.getId().getValue();
2698 String dpnID = null;
2699 if (dpnKey.contains(NatConstants.COLON_SEPARATOR)) {
2700 dpnID = new BigInteger(dpnKey.split(NatConstants.COLON_SEPARATOR)[1]).toString();