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 java.util.Objects.requireNonNull;
13 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
14 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
16 import com.google.common.base.Optional;
17 import com.google.common.base.Preconditions;
18 import com.google.common.base.Splitter;
19 import com.google.common.base.Strings;
21 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
22 import java.math.BigInteger;
23 import java.net.InetAddress;
24 import java.net.UnknownHostException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
32 import java.util.Objects;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.Future;
36 import java.util.stream.Collectors;
37 import javax.annotation.Nonnull;
38 import javax.annotation.Nullable;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
41 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
42 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
43 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
44 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
45 import org.opendaylight.genius.infra.Datastore.Configuration;
46 import org.opendaylight.genius.infra.Datastore.Operational;
47 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
48 import org.opendaylight.genius.infra.TypedReadTransaction;
49 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
50 import org.opendaylight.genius.infra.TypedWriteTransaction;
51 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
52 import org.opendaylight.genius.mdsalutil.ActionInfo;
53 import org.opendaylight.genius.mdsalutil.FlowEntity;
54 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
55 import org.opendaylight.genius.mdsalutil.GroupEntity;
56 import org.opendaylight.genius.mdsalutil.InstructionInfo;
57 import org.opendaylight.genius.mdsalutil.MDSALUtil;
58 import org.opendaylight.genius.mdsalutil.MatchInfo;
59 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
60 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
61 import org.opendaylight.genius.mdsalutil.NwConstants;
62 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
63 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
64 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
65 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
66 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
67 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
68 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
69 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
70 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
71 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
72 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
73 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
74 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
75 import org.opendaylight.netvirt.elanmanager.api.IElanService;
76 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
77 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
78 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
79 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
80 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
81 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
82 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
83 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
84 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
85 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
86 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
87 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
88 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
90 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
91 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
92 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.BridgeRefInfo;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntry;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.bridge.ref.info.BridgeRefEntryKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInputBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
244 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
246 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
247 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
248 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
249 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
250 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
251 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
252 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
253 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
254 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
255 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
256 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
257 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
258 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
259 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
260 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
261 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
262 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
263 import org.opendaylight.yangtools.yang.binding.DataObject;
264 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
265 import org.opendaylight.yangtools.yang.common.RpcResult;
266 import org.slf4j.Logger;
267 import org.slf4j.LoggerFactory;
269 public final class NatUtil {
271 private static String OF_URI_SEPARATOR = ":";
272 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
273 private static final String OTHER_CONFIG_PARAMETERS_DELIMITER = ",";
274 private static final String OTHER_CONFIG_KEY_VALUE_DELIMITER = ":";
275 private static final String PROVIDER_MAPPINGS = "provider_mappings";
277 private NatUtil() { }
280 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
283 public static BigInteger getCookieSnatFlow(long routerId) {
284 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
285 BigInteger.valueOf(routerId));
289 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
292 public static BigInteger getCookieNaptFlow(long routerId) {
293 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
294 BigInteger.valueOf(routerId));
298 getVpnId() returns the VPN ID from the VPN name
300 public static long getVpnId(DataBroker broker, @Nullable String vpnName) {
301 if (vpnName == null) {
302 return NatConstants.INVALID_ID;
305 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
306 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
307 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
308 .instance.to.vpn.id.VpnInstance> vpnInstance =
309 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
310 LogicalDatastoreType.CONFIGURATION, id);
312 long vpnId = NatConstants.INVALID_ID;
313 if (vpnInstance.isPresent()) {
314 Long vpnIdAsLong = vpnInstance.get().getVpnId();
315 if (vpnIdAsLong != null) {
322 public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
323 if (vpnName == null) {
324 return NatConstants.INVALID_ID;
328 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
329 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
330 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
331 } catch (InterruptedException | ExecutionException e) {
332 LOG.error("Error retrieving VPN id for {}", vpnName, e);
335 return NatConstants.INVALID_ID;
338 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
339 //Get the external network ID from the ExternalRouter model
340 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
341 if (networkId == null) {
342 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
343 return NatConstants.INVALID_ID;
346 //Get the VPN ID from the ExternalNetworks model
347 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
348 if (vpnUuid == null) {
349 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
350 return NatConstants.INVALID_ID;
352 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
356 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
357 return InstanceIdentifier.builder(FloatingIpInfo.class)
358 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
361 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
362 return InstanceIdentifier.builder(RouterToVpnMapping.class)
363 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
366 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
367 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
368 .child(Ports.class, new PortsKey(portName)).build();
371 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
373 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
374 .child(Ports.class, new PortsKey(portName))
375 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
378 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
379 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
380 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
381 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
382 .instance.to.vpn.id.VpnInstance.class,
383 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
384 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
388 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
389 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
390 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
391 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
392 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
396 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
398 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
399 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
400 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
403 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
404 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
405 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
408 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
409 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
410 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
415 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
416 String routerName = getRouterName(broker, routerId);
417 if (routerName == null) {
418 LOG.error("getNetworkIdFromRouterId - empty routerName received");
421 return getNetworkIdFromRouterName(broker, routerName);
425 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
426 if (routerName == null) {
427 LOG.error("getNetworkIdFromRouterName - empty routerName received");
430 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
431 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
432 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
435 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
436 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
437 .child(Routers.class, new RoutersKey(routerId)).build();
438 return routerInstanceIndentifier;
441 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
442 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
443 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
448 * Return if SNAT is enabled for the given router.
450 * @param broker The DataBroker
451 * @param routerId The router
452 * @return boolean true if enabled, otherwise false
454 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
455 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
456 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
457 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
461 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
462 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
463 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
464 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
468 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
470 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
471 } catch (InterruptedException | ExecutionException e) {
472 LOG.error("Error reading network VPN id for {}", networkId, e);
478 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
479 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
480 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
481 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
485 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
486 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
488 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
489 } catch (InterruptedException | ExecutionException e) {
490 LOG.error("Error retrieving provider type for {}", networkId, e);
496 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
497 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
498 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
499 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse(
504 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
505 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
506 Optional<Routers> routerData =
507 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
508 LogicalDatastoreType.CONFIGURATION, id);
509 if (routerData.isPresent()) {
510 Uuid networkId = routerData.get().getNetworkId();
511 if (networkId != null) {
512 return networkId.getValue();
515 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
519 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
520 return InstanceIdentifier.builder(ExternalNetworks.class)
521 .child(Networks.class, new NetworksKey(networkId)).build();
525 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
526 // convert routerId to Name
527 String routerName = getRouterName(broker, routerId);
528 if (routerName == null) {
529 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
532 return getPrimaryNaptfromRouterName(broker, routerName);
536 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
537 if (routerName == null) {
538 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
541 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
542 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
543 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
547 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
548 return InstanceIdentifier.builder(NaptSwitches.class).child(RouterToNaptSwitch.class,
549 new RouterToNaptSwitchKey(routerId)).build();
552 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
553 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
554 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
558 public static String getRouterName(DataBroker broker, Long routerId) {
559 return getVpnInstanceFromVpnIdentifier(broker, routerId);
562 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
563 return InstanceIdentifier.builder(VpnInstanceOpData.class)
564 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
567 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
568 return new FlowEntityBuilder()
576 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
577 return new FlowEntityBuilder()
584 public static long getIpAddress(byte[] rawIpAddress) {
585 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
586 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
590 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
591 String nextHopIp = null;
592 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
593 InstanceIdentifier.builder(DpnEndpoints.class)
594 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
595 Optional<DPNTEPsInfo> tunnelInfo =
596 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
597 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
598 if (tunnelInfo.isPresent()) {
599 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
600 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
601 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
608 public static String getVpnRd(DataBroker broker, String vpnName) {
609 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
610 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
611 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
612 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
613 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
614 .VpnInstance::getVrfId).orElse(null);
618 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
620 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
621 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
622 .VpnInstance::getVrfId).orElse(null);
623 } catch (InterruptedException | ExecutionException e) {
624 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
630 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
631 String internalPort, NAPTEntryEvent.Protocol protocol) {
632 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
633 InstanceIdentifier<IpPortMap> ipPortMapId =
634 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
635 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
636 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
640 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
642 ProtocolTypes protocolType) {
643 return InstanceIdentifier.builder(IntextIpPortMap.class)
644 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
645 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
646 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
649 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
650 return InstanceIdentifier.builder(VpnInterfaces.class)
651 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
655 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
656 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
657 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
658 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
662 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
664 * NodeConnectorId is of form 'openflow:dpnid:portnum'
666 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
667 if (split.length != 3) {
668 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
674 public static BigInteger getDpIdFromInterface(
675 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
676 .state.Interface ifState) {
677 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
678 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
679 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
683 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
684 // returns only router, attached to IPv4 networks
685 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
686 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
687 Optional<VpnMap> optionalVpnMap =
688 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
689 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
690 if (!optionalVpnMap.isPresent()) {
691 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
694 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
695 if (routerIdsList != null && !routerIdsList.isEmpty()) {
696 for (Uuid routerUuid : routerIdsList) {
697 InstanceIdentifier<Router> routerIdentifier = buildNeutronRouterIdentifier(routerUuid);
698 Optional<Router> optRouter = SingleTransactionDataBroker
699 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
700 LogicalDatastoreType.CONFIGURATION, routerIdentifier);
701 if (!optRouter.isPresent()) {
704 List<Routes> routes = optRouter.get().getRoutes();
705 if (routes == null || routes.isEmpty()) {
708 for (Routes r : routes) {
709 if (r.getDestination().getIpv4Prefix() != null) {
710 return routerUuid.getValue();
715 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
720 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
721 Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
722 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
723 Optional<VpnMaps> optionalVpnMaps =
724 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
725 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
726 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
727 for (VpnMap vpnMap : requireNonNullElse(optionalVpnMaps.get().getVpnMap(),
728 Collections.<VpnMap>emptyList())) {
729 if (routerId.equals(vpnMap.getVpnId().getValue())) {
732 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
733 if (routerIdsList.isEmpty()) {
736 // Skip router vpnId fetching from internet BGP-VPN
737 if (vpnMap.getNetworkIds() != null && !vpnMap.getNetworkIds().isEmpty()) {
738 // We only need to check the first network; if it’s not an external network there’s no
739 // need to check the rest of the VPN’s network list
740 if (isExternalNetwork(broker, vpnMap.getNetworkIds().iterator().next())) {
744 if (routerIdsList.contains(new Uuid(routerId))) {
745 return vpnMap.getVpnId();
749 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
753 static long getAssociatedVpn(DataBroker broker, String routerName) {
754 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
755 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
756 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
757 NatConstants.INVALID_ID);
761 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
762 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
763 if (vpnUuid == null) {
764 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
767 return vpnUuid.getValue();
771 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
772 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
773 if (vpnUuid == null) {
774 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
777 return vpnUuid.getValue();
780 // TODO Clean up the exception handling
781 @SuppressWarnings("checkstyle:IllegalCatch")
782 public static void addPrefixToBGP(DataBroker broker,
783 IBgpManager bgpManager,
784 IFibManager fibManager,
789 @Nullable String parentVpnRd,
790 @Nullable String macAddress,
796 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
797 prefix, nextHopIp, label);
798 if (nextHopIp == null) {
799 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
804 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
805 dpId, Prefixes.PrefixCue.Nat);
806 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
807 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
808 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
809 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
810 /* Publish to Bgp only if its an INTERNET VPN */
811 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
812 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
813 null /*gatewayMac*/);
815 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
816 prefix, nextHopIp, label);
817 } catch (Exception e) {
818 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
819 prefix, nextHopIp, label, e);
823 static void addPrefixToInterface(DataBroker broker, long vpnId, @Nullable String interfaceName, String ipPrefix,
824 String networkId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
825 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
826 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
827 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
828 .to._interface.VpnIdsKey(vpnId))
829 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
830 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
831 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
832 prefixBuilder.setNetworkId(new Uuid(networkId));
834 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
835 prefixBuilder.build());
836 } catch (TransactionCommitFailedException e) {
837 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
838 ipPrefix, vpnId, dpId, e);
842 public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
844 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
845 InstanceIdentifier.builder(PrefixToInterface.class)
846 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
847 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
848 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
850 } catch (TransactionCommitFailedException e) {
851 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
856 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
857 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
858 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
862 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
863 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
864 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
865 return routerInstanceIndentifier;
869 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
870 String internalIpAddress, ProtocolTypes protocolType) {
871 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
872 LogicalDatastoreType.CONFIGURATION,
873 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
874 IntIpProtoType::getPorts).orElse(emptyList());
877 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
878 String internalIpAddress,
879 ProtocolTypes protocolType) {
880 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
881 InstanceIdentifier.builder(SnatintIpPortMap.class)
882 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
883 .child(IpPort.class, new IpPortKey(internalIpAddress))
884 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
885 return intIpProtocolTypeId;
888 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
889 String internalIpAddress) {
890 InstanceIdentifier<IpPort> intIpProtocolTypeId =
891 InstanceIdentifier.builder(SnatintIpPortMap.class)
892 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
893 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
894 return intIpProtocolTypeId;
898 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
899 String internalIpAddress) {
900 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
901 LogicalDatastoreType.CONFIGURATION,
902 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
905 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
906 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
907 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
911 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
912 return InstanceIdentifier.create(NaptSwitches.class);
915 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
916 return InstanceIdentifier.create(NaptSwitches.class)
917 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
920 public static String getGroupIdKey(String routerName) {
921 return "snatmiss." + routerName;
924 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
925 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
926 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
929 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
930 RpcResult<AllocateIdOutput> rpcResult = result.get();
931 return rpcResult.getResult().getIdValue();
932 } catch (NullPointerException | InterruptedException | ExecutionException e) {
933 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
938 // TODO Clean up the exception handling
939 @SuppressWarnings("checkstyle:IllegalCatch")
940 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
941 String rd, String prefix, String vpnName, Logger log) {
943 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
944 fibManager.removeFibEntry(rd, prefix, null);
945 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
946 bgpManager.withdrawPrefix(rd, prefix);
948 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
949 } catch (Exception e) {
950 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
951 rd, prefix, vpnName, e);
956 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
957 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
958 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
961 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
962 return InstanceIdentifier.builder(IntextIpPortMap.class)
963 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
966 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
967 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
968 return InstanceIdentifier.builder(IntextIpMap.class)
969 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
970 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
971 .intext.ip.map.IpMappingKey(routerId))
976 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
977 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
978 .ip.map.IpMapping> ipMappingOptional =
979 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
980 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
981 // Ensure there are no duplicates
982 Collection<String> externalIps = new HashSet<>();
983 if (ipMappingOptional.isPresent()) {
984 for (IpMap ipMap : requireNonNullElse(ipMappingOptional.get().getIpMap(), Collections.<IpMap>emptyList())) {
985 externalIps.add(ipMap.getExternalIp());
992 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
993 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
994 if (routerData != null) {
995 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
1002 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
1003 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
1004 .ip.map.IpMapping> ipMappingOptional =
1005 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1006 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
1007 Map<String, Long> externalIpsLabel = new HashMap<>();
1008 if (ipMappingOptional.isPresent()) {
1009 for (IpMap ipMap : requireNonNullElse(ipMappingOptional.get().getIpMap(), Collections.<IpMap>emptyList())) {
1010 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
1013 return externalIpsLabel;
1017 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
1018 String leastLoadedExternalIp = null;
1019 InstanceIdentifier<ExternalCounters> id =
1020 InstanceIdentifier.builder(ExternalIpsCounter.class)
1021 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
1022 Optional<ExternalCounters> externalCountersData =
1023 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1024 if (externalCountersData.isPresent()) {
1025 ExternalCounters externalCounter = externalCountersData.get();
1026 short countOfLstLoadExtIp = 32767;
1027 for (ExternalIpCounter externalIpCounter : requireNonNullElse(externalCounter.getExternalIpCounter(),
1028 Collections.<ExternalIpCounter>emptyList())) {
1029 String curExternalIp = externalIpCounter.getExternalIp();
1030 short countOfCurExtIp = externalIpCounter.getCounter();
1031 if (countOfCurExtIp < countOfLstLoadExtIp) {
1032 countOfLstLoadExtIp = countOfCurExtIp;
1033 leastLoadedExternalIp = curExternalIp;
1037 return leastLoadedExternalIp;
1040 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
1042 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
1043 String subnetIP = getSubnetIp(dataBroker, subnetId);
1044 if (subnetIP != null) {
1045 return getSubnetIpAndPrefix(subnetIP);
1047 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1052 public static String[] getSubnetIpAndPrefix(String subnetString) {
1053 String[] subnetSplit = subnetString.split("/");
1054 String subnetIp = subnetSplit[0];
1055 String subnetPrefix = "0";
1056 if (subnetSplit.length == 2) {
1057 subnetPrefix = subnetSplit[1];
1059 return new String[] {subnetIp, subnetPrefix};
1063 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1064 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1065 .builder(Subnetmaps.class)
1066 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1068 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1069 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1072 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1073 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1074 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1075 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1076 if (leastLoadedExtIpAddrSplit.length == 2) {
1077 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1079 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1083 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1084 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1085 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1086 Optional<RouterDpnList> routerDpnListData =
1087 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1088 LogicalDatastoreType.OPERATIONAL, id);
1089 List<BigInteger> dpns = new ArrayList<>();
1090 if (routerDpnListData.isPresent()) {
1091 for (DpnVpninterfacesList dpnVpnInterface : requireNonNullElse(
1092 routerDpnListData.get().getDpnVpninterfacesList(), Collections.<DpnVpninterfacesList>emptyList())) {
1093 dpns.add(dpnVpnInterface.getDpnId());
1099 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1100 long bgpVpnId = NatConstants.INVALID_ID;
1101 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1102 if (bgpVpnUuid != null) {
1103 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1109 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1110 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1111 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1112 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1115 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1116 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1117 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1118 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1119 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1120 .RouterInterface.class,
1121 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1122 .RouterInterfaceKey(interfaceName)).build();
1125 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1126 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1128 if (dpId.equals(BigInteger.ZERO)) {
1129 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1130 + "to handle router {} association model", interfaceName, routerName);
1134 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1135 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1136 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1138 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1139 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1140 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1141 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1142 .setInterface(interfaceName).build();
1143 if (optionalDpnVpninterfacesList.isPresent()) {
1144 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1145 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1146 operTx.merge(dpnVpnInterfacesListIdentifier
1147 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1148 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1149 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1151 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1152 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1153 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1154 routerDpnListBuilder.setRouterId(routerName);
1155 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1156 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1157 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1158 routerInterfaces.add(routerInterface);
1159 dpnVpnList.setRouterInterfaces(routerInterfaces);
1160 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1161 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1165 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1166 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1167 if (dpId.equals(BigInteger.ZERO)) {
1168 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1169 + "association model", interfaceName, routerName);
1173 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1174 + "DPNRouters map", dpId, routerName, interfaceName);
1175 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1177 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1179 if (optionalDpnRoutersList.isPresent()) {
1180 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1181 .setRouter(routerName).build();
1182 List<RoutersList> routersListFromDs = requireNonNullElse(optionalDpnRoutersList.get().getRoutersList(),
1184 if (!routersListFromDs.contains(routersList)) {
1185 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1186 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1187 operTx.merge(dpnRoutersListIdentifier
1188 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1190 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1191 + "DPNRouters map", routerName, dpId);
1194 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1195 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1196 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1197 dpnRoutersListBuilder.setDpnId(dpId);
1198 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1199 routersListBuilder.setRouter(routerName);
1200 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1201 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1205 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1206 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1207 if (dpId.equals(BigInteger.ZERO)) {
1208 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1212 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1213 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1214 if (optionalRouterDpnList.isPresent()) {
1215 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1216 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1217 operTx.delete(routerDpnListIdentifier);
1219 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1220 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1224 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1225 BigInteger dpId, @Nonnull TypedReadWriteTransaction<Operational> operTx) {
1226 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1227 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1229 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1230 } catch (InterruptedException | ExecutionException e) {
1231 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1232 optionalRouterDpnList = Optional.absent();
1234 if (optionalRouterDpnList.isPresent()) {
1235 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1236 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1237 optionalRouterDpnList.get().getRouterInterfaces();
1238 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1239 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1240 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1241 .setInterface(vpnInterfaceName).build();
1243 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1244 if (routerInterfaces.isEmpty()) {
1245 operTx.delete(routerDpnListIdentifier);
1247 operTx.delete(routerDpnListIdentifier.child(
1248 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1249 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1250 new RouterInterfacesKey(vpnInterfaceName)));
1256 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1257 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1258 throws ExecutionException, InterruptedException {
1260 1) Get the DpnRoutersList for the DPN.
1261 2) Get the RoutersList identifier for the DPN and router.
1262 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1263 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1264 then remove RouterList.
1267 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1268 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1270 //Get the dpn-routers-list instance for the current DPN.
1271 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1272 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1274 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1275 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1276 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1280 //Get the routers-list instance for the router on the current DPN only
1281 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1282 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1284 if (routersListData == null || !routersListData.isPresent()) {
1285 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1286 + "in the ODL-L3VPN:dpn-routers model",
1291 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1292 + "from the NeutronVPN - router-interfaces-map", routerName);
1293 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1294 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1295 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1296 .RouterInterfaces> routerInterfacesData =
1297 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1298 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1300 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1301 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1302 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1303 curDpnId, routerName, routerName);
1304 operTx.delete(routersListIdentifier);
1308 //Get the VM interfaces for the router on the current DPN only.
1309 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1310 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1311 if (vmInterfaces == null) {
1312 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1313 + "NeutronVPN - router-interfaces-map", routerName);
1317 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1318 // then remove RouterList.
1319 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1320 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1321 String vmInterfaceName = vmInterface.getInterfaceId();
1322 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1323 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1324 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1325 + "the DPN ID {} for the checked interface {}",
1326 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1329 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1330 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1331 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1335 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1336 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1337 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1338 operTx.delete(routersListIdentifier);
1341 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1342 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1343 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1344 .rev150602.RouterInterfacesMap.class)
1345 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1346 .interfaces.map.RouterInterfaces.class,
1347 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1348 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1351 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1352 return InstanceIdentifier.builder(DpnRouters.class)
1353 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1354 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1357 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1358 BigInteger nodeId = BigInteger.ZERO;
1360 GetDpidFromInterfaceInput
1362 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1363 Future<RpcResult<GetDpidFromInterfaceOutput>>
1365 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1366 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1367 if (dpIdResult.isSuccessful()) {
1368 nodeId = dpIdResult.getResult().getDpid();
1370 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1372 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1373 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1379 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1380 ItmRpcService itmRpcService,
1381 IInterfaceManager interfaceManager, String ifName,
1382 Long tunnelKey, boolean internalTunnelInterface) {
1383 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1384 ifName, tunnelKey, 0, internalTunnelInterface);
1388 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1389 ItmRpcService itmRpcService,
1390 IInterfaceManager interfaceManager,
1391 String ifName, @Nullable Long tunnelKey, int pos,
1392 boolean internalTunnelInterface) {
1393 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1394 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1395 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1396 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1397 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1398 if (tunnelKey != null) {
1399 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1400 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1401 } //init builders, ITM/IFM rpc can be called based on type of interface
1404 List<Action> actions = emptyList();
1405 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1406 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1407 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1408 if (!rpcResult.isSuccessful()) {
1409 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1410 + "returned with Errors {}", ifName, rpcResult.getErrors());
1412 actions = rpcResult.getResult().getAction();
1415 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1416 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1417 if (!rpcResult.isSuccessful()) {
1418 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1419 + "returned with Errors {}", ifName, rpcResult.getErrors());
1421 actions = rpcResult.getResult().getAction();
1424 List<ActionInfo> listActionInfo = new ArrayList<>();
1425 for (Action action : requireNonNullElse(actions, Collections.<Action>emptyList())) {
1426 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1427 actionClass = action.getAction();
1428 if (actionClass instanceof OutputActionCase) {
1429 listActionInfo.add(new ActionOutput(pos++,
1430 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1431 } else if (actionClass instanceof PushVlanActionCase) {
1432 listActionInfo.add(new ActionPushVlan(pos++));
1433 } else if (actionClass instanceof SetFieldCase) {
1434 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1435 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1436 .getVlanId().getValue();
1437 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1439 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1440 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1441 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1442 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1443 NxRegLoad nxRegLoad =
1444 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1445 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1446 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1449 return listActionInfo;
1450 } catch (InterruptedException | ExecutionException e) {
1451 LOG.error("Exception when egress actions for interface {}", ifName, e);
1453 LOG.error("Error when getting egress actions for interface {}", ifName);
1458 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1459 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1463 public static List<Port> getNeutronPorts(DataBroker broker) {
1464 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1465 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1466 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1467 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1469 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1470 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1472 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1473 LOG.error("getNeutronPorts : No neutron ports found");
1477 return portsOptional.get().getPort();
1481 public static Port getNeutronPortForIp(DataBroker broker, IpAddress targetIP, String deviceType) {
1482 List<Port> ports = getNeutronPorts(
1485 for (Port port : ports) {
1486 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1487 for (FixedIps ip : port.getFixedIps()) {
1488 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1494 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1499 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1501 LOG.error("getSubnetIdForFloatingIp : port is null");
1504 for (FixedIps ip : requireNonNullElse(port.getFixedIps(), Collections.<FixedIps>emptyList())) {
1505 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1506 return ip.getSubnetId();
1509 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1514 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1515 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1516 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1517 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1518 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1522 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1523 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1524 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1525 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1526 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1531 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1532 if (subnetId == null) {
1533 LOG.error("getSubnetGwMac : subnetID is null");
1537 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1538 .child(Subnet.class, new SubnetKey(subnetId));
1539 Optional<Subnet> subnetOpt =
1540 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1541 LogicalDatastoreType.CONFIGURATION, subnetInst);
1542 if (!subnetOpt.isPresent()) {
1543 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1547 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1548 if (gatewayIp == null) {
1549 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1553 if (null != gatewayIp.getIpv6Address()) {
1557 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1558 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1560 Optional<VpnPortipToPort> portIpToPortOpt =
1561 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1562 LogicalDatastoreType.CONFIGURATION, portIpInst);
1563 if (portIpToPortOpt.isPresent()) {
1564 return portIpToPortOpt.get().getMacAddress();
1567 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1568 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1570 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1571 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1572 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1573 if (learntIpToPortOpt.isPresent()) {
1574 return learntIpToPortOpt.get().getMacAddress();
1577 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1581 public static boolean isIPv6Subnet(String prefix) {
1582 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1585 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1586 return InstanceIdentifier.builder(DpnRouters.class)
1587 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1590 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1591 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1592 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1593 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1596 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1597 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1598 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1602 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1603 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1604 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1605 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1606 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1610 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1611 Uuid floatingIpId) {
1613 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1614 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1615 } catch (InterruptedException | ExecutionException e) {
1616 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1622 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1623 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1624 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1625 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1626 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1630 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1631 Uuid floatingIpId) {
1633 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1634 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1635 } catch (InterruptedException | ExecutionException e) {
1636 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1641 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1642 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1643 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1647 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1648 InstanceIdentifier<Interface> ifStateId =
1649 buildStateInterfaceId(interfaceName);
1650 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1651 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1654 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1655 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1656 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1657 .interfaces.rev140508.InterfacesState.class)
1658 .child(Interface.class,
1659 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1660 .interfaces.state.InterfaceKey(interfaceName));
1661 return idBuilder.build();
1665 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1666 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1667 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1668 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1672 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1674 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1675 } catch (InterruptedException | ExecutionException e) {
1676 LOG.error("Error reading router {}", routerName, e);
1681 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1682 if (routerId == NatConstants.INVALID_ID) {
1683 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1686 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1687 .setRouterId(routerId).setRouterName(routerName).build();
1688 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1692 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1693 IdManagerService idManager) {
1694 InetAddress defaultIP = null;
1696 defaultIP = InetAddress.getByName("0.0.0.0");
1697 } catch (UnknownHostException e) {
1698 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1699 + "Default Route to NAT.", e);
1703 List<MatchInfo> matches = new ArrayList<>();
1704 matches.add(MatchEthernetType.IPV4);
1705 //add match for vrfid
1706 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1708 List<InstructionInfo> instructions = new ArrayList<>();
1709 List<ActionInfo> actionsInfo = new ArrayList<>();
1710 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1711 actionsInfo.add(new ActionGroup(groupId));
1712 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1713 instructions.add(new InstructionApplyActions(actionsInfo));
1714 return MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1715 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1716 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1720 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1721 String routerName = getRouterName(broker, routerId);
1722 if (routerName == null) {
1723 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1726 return getExtGwMacAddFromRouterName(broker, routerName);
1730 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1731 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1732 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1733 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1737 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1739 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1740 Routers::getExtGwMacAddress).orElse(null);
1741 } catch (InterruptedException | ExecutionException e) {
1742 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1747 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1748 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1749 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1750 .child(Router.class, new RouterKey(routerUuid));
1751 return routerInstanceIdentifier;
1755 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1756 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1757 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1758 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1763 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1764 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1765 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1766 LogicalDatastoreType.CONFIGURATION,
1767 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(emptyList());
1771 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1772 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1773 Optional<ExternalNetworks> externalNwData =
1774 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1775 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1776 if (externalNwData.isPresent()) {
1777 for (Networks externalNw : requireNonNullElse(externalNwData.get().getNetworks(),
1778 Collections.<Networks>emptyList())) {
1779 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1780 return requireNonNullElse(externalNw.getRouterIds(), emptyList());
1787 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1790 long ipLo = ipToLong(InetAddress.getByName(start));
1791 long ipHi = ipToLong(InetAddress.getByName(end));
1792 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1793 return ipToTest >= ipLo && ipToTest <= ipHi;
1794 } catch (UnknownHostException e) {
1795 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1801 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1802 if (externalIps == null) {
1803 return Collections.emptySet();
1806 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1810 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, @Nullable String routerName) {
1811 if (routerName == null) {
1812 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1813 return Collections.emptySet();
1816 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1817 Optional<Routers> routerData =
1818 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1819 LogicalDatastoreType.CONFIGURATION, id);
1820 if (routerData.isPresent()) {
1821 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1823 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1824 return Collections.emptySet();
1829 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1830 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, 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();
1841 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1842 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1846 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1847 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1848 if (subnetId == null) {
1849 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1850 return Optional.absent();
1853 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1854 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1855 InstanceIdentifier.builder(ExternalSubnets.class)
1856 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1857 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1859 return tx.read(subnetsIdentifier).get();
1860 } catch (InterruptedException | ExecutionException e) {
1861 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1862 return Optional.absent();
1866 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1867 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1868 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1870 if (optionalExternalSubnets.isPresent()) {
1871 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1874 return NatConstants.INVALID_ID;
1877 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1878 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1879 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1881 if (optionalExternalSubnets.isPresent()) {
1882 return NatUtil.getVpnId(tx, subnetId.getValue());
1885 return NatConstants.INVALID_ID;
1888 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1890 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1891 if (externalSubnetId != null) {
1892 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1895 return NatConstants.INVALID_ID;
1899 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1900 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1901 for (ExternalIps extIp : requireNonNullElse(router.getExternalIps(), Collections.<ExternalIps>emptyList())) {
1902 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1903 if (extIpString.equals(externalIpAddress)) {
1904 return extIp.getSubnetId();
1907 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1911 private static long ipToLong(InetAddress ip) {
1912 byte[] octets = ip.getAddress();
1914 for (byte octet : octets) {
1916 result |= octet & 0xff;
1922 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1923 if (externalIps == null) {
1927 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1930 // elan-instances config container
1932 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1933 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1934 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1935 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1939 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1941 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1942 } catch (InterruptedException | ExecutionException e) {
1943 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1948 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1949 return InstanceIdentifier.builder(ElanInstances.class)
1950 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1953 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, NatOverVxlanUtil natOverVxlanUtil,
1954 IElanService elanManager, IdManagerService idManager,
1955 long routerId, String routerName) {
1956 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1957 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1958 return natOverVxlanUtil.getRouterVni(routerName, routerId).longValue();
1960 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1964 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1965 short tableId, TypedWriteTransaction<Configuration> confTx) {
1966 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1967 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1969 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1970 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1971 List<MatchInfo> matches = new ArrayList<>();
1972 matches.add(MatchEthernetType.IPV4);
1973 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1974 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1975 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1976 matches, preDnatToSnatInstructions);
1978 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
1979 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1980 preDnatToSnatTableFlowEntity, naptDpnId);
1983 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
1984 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
1985 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1986 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1987 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1988 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
1989 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1990 flowRef, naptDpnId);
1993 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1994 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1995 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1998 public static boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1999 String vpnName, String externalIp,
2000 Boolean isMoreThanOneFipCheckOnDpn) {
2001 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
2002 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
2003 if (dpnInVpn.isPresent()) {
2004 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
2005 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
2007 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
2008 if (ipAddressList != null && !ipAddressList.isEmpty()) {
2009 int floatingIpPresentCount = 0;
2010 for (IpAddresses ipAddress: ipAddressList) {
2011 if (!Objects.equals(ipAddress.getIpAddress(), externalIp)
2012 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
2013 floatingIpPresentCount++;
2014 //Add tunnel table check
2015 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
2018 //Remove tunnel table check
2019 if (!isMoreThanOneFipCheckOnDpn) {
2025 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
2029 } catch (NullPointerException e) {
2030 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
2031 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
2038 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
2039 return InstanceIdentifier.builder(VpnInstanceOpData.class)
2040 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
2041 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
2045 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
2046 throws ExecutionException, InterruptedException {
2047 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
2050 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
2051 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
2052 Optional<VpnInstance> vpnInstance =
2053 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2054 LogicalDatastoreType.CONFIGURATION, id);
2055 if (vpnInstance.isPresent()) {
2056 return getPrimaryRd(vpnInstance.get());
2062 public static String getPrimaryRd(@Nullable VpnInstance vpnInstance) {
2063 if (vpnInstance == null) {
2066 List<String> rds = getListOfRdsFromVpnInstance(vpnInstance);
2067 return rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2070 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2071 return InstanceIdentifier.builder(VpnInstances.class)
2072 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2076 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2077 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2078 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2079 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2082 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
2083 if (routerName != null) {
2084 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
2085 if (extRouter != null) {
2086 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
2090 return NatConstants.INVALID_ID;
2093 public static String validateAndAddNetworkMask(String ipAddress) {
2094 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2097 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2098 String vpnInterfaceName, String vpnName) {
2099 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2100 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2104 public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
2105 InstanceIdentifier<VpnInstanceOpDataEntry> id = NatUtil.getVpnInstanceOpDataIdentifier(rd);
2106 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2107 broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
2110 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2111 String routerName, BigInteger dpnId) {
2112 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2113 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2115 if (networkData != null && networkData.isPresent()) {
2116 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2117 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2118 for (Uuid routerUuid : routerUuidList) {
2119 String sharedRouterName = routerUuid.getValue();
2120 if (!routerName.equals(sharedRouterName)) {
2121 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2122 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2123 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2124 + "associated with other active router {} on NAPT switch {}", networkId,
2125 sharedRouterName, switchDpnId);
2135 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2136 String routerName, BigInteger dpnId) {
2137 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2138 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2139 .subnets.Subnets::getRouterIds).orElse(emptyList());
2140 if (!routerUuidList.isEmpty()) {
2141 for (Uuid routerUuid : routerUuidList) {
2142 String sharedRouterName = routerUuid.getValue();
2143 if (!routerName.equals(sharedRouterName)) {
2144 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2145 if (switchDpnId != null && switchDpnId.equals(dpnId)) {
2146 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2147 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2148 sharedRouterName, switchDpnId);
2157 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2158 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2159 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2160 List<ExternalIps> externalIps = router.getExternalIps();
2161 List<String> externalIpsSting = new ArrayList<>();
2163 if (externalIps == null || externalIps.isEmpty()) {
2164 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2167 for (ExternalIps externalIp : externalIps) {
2168 externalIpsSting.add(externalIp.getIpAddress());
2170 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2171 if (addOrRemove == NwConstants.ADD_FLOW) {
2172 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2173 router.getNetworkId(), subnetVpnName.getValue(), tx);
2174 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2175 router.getExtGwMacAddress(), primarySwitchId,
2176 router.getNetworkId());
2178 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2179 router.getNetworkId(), subnetVpnName.getValue(), tx);
2180 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2181 router.getExtGwMacAddress(), primarySwitchId,
2182 router.getNetworkId());
2184 }), LOG, "Error installing router gateway flows");
2187 @SuppressWarnings("checkstyle:IllegalCatch")
2188 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2189 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2190 String routerName, long routerId, long routerVpnId,
2191 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2192 throws ExecutionException, InterruptedException {
2193 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2194 //remove miss entry to NAPT switch
2195 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2196 if (extNwProvType == null) {
2199 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2200 Map<String, Long> externalIpLabel;
2201 if (extNwProvType == ProviderTypes.VXLAN) {
2202 externalIpLabel = null;
2204 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2206 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2207 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2208 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2211 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2212 boolean naptStatus =
2213 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2214 externalIpCache, confTx);
2216 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2218 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
2219 FlowEntity flowEntity = null;
2221 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2222 NatConstants.DEL_FLOW);
2223 if (flowEntity == null) {
2224 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2225 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2228 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
2229 mdsalManager.removeFlow(confTx, flowEntity);
2231 } catch (Exception ex) {
2232 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2236 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2240 GroupEntity groupEntity = null;
2242 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2243 GroupTypes.GroupAll, emptyList() /*listBucketInfo*/);
2244 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2245 mdsalManager.removeGroup(groupEntity);
2246 } catch (Exception ex) {
2247 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2250 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2253 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2254 externalIpLabel, confTx);
2255 //remove table 26 flow ppointing to table46
2256 FlowEntity flowEntity = null;
2258 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2259 NatConstants.DEL_FLOW);
2260 if (flowEntity == null) {
2261 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2265 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2266 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2267 mdsalManager.removeFlow(confTx, flowEntity);
2269 } catch (Exception ex) {
2270 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2274 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2277 //best effort to check IntExt model
2278 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2282 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2283 ProviderTypes extNwProvType) {
2284 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2285 || extNwProvType == ProviderTypes.VXLAN)) {
2291 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2292 BigInteger dpnId, DataBroker dataBroker) {
2293 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2294 elanInstanceName,dpnId);
2296 synchronized (elanInstanceName.intern()) {
2297 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2298 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2299 List<String> elanInterfaceList;
2300 DpnInterfaces dpnInterface;
2301 if (!dpnInElanInterfaces.isPresent()) {
2302 elanInterfaceList = new ArrayList<>();
2304 dpnInterface = dpnInElanInterfaces.get();
2305 elanInterfaceList = dpnInterface.getInterfaces();
2307 if (!elanInterfaceList.contains(pseudoPortId)) {
2308 elanInterfaceList.add(pseudoPortId);
2309 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2310 .withKey(new DpnInterfacesKey(dpnId)).build();
2311 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2312 elanDpnInterfaceId, dpnInterface);
2315 } catch (ReadFailedException e) {
2316 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2317 } catch (TransactionCommitFailedException e) {
2318 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2322 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2323 BigInteger dpnId, DataBroker dataBroker) {
2324 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2325 elanInstanceName,dpnId);
2327 synchronized (elanInstanceName.intern()) {
2328 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2329 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2330 List<String> elanInterfaceList;
2331 DpnInterfaces dpnInterface;
2332 if (!dpnInElanInterfaces.isPresent()) {
2333 LOG.info("No interface in any dpn for {}", elanInstanceName);
2336 dpnInterface = dpnInElanInterfaces.get();
2337 elanInterfaceList = dpnInterface.getInterfaces();
2339 if (!elanInterfaceList.contains(pseudoPortId)) {
2340 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2343 elanInterfaceList.remove(pseudoPortId);
2344 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2345 .withKey(new DpnInterfacesKey(dpnId)).build();
2346 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2347 elanDpnInterfaceId, dpnInterface);
2349 } catch (ReadFailedException e) {
2350 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2351 } catch (TransactionCommitFailedException e) {
2352 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2357 public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId,
2358 DataBroker broker) {
2359 InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId =
2360 getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
2361 DpnInterfaces dpnInterfaces = null;
2363 dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL,
2364 elanDpnInterfacesId);
2366 catch (ReadFailedException e) {
2367 LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
2369 return dpnInterfaces;
2372 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
2373 InstanceIdentifier<T> path) {
2374 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
2375 return tx.read(datastoreType, path).get();
2376 } catch (InterruptedException | ExecutionException e) {
2377 throw new RuntimeException(e);
2381 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2382 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2383 for (Map.Entry<String,Routers> router : extRouter) {
2384 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2385 .equals(networkid)) {
2392 public static InstanceIdentifier<ExtRouters> buildExtRouters() {
2393 InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
2395 return extRouterInstanceIndentifier;
2399 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2401 return SingleTransactionDataBroker.syncRead(dataBroker,
2402 LogicalDatastoreType.OPERATIONAL, getLearntVpnVipToPortDataId());
2404 catch (ReadFailedException e) {
2405 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2410 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2411 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2412 .builder(LearntVpnVipToPortData.class).build();
2413 return learntVpnVipToPortDataId;
2416 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2418 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2419 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2420 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2423 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2424 return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2425 .inventory.rev130819.nodes.Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2426 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2429 public static void createGroupIdPool(IdManagerService idManager) {
2430 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2431 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2432 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2433 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2436 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2437 if (result != null && result.get().isSuccessful()) {
2438 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2440 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2442 } catch (InterruptedException | ExecutionException e) {
2443 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2447 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2448 NodeId nodeId = new NodeId("openflow:" + switchId);
2449 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2450 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeInstanceId
2451 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight
2452 .inventory.rev130819.nodes.Node.class, new NodeKey(nodeId)).build();
2453 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node> nodeOptional =
2454 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2455 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2456 if (nodeOptional.isPresent()) {
2457 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2460 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);
2464 public static boolean isExternalNetwork(DataBroker broker, Uuid networkId) {
2465 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2466 Optional<Networks> networkData =
2467 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2468 broker, LogicalDatastoreType.CONFIGURATION, id);
2469 return networkData.isPresent();
2473 public static String getElanInstancePhysicalNetwok(String elanInstanceName, DataBroker broker) {
2474 ElanInstance elanInstance = getElanInstanceByName(elanInstanceName, broker);
2475 if (null != elanInstance) {
2476 return elanInstance.getPhysicalNetworkName();
2482 public static Map<String, String> getOpenvswitchOtherConfigMap(BigInteger dpnId, DataBroker dataBroker) {
2483 String otherConfigVal = getProviderMappings(dpnId, dataBroker);
2484 return getMultiValueMap(otherConfigVal);
2487 public static Map<String, String> getMultiValueMap(String multiKeyValueStr) {
2488 if (Strings.isNullOrEmpty(multiKeyValueStr)) {
2489 return Collections.emptyMap();
2492 Map<String, String> valueMap = new HashMap<>();
2493 Splitter splitter = Splitter.on(OTHER_CONFIG_PARAMETERS_DELIMITER);
2494 for (String keyValue : splitter.split(multiKeyValueStr)) {
2495 String[] split = keyValue.split(OTHER_CONFIG_KEY_VALUE_DELIMITER, 2);
2496 if (split.length == 2) {
2497 valueMap.put(split[0], split[1]);
2504 public static Optional<Node> getBridgeRefInfo(BigInteger dpnId, DataBroker dataBroker) {
2505 InstanceIdentifier<BridgeRefEntry> bridgeRefInfoPath = InstanceIdentifier.create(BridgeRefInfo.class)
2506 .child(BridgeRefEntry.class, new BridgeRefEntryKey(dpnId));
2508 Optional<BridgeRefEntry> bridgeRefEntry =
2509 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2510 LogicalDatastoreType.OPERATIONAL, bridgeRefInfoPath);
2511 if (!bridgeRefEntry.isPresent()) {
2512 LOG.info("getBridgeRefInfo : bridgeRefEntry is not present for {}", dpnId);
2513 return Optional.absent();
2516 InstanceIdentifier<Node> nodeId =
2517 bridgeRefEntry.get().getBridgeReference().getValue().firstIdentifierOf(Node.class);
2519 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2520 LogicalDatastoreType.OPERATIONAL, nodeId);
2524 public static String getProviderMappings(BigInteger dpId, DataBroker dataBroker) {
2525 return getBridgeRefInfo(dpId, dataBroker).toJavaUtil().map(node -> getOpenvswitchOtherConfigs(node,
2526 PROVIDER_MAPPINGS, dataBroker)).orElse(null);
2530 public static String getOpenvswitchOtherConfigs(Node node, String key, DataBroker dataBroker) {
2531 OvsdbNodeAugmentation ovsdbNode = node.augmentation(OvsdbNodeAugmentation.class);
2532 if (ovsdbNode == null) {
2533 Optional<Node> nodeFromReadOvsdbNode = readOvsdbNode(node, dataBroker);
2534 if (nodeFromReadOvsdbNode.isPresent()) {
2535 ovsdbNode = nodeFromReadOvsdbNode.get().augmentation(OvsdbNodeAugmentation.class);
2539 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
2540 for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
2541 if (Objects.equals(openvswitchOtherConfigs.getOtherConfigKey(), key)) {
2542 return openvswitchOtherConfigs.getOtherConfigValue();
2546 LOG.info("getOpenvswitchOtherConfigs : OtherConfigs is not present for ovsdbNode {}", node.getNodeId());
2551 public static Optional<Node> readOvsdbNode(Node bridgeNode, DataBroker dataBroker) {
2552 OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
2553 if (bridgeAugmentation != null) {
2554 InstanceIdentifier<Node> ovsdbNodeIid =
2555 (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
2556 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
2557 LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
2559 return Optional.absent();
2564 public static OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
2568 return node.augmentation(OvsdbBridgeAugmentation.class);
2571 // Use Objects.requireNonNullElse instead with JDK9+
2573 public static <T> T requireNonNullElse(@Nullable T obj, @Nonnull T defaultObj) {
2574 return obj != null ? obj : requireNonNull(defaultObj);
2577 public static String getDefaultFibRouteToSNATForSubnetJobKey(String subnetName, BigInteger dpnId) {
2578 return NatConstants.NAT_DJC_PREFIX + subnetName + dpnId;
2581 public static ExternalSubnets getExternalSubnets(DataBroker dataBroker) {
2582 InstanceIdentifier<ExternalSubnets> subnetsIdentifier =
2583 InstanceIdentifier.builder(ExternalSubnets.class)
2586 Optional<ExternalSubnets> optionalExternalSubnets = SingleTransactionDataBroker
2587 .syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
2588 if (optionalExternalSubnets.isPresent()) {
2589 return optionalExternalSubnets.get();
2591 } catch (ReadFailedException e) {
2592 LOG.error("Failed to read the subnets from the datastore.");
2598 public static void addFlow(TypedWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2599 BigInteger dpId, short tableId, String flowId, int priority, String flowName, BigInteger cookie,
2600 List<? extends MatchInfoBase> matches, List<InstructionInfo> instructions) {
2601 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
2602 NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
2604 LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
2605 mdsalManager.addFlow(confTx, flowEntity);
2608 public static void removeFlow(TypedReadWriteTransaction<Configuration> confTx, IMdsalApiManager mdsalManager,
2609 BigInteger dpId, short tableId, String flowId) throws ExecutionException, InterruptedException {
2610 LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
2611 mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
2614 public static String getIpv6FlowRef(BigInteger dpnId, short tableId, long routerID) {
2615 return new StringBuilder().append(NatConstants.IPV6_FLOWID_PREFIX).append(dpnId).append(NatConstants
2616 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
2619 public static String getTunnelInterfaceName(BigInteger srcDpId, BigInteger dstDpId,
2620 ItmRpcService itmManager) {
2621 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
2622 RpcResult<GetTunnelInterfaceNameOutput> rpcResult;
2624 Future<RpcResult<GetTunnelInterfaceNameOutput>> result = itmManager
2625 .getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder().setSourceDpid(srcDpId)
2626 .setDestinationDpid(dstDpId).setTunnelType(tunType).build());
2627 rpcResult = result.get();
2628 if (!rpcResult.isSuccessful()) {
2629 tunType = TunnelTypeGre.class ;
2630 result = itmManager.getTunnelInterfaceName(new GetTunnelInterfaceNameInputBuilder()
2631 .setSourceDpid(srcDpId)
2632 .setDestinationDpid(dstDpId)
2633 .setTunnelType(tunType)
2635 rpcResult = result.get();
2636 if (!rpcResult.isSuccessful()) {
2637 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2638 rpcResult.getErrors());
2640 return rpcResult.getResult().getInterfaceName();
2642 LOG.warn("getTunnelInterfaceName : RPC Call to getTunnelInterfaceId returned with Errors {}",
2643 rpcResult.getErrors());
2645 return rpcResult.getResult().getInterfaceName();
2647 } catch (InterruptedException | ExecutionException | NullPointerException e) {
2648 LOG.error("getTunnelInterfaceName : Exception when getting tunnel interface Id for tunnel "
2649 + "between {} and {}", srcDpId, dstDpId);
2654 public static String getIpv6JobKey(String routerName) {
2655 return "Ipv6." + routerName;