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 org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
12 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
14 import com.google.common.base.Optional;
15 import com.google.common.base.Preconditions;
16 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
17 import java.math.BigInteger;
18 import java.net.InetAddress;
19 import java.net.UnknownHostException;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
27 import java.util.Objects;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.Future;
31 import java.util.stream.Collectors;
32 import javax.annotation.Nonnull;
33 import javax.annotation.Nullable;
34 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
35 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
36 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
37 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
38 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
39 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
40 import org.opendaylight.genius.infra.Datastore.Configuration;
41 import org.opendaylight.genius.infra.Datastore.Operational;
42 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
43 import org.opendaylight.genius.infra.TypedReadTransaction;
44 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
45 import org.opendaylight.genius.infra.TypedWriteTransaction;
46 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
47 import org.opendaylight.genius.mdsalutil.ActionInfo;
48 import org.opendaylight.genius.mdsalutil.FlowEntity;
49 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
50 import org.opendaylight.genius.mdsalutil.GroupEntity;
51 import org.opendaylight.genius.mdsalutil.InstructionInfo;
52 import org.opendaylight.genius.mdsalutil.MDSALUtil;
53 import org.opendaylight.genius.mdsalutil.MatchInfo;
54 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
55 import org.opendaylight.genius.mdsalutil.NwConstants;
56 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
57 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
58 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
59 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
60 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
61 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
62 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
63 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
64 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
65 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
66 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
67 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
68 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
69 import org.opendaylight.netvirt.elanmanager.api.IElanService;
70 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
71 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
72 import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
73 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
74 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronUtils;
75 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
76 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
77 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
78 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
79 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
80 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
81 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
82 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
83 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefixBuilder;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
86 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelInputBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetEgressActionsForTunnelOutput;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfacesKey;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
168 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;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
207 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;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
209 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
210 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
211 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
212 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
213 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
214 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
215 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
216 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
217 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
218 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
219 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
220 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
221 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
222 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
223 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
224 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
225 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
226 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
227 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
228 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
229 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
230 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
231 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
232 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
233 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.l3.attributes.Routes;
234 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
235 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
236 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
237 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
238 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
239 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
240 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
241 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
242 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
243 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
244 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;
245 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
246 import org.opendaylight.yangtools.yang.binding.DataObject;
247 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
248 import org.opendaylight.yangtools.yang.common.RpcResult;
249 import org.slf4j.Logger;
250 import org.slf4j.LoggerFactory;
252 public final class NatUtil {
254 private static String OF_URI_SEPARATOR = ":";
255 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
257 private NatUtil() { }
260 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
263 public static BigInteger getCookieSnatFlow(long routerId) {
264 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
265 BigInteger.valueOf(routerId));
269 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
272 public static BigInteger getCookieNaptFlow(long routerId) {
273 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
274 BigInteger.valueOf(routerId));
278 getVpnId() returns the VPN ID from the VPN name
280 public static long getVpnId(DataBroker broker, String vpnName) {
281 if (vpnName == null) {
282 return NatConstants.INVALID_ID;
285 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
286 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
287 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
288 .instance.to.vpn.id.VpnInstance> vpnInstance =
289 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
290 LogicalDatastoreType.CONFIGURATION, id);
292 long vpnId = NatConstants.INVALID_ID;
293 if (vpnInstance.isPresent()) {
294 Long vpnIdAsLong = vpnInstance.get().getVpnId();
295 if (vpnIdAsLong != null) {
302 public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
303 if (vpnName == null) {
304 return NatConstants.INVALID_ID;
308 return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
309 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
310 .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
311 } catch (InterruptedException | ExecutionException e) {
312 LOG.error("Error retrieving VPN id for {}", vpnName, e);
315 return NatConstants.INVALID_ID;
318 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
319 //Get the external network ID from the ExternalRouter model
320 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
321 if (networkId == null) {
322 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
323 return NatConstants.INVALID_ID;
326 //Get the VPN ID from the ExternalNetworks model
327 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
328 if (vpnUuid == null) {
329 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
330 return NatConstants.INVALID_ID;
332 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
336 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
337 return InstanceIdentifier.builder(FloatingIpInfo.class)
338 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
341 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
342 return InstanceIdentifier.builder(RouterToVpnMapping.class)
343 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
346 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
347 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
348 .child(Ports.class, new PortsKey(portName)).build();
351 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
353 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
354 .child(Ports.class, new PortsKey(portName))
355 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
358 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
359 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
360 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
361 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
362 .instance.to.vpn.id.VpnInstance.class,
363 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
364 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
367 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
368 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
369 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
370 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
371 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
375 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
377 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
378 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
379 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
382 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
383 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
384 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
387 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
388 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
389 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
393 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
394 String routerName = getRouterName(broker, routerId);
395 if (routerName == null) {
396 LOG.error("getNetworkIdFromRouterId - empty routerName received");
399 return getNetworkIdFromRouterName(broker, routerName);
402 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
403 if (routerName == null) {
404 LOG.error("getNetworkIdFromRouterName - empty routerName received");
407 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
408 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
409 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
412 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
413 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
414 .child(Routers.class, new RoutersKey(routerId)).build();
415 return routerInstanceIndentifier;
418 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
419 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
420 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
425 * Return if SNAT is enabled for the given router.
427 * @param broker The DataBroker
428 * @param routerId The router
429 * @return boolean true if enabled, otherwise false
431 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
432 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
433 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
434 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
437 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
438 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
439 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
440 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
444 public static Uuid getVpnIdfromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
446 return tx.read(buildNetworkIdentifier(networkId)).get().toJavaUtil().map(Networks::getVpnid).orElse(null);
447 } catch (InterruptedException | ExecutionException e) {
448 LOG.error("Error reading network VPN id for {}", networkId, e);
453 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
454 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
455 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
456 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
460 public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
461 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
463 return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
464 } catch (InterruptedException | ExecutionException e) {
465 LOG.error("Error retrieving provider type for {}", networkId, e);
471 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
472 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
473 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
474 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse(
475 Collections.emptyList());
478 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
479 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
480 Optional<Routers> routerData =
481 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
482 LogicalDatastoreType.CONFIGURATION, id);
483 if (routerData.isPresent()) {
484 Uuid networkId = routerData.get().getNetworkId();
485 if (networkId != null) {
486 return networkId.getValue();
489 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
493 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
494 return InstanceIdentifier.builder(ExternalNetworks.class)
495 .child(Networks.class, new NetworksKey(networkId)).build();
498 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
499 // convert routerId to Name
500 String routerName = getRouterName(broker, routerId);
501 if (routerName == null) {
502 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
505 return getPrimaryNaptfromRouterName(broker, routerName);
508 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
509 if (routerName == null) {
510 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
513 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
514 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
515 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
519 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
520 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
521 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
525 public static Optional<NaptSwitches> getAllPrimaryNaptSwitches(DataBroker broker) {
526 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
527 LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
530 public static String getRouterName(DataBroker broker, Long routerId) {
531 return getVpnInstanceFromVpnIdentifier(broker, routerId);
534 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
535 return InstanceIdentifier.builder(VpnInstanceOpData.class)
536 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
539 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
540 return new FlowEntityBuilder()
548 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
549 return new FlowEntityBuilder()
556 public static long getIpAddress(byte[] rawIpAddress) {
557 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
558 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
561 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
562 String nextHopIp = null;
563 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
564 InstanceIdentifier.builder(DpnEndpoints.class)
565 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
566 Optional<DPNTEPsInfo> tunnelInfo =
567 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
568 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
569 if (tunnelInfo.isPresent()) {
570 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
571 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
572 nextHopIp = nexthopIpList.get(0).getIpAddress().stringValue();
578 public static String getVpnRd(DataBroker broker, String vpnName) {
580 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
581 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
582 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
583 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
584 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
585 .VpnInstance::getVrfId).orElse(null);
588 public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
590 return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
591 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
592 .VpnInstance::getVrfId).orElse(null);
593 } catch (InterruptedException | ExecutionException e) {
594 LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
599 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
600 String internalPort, NAPTEntryEvent.Protocol protocol) {
601 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
602 InstanceIdentifier<IpPortMap> ipPortMapId =
603 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
604 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
605 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
609 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
611 ProtocolTypes protocolType) {
612 return InstanceIdentifier.builder(IntextIpPortMap.class)
613 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
614 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
615 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
618 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
619 return InstanceIdentifier.builder(VpnInterfaces.class)
620 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
623 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
624 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
625 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
626 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
629 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
631 * NodeConnectorId is of form 'openflow:dpnid:portnum'
633 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
634 if (split.length != 3) {
635 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
641 public static BigInteger getDpIdFromInterface(
642 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
643 .state.Interface ifState) {
644 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
645 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
646 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
649 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
650 // returns only router, attached to IPv4 networks
651 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
652 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
653 Optional<VpnMap> optionalVpnMap =
654 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
655 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
656 if (!optionalVpnMap.isPresent()) {
657 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
660 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(optionalVpnMap.get().getRouterIds());
661 if (routerIdsList != null && !routerIdsList.isEmpty()) {
662 for (Uuid routerUuid : routerIdsList) {
663 InstanceIdentifier<Router> routerIdentifier = buildNeutronRouterIdentifier(routerUuid);
664 Optional<Router> optRouter = SingleTransactionDataBroker
665 .syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
666 LogicalDatastoreType.CONFIGURATION, routerIdentifier);
667 if (!optRouter.isPresent()) {
670 List<Routes> routes = optRouter.get().getRoutes();
671 if (routes == null || routes.isEmpty()) {
674 for (Routes r : routes) {
675 if (r.getDestination().getIpv4Prefix() != null) {
676 return routerUuid.getValue();
681 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
685 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
686 Preconditions.checkNotNull(routerId, "dissociateRouter: routerId not found!");
687 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
688 Optional<VpnMaps> optionalVpnMaps =
689 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
690 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
691 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
692 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
693 for (VpnMap vpnMap: allMaps) {
694 if (routerId.equals(vpnMap.getVpnId().getValue())) {
697 List<Uuid> routerIdsList = NeutronUtils.getVpnMapRouterIdsListUuid(vpnMap.getRouterIds());
698 if (routerIdsList == null || routerIdsList.isEmpty()) {
701 if (routerIdsList.contains(new Uuid(routerId))) {
702 return vpnMap.getVpnId();
706 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
710 static long getAssociatedVpn(DataBroker broker, String routerName) {
711 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
712 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
713 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
714 NatConstants.INVALID_ID);
717 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
718 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
719 if (vpnUuid == null) {
720 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
723 return vpnUuid.getValue();
726 public static String getAssociatedVPN(TypedReadTransaction<Configuration> tx, Uuid networkId) {
727 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(tx, networkId);
728 if (vpnUuid == null) {
729 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
732 return vpnUuid.getValue();
735 // TODO Clean up the exception handling
736 @SuppressWarnings("checkstyle:IllegalCatch")
737 public static void addPrefixToBGP(DataBroker broker,
738 IBgpManager bgpManager,
739 IFibManager fibManager,
752 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
753 prefix, nextHopIp, label);
754 if (nextHopIp == null) {
755 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
760 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, parentVpnRd,
761 subnetId, dpId, Prefixes.PrefixCue.Nat);
762 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
763 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
764 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
765 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
766 /* Publish to Bgp only if its an INTERNET VPN */
767 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
768 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
769 null /*gatewayMac*/);
771 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
772 prefix, nextHopIp, label);
773 } catch (Exception e) {
774 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
775 prefix, nextHopIp, label, e);
779 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
780 String networkId, Uuid subnetId, BigInteger dpId, Prefixes.PrefixCue prefixCue) {
781 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
782 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
783 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
784 .to._interface.VpnIdsKey(vpnId))
785 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
786 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
787 prefixBuilder.setVpnInterfaceName(interfaceName).setPrefixCue(prefixCue);
788 prefixBuilder.setNetworkId(new Uuid(networkId));
790 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
791 prefixBuilder.build());
792 } catch (TransactionCommitFailedException e) {
793 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
794 ipPrefix, vpnId, dpId, e);
798 public static void deletePrefixToInterface(DataBroker broker, long vpnId, String ipPrefix) {
800 SingleTransactionDataBroker.syncDelete(broker, LogicalDatastoreType.OPERATIONAL,
801 InstanceIdentifier.builder(PrefixToInterface.class)
802 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
803 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
804 .prefix.to._interface.VpnIdsKey(vpnId)).child(Prefixes.class, new PrefixesKey(ipPrefix))
806 } catch (TransactionCommitFailedException e) {
807 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for vpn-id {}",
812 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
813 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
814 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
818 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
819 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
820 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
821 return routerInstanceIndentifier;
825 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
826 String internalIpAddress, ProtocolTypes protocolType) {
827 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
828 LogicalDatastoreType.CONFIGURATION,
829 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
830 IntIpProtoType::getPorts).orElse(Collections.emptyList());
833 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
834 String internalIpAddress,
835 ProtocolTypes protocolType) {
836 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
837 InstanceIdentifier.builder(SnatintIpPortMap.class)
838 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
839 .child(IpPort.class, new IpPortKey(internalIpAddress))
840 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
841 return intIpProtocolTypeId;
844 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
845 String internalIpAddress) {
846 InstanceIdentifier<IpPort> intIpProtocolTypeId =
847 InstanceIdentifier.builder(SnatintIpPortMap.class)
848 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
849 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
850 return intIpProtocolTypeId;
854 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
855 String internalIpAddress) {
856 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
857 LogicalDatastoreType.CONFIGURATION,
858 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
861 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
862 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
863 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
867 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
868 return InstanceIdentifier.create(NaptSwitches.class);
871 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
872 return InstanceIdentifier.create(NaptSwitches.class)
873 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
876 public static String getGroupIdKey(String routerName) {
877 return "snatmiss." + routerName;
880 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
881 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
882 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
885 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
886 RpcResult<AllocateIdOutput> rpcResult = result.get();
887 return rpcResult.getResult().getIdValue();
888 } catch (NullPointerException | InterruptedException | ExecutionException e) {
889 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
894 // TODO Clean up the exception handling
895 @SuppressWarnings("checkstyle:IllegalCatch")
896 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
897 String rd, String prefix, String vpnName, Logger log) {
899 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
900 fibManager.removeFibEntry(rd, prefix, null);
901 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
902 bgpManager.withdrawPrefix(rd, prefix);
904 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
905 } catch (Exception e) {
906 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
907 rd, prefix, vpnName, e);
911 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
912 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
913 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
916 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
917 return InstanceIdentifier.builder(IntextIpPortMap.class)
918 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
921 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
922 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
923 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
924 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
925 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
926 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
927 .intext.ip.map.IpMappingKey(routerId)).build();
932 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
933 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
934 .ip.map.IpMapping> ipMappingOptional =
935 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
936 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
937 // Ensure there are no duplicates
938 Collection<String> externalIps = new HashSet<>();
939 if (ipMappingOptional.isPresent()) {
940 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
941 for (IpMap ipMap : ipMaps) {
942 externalIps.add(ipMap.getExternalIp());
949 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
950 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
951 if (routerData != null) {
952 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
955 return Collections.emptyList();
959 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
960 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
961 .ip.map.IpMapping> ipMappingOptional =
962 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
963 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
964 Map<String, Long> externalIpsLabel = new HashMap<>();
965 if (ipMappingOptional.isPresent()) {
966 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
967 for (IpMap ipMap : ipMaps) {
968 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
971 return externalIpsLabel;
974 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
975 String leastLoadedExternalIp = null;
976 InstanceIdentifier<ExternalCounters> id =
977 InstanceIdentifier.builder(ExternalIpsCounter.class)
978 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
979 Optional<ExternalCounters> externalCountersData =
980 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
981 if (externalCountersData.isPresent()) {
982 ExternalCounters externalCounter = externalCountersData.get();
983 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
984 short countOfLstLoadExtIp = 32767;
985 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
986 String curExternalIp = externalIpCounter.getExternalIp();
987 short countOfCurExtIp = externalIpCounter.getCounter();
988 if (countOfCurExtIp < countOfLstLoadExtIp) {
989 countOfLstLoadExtIp = countOfCurExtIp;
990 leastLoadedExternalIp = curExternalIp;
994 return leastLoadedExternalIp;
997 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
998 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
999 String subnetIP = getSubnetIp(dataBroker, subnetId);
1000 if (subnetIP != null) {
1001 return getSubnetIpAndPrefix(subnetIP);
1003 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
1007 public static String[] getSubnetIpAndPrefix(String subnetString) {
1008 String[] subnetSplit = subnetString.split("/");
1009 String subnetIp = subnetSplit[0];
1010 String subnetPrefix = "0";
1011 if (subnetSplit.length == 2) {
1012 subnetPrefix = subnetSplit[1];
1014 return new String[] {subnetIp, subnetPrefix};
1017 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
1018 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
1019 .builder(Subnetmaps.class)
1020 .child(Subnetmap.class, new SubnetmapKey(subnetId))
1022 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1023 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
1027 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
1028 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
1029 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
1030 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
1031 if (leastLoadedExtIpAddrSplit.length == 2) {
1032 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
1034 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
1038 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
1039 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
1040 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
1041 Optional<RouterDpnList> routerDpnListData =
1042 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1043 LogicalDatastoreType.OPERATIONAL, id);
1044 List<BigInteger> dpns = new ArrayList<>();
1045 if (routerDpnListData.isPresent()) {
1046 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
1047 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
1048 dpns.add(dpnVpnInterface.getDpnId());
1054 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
1055 long bgpVpnId = NatConstants.INVALID_ID;
1056 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1057 if (bgpVpnUuid != null) {
1058 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1063 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1064 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
1065 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1066 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
1069 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
1070 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
1071 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
1072 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
1073 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1074 .RouterInterface.class,
1075 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
1076 .RouterInterfaceKey(interfaceName)).build();
1079 public static void addToNeutronRouterDpnsMap(String routerName, String interfaceName, BigInteger dpId,
1080 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1082 if (dpId.equals(BigInteger.ZERO)) {
1083 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
1084 + "to handle router {} association model", interfaceName, routerName);
1088 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
1089 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1090 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
1092 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = operTx.read(dpnVpnInterfacesListIdentifier).get();
1093 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1094 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1095 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(interfaceName))
1096 .setInterface(interfaceName).build();
1097 if (optionalDpnVpninterfacesList.isPresent()) {
1098 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
1099 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1100 operTx.merge(dpnVpnInterfacesListIdentifier
1101 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1102 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1103 new RouterInterfacesKey(interfaceName)), routerInterface, CREATE_MISSING_PARENTS);
1105 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
1106 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
1107 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1108 routerDpnListBuilder.setRouterId(routerName);
1109 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1110 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1111 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1112 routerInterfaces.add(routerInterface);
1113 dpnVpnList.setRouterInterfaces(routerInterfaces);
1114 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1115 operTx.merge(getRouterId(routerName), routerDpnListBuilder.build(), CREATE_MISSING_PARENTS);
1119 public static void addToDpnRoutersMap(String routerName, String interfaceName, BigInteger dpId,
1120 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1121 if (dpId.equals(BigInteger.ZERO)) {
1122 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1123 + "association model", interfaceName, routerName);
1127 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1128 + "DPNRouters map", dpId, routerName, interfaceName);
1129 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1131 Optional<DpnRoutersList> optionalDpnRoutersList = operTx.read(dpnRoutersListIdentifier).get();
1133 if (optionalDpnRoutersList.isPresent()) {
1134 RoutersList routersList = new RoutersListBuilder().withKey(new RoutersListKey(routerName))
1135 .setRouter(routerName).build();
1136 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1137 if (!routersListFromDs.contains(routersList)) {
1138 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1139 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1140 operTx.merge(dpnRoutersListIdentifier
1141 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, CREATE_MISSING_PARENTS);
1143 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1144 + "DPNRouters map", routerName, dpId);
1147 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1148 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1149 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1150 dpnRoutersListBuilder.setDpnId(dpId);
1151 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1152 routersListBuilder.setRouter(routerName);
1153 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1154 operTx.merge(getDpnRoutersId(dpId), dpnRoutersListBuilder.build(), CREATE_MISSING_PARENTS);
1158 public static void removeFromNeutronRouterDpnsMap(String routerName, BigInteger dpId,
1159 TypedReadWriteTransaction<Operational> operTx) throws ExecutionException, InterruptedException {
1160 if (dpId.equals(BigInteger.ZERO)) {
1161 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1165 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1166 Optional<DpnVpninterfacesList> optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1167 if (optionalRouterDpnList.isPresent()) {
1168 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1169 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1170 operTx.delete(routerDpnListIdentifier);
1172 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1173 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1177 public static void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,
1178 BigInteger dpId, @Nonnull TypedReadWriteTransaction<Operational> operTx) {
1179 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1180 Optional<DpnVpninterfacesList> optionalRouterDpnList;
1182 optionalRouterDpnList = operTx.read(routerDpnListIdentifier).get();
1183 } catch (InterruptedException | ExecutionException e) {
1184 LOG.error("Error reading the router DPN list for {}", routerDpnListIdentifier, e);
1185 optionalRouterDpnList = Optional.absent();
1187 if (optionalRouterDpnList.isPresent()) {
1188 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1189 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1190 optionalRouterDpnList.get().getRouterInterfaces();
1191 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1192 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1193 new RouterInterfacesBuilder().withKey(new RouterInterfacesKey(vpnInterfaceName))
1194 .setInterface(vpnInterfaceName).build();
1196 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1197 if (routerInterfaces.isEmpty()) {
1198 operTx.delete(routerDpnListIdentifier);
1200 operTx.delete(routerDpnListIdentifier.child(
1201 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1202 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1203 new RouterInterfacesKey(vpnInterfaceName)));
1209 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1210 BigInteger curDpnId, OdlInterfaceRpcService ifaceMgrRpcService, TypedReadWriteTransaction<Operational> operTx)
1211 throws ExecutionException, InterruptedException {
1213 1) Get the DpnRoutersList for the DPN.
1214 2) Get the RoutersList identifier for the DPN and router.
1215 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1216 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1217 then remove RouterList.
1220 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1221 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1223 //Get the dpn-routers-list instance for the current DPN.
1224 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1225 Optional<DpnRoutersList> dpnRoutersListData = operTx.read(dpnRoutersListIdentifier).get();
1227 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1228 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1229 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1233 //Get the routers-list instance for the router on the current DPN only
1234 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1235 Optional<RoutersList> routersListData = operTx.read(routersListIdentifier).get();
1237 if (routersListData == null || !routersListData.isPresent()) {
1238 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1239 + "in the ODL-L3VPN:dpn-routers model",
1244 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1245 + "from the NeutronVPN - router-interfaces-map", routerName);
1246 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1247 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1248 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1249 .RouterInterfaces> routerInterfacesData =
1250 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1251 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1253 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1254 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1255 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1256 curDpnId, routerName, routerName);
1257 operTx.delete(routersListIdentifier);
1261 //Get the VM interfaces for the router on the current DPN only.
1262 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1263 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1264 if (vmInterfaces == null) {
1265 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1266 + "NeutronVPN - router-interfaces-map", routerName);
1270 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1271 // then remove RouterList.
1272 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1273 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1274 String vmInterfaceName = vmInterface.getInterfaceId();
1275 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1276 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1277 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1278 + "the DPN ID {} for the checked interface {}",
1279 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1282 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1283 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1284 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1288 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1289 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1290 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1291 operTx.delete(routersListIdentifier);
1294 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1295 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1296 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1297 .rev150602.RouterInterfacesMap.class)
1298 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1299 .interfaces.map.RouterInterfaces.class,
1300 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1301 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1304 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1305 return InstanceIdentifier.builder(DpnRouters.class)
1306 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1307 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1310 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1311 BigInteger nodeId = BigInteger.ZERO;
1313 GetDpidFromInterfaceInput
1315 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1316 Future<RpcResult<GetDpidFromInterfaceOutput>>
1318 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1319 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1320 if (dpIdResult.isSuccessful()) {
1321 nodeId = dpIdResult.getResult().getDpid();
1323 LOG.debug("getDpnForInterface : Could not retrieve DPN Id for interface {}", ifName);
1325 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1326 LOG.error("getDpnForInterface : Exception when getting dpn for interface {}", ifName, e);
1332 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1333 ItmRpcService itmRpcService,
1334 IInterfaceManager interfaceManager, String ifName,
1335 Long tunnelKey, boolean internalTunnelInterface) {
1336 return getEgressActionsForInterface(odlInterfaceRpcService, itmRpcService, interfaceManager,
1337 ifName, tunnelKey, 0, internalTunnelInterface);
1341 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService odlInterfaceRpcService,
1342 ItmRpcService itmRpcService,
1343 IInterfaceManager interfaceManager,
1344 String ifName, Long tunnelKey, int pos,
1345 boolean internalTunnelInterface) {
1346 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1347 GetEgressActionsForInterfaceInputBuilder egressActionsIfmBuilder =
1348 new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
1349 GetEgressActionsForTunnelInputBuilder egressActionsItmBuilder =
1350 new GetEgressActionsForTunnelInputBuilder().setIntfName(ifName);
1351 if (tunnelKey != null) {
1352 egressActionsIfmBuilder.setTunnelKey(tunnelKey);
1353 egressActionsItmBuilder.setTunnelKey(tunnelKey);
1354 } //init builders, ITM/IFM rpc can be called based on type of interface
1357 List<Action> actions = Collections.emptyList();
1358 if (interfaceManager.isItmDirectTunnelsEnabled() && internalTunnelInterface) {
1359 RpcResult<GetEgressActionsForTunnelOutput> rpcResult =
1360 itmRpcService.getEgressActionsForTunnel(egressActionsItmBuilder.build()).get();
1361 if (!rpcResult.isSuccessful()) {
1362 LOG.error("getEgressActionsForTunnels : RPC Call to Get egress actions for Tunnels {} "
1363 + "returned with Errors {}", ifName, rpcResult.getErrors());
1365 actions = rpcResult.getResult().getAction();
1368 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult =
1369 odlInterfaceRpcService.getEgressActionsForInterface(egressActionsIfmBuilder.build()).get();
1370 if (!rpcResult.isSuccessful()) {
1371 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1372 + "returned with Errors {}", ifName, rpcResult.getErrors());
1374 actions = rpcResult.getResult().getAction();
1377 List<ActionInfo> listActionInfo = new ArrayList<>();
1378 for (Action action : actions) {
1379 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1380 actionClass = action.getAction();
1381 if (actionClass instanceof OutputActionCase) {
1382 listActionInfo.add(new ActionOutput(pos++,
1383 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1384 } else if (actionClass instanceof PushVlanActionCase) {
1385 listActionInfo.add(new ActionPushVlan(pos++));
1386 } else if (actionClass instanceof SetFieldCase) {
1387 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1388 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1389 .getVlanId().getValue();
1390 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1392 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1393 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1394 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1395 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1396 NxRegLoad nxRegLoad =
1397 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1398 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1399 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1402 return listActionInfo;
1403 } catch (InterruptedException | ExecutionException e) {
1404 LOG.error("Exception when egress actions for interface {}", ifName, e);
1406 LOG.error("Error when getting egress actions for interface {}", ifName);
1407 return Collections.emptyList();
1410 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1411 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1415 public static List<Port> getNeutronPorts(DataBroker broker) {
1416 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1417 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1418 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1419 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1421 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1422 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1424 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1425 LOG.error("getNeutronPorts : No neutron ports found");
1426 return Collections.emptyList();
1429 return portsOptional.get().getPort();
1432 public static Port getNeutronPortForIp(DataBroker broker,
1433 IpAddress targetIP, String deviceType) {
1434 List<Port> ports = getNeutronPorts(
1437 for (Port port : ports) {
1438 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1439 for (FixedIps ip : port.getFixedIps()) {
1440 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1446 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1450 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1452 LOG.error("getSubnetIdForFloatingIp : port is null");
1455 for (FixedIps ip : port.getFixedIps()) {
1456 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1457 return ip.getSubnetId();
1460 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1464 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1465 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1466 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1467 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1468 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1472 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1473 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1474 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1475 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1476 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1477 Collections.emptyList());
1480 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1481 if (subnetId == null) {
1482 LOG.error("getSubnetGwMac : subnetID is null");
1486 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1487 .child(Subnet.class, new SubnetKey(subnetId));
1488 Optional<Subnet> subnetOpt =
1489 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1490 LogicalDatastoreType.CONFIGURATION, subnetInst);
1491 if (!subnetOpt.isPresent()) {
1492 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1496 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1497 if (gatewayIp == null) {
1498 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1502 if (null != gatewayIp.getIpv6Address()) {
1506 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1507 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1509 Optional<VpnPortipToPort> portIpToPortOpt =
1510 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1511 LogicalDatastoreType.CONFIGURATION, portIpInst);
1512 if (portIpToPortOpt.isPresent()) {
1513 return portIpToPortOpt.get().getMacAddress();
1516 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1517 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1519 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1520 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1521 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1522 if (learntIpToPortOpt.isPresent()) {
1523 return learntIpToPortOpt.get().getMacAddress();
1526 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1530 public static boolean isIPv6Subnet(String prefix) {
1531 return IpPrefixBuilder.getDefaultInstance(prefix).getIpv6Prefix() != null;
1534 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1535 return InstanceIdentifier.builder(DpnRouters.class)
1536 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1539 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1540 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1541 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1542 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1545 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1546 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1547 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1550 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1551 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1552 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1553 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1554 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1557 protected static String getFloatingIpPortMacFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1558 Uuid floatingIpId) {
1560 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1561 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1562 } catch (InterruptedException | ExecutionException e) {
1563 LOG.error("Error reading the floating IP port MAC for {}", floatingIpId, e);
1568 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1569 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1570 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1571 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1572 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1576 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(TypedReadTransaction<Configuration> confTx,
1577 Uuid floatingIpId) {
1579 return confTx.read(buildfloatingIpIdToPortMappingIdentifier(floatingIpId)).get().toJavaUtil().map(
1580 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1581 } catch (InterruptedException | ExecutionException e) {
1582 LOG.error("Error reading the floating IP port subnet for {}", floatingIpId, e);
1587 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1588 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1589 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1592 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1593 InstanceIdentifier<Interface> ifStateId =
1594 buildStateInterfaceId(interfaceName);
1595 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1596 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1599 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1600 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1601 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1602 .interfaces.rev140508.InterfacesState.class)
1603 .child(Interface.class,
1604 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1605 .interfaces.state.InterfaceKey(interfaceName));
1606 InstanceIdentifier<Interface> id = idBuilder.build();
1610 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1611 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1612 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1613 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1617 public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
1619 return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
1620 } catch (InterruptedException | ExecutionException e) {
1621 LOG.error("Error reading router {}", routerName, e);
1626 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1627 if (routerId == NatConstants.INVALID_ID) {
1628 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1631 RouterIds rtrs = new RouterIdsBuilder().withKey(new RouterIdsKey(routerId))
1632 .setRouterId(routerId).setRouterName(routerName).build();
1633 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1636 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1637 IdManagerService idManager) {
1638 InetAddress defaultIP = null;
1640 defaultIP = InetAddress.getByName("0.0.0.0");
1641 } catch (UnknownHostException e) {
1642 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1643 + "Default Route to NAT.", e);
1647 List<MatchInfo> matches = new ArrayList<>();
1648 matches.add(MatchEthernetType.IPV4);
1649 //add match for vrfid
1650 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1652 List<InstructionInfo> instructions = new ArrayList<>();
1653 List<ActionInfo> actionsInfo = new ArrayList<>();
1654 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1655 actionsInfo.add(new ActionGroup(groupId));
1656 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1657 instructions.add(new InstructionApplyActions(actionsInfo));
1658 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1659 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1660 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1664 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1665 String routerName = getRouterName(broker, routerId);
1666 if (routerName == null) {
1667 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1670 return getExtGwMacAddFromRouterName(broker, routerName);
1673 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1674 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1675 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1676 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1680 static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
1682 return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
1683 Routers::getExtGwMacAddress).orElse(null);
1684 } catch (InterruptedException | ExecutionException e) {
1685 LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
1690 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1691 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1692 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1693 .child(Router.class, new RouterKey(routerUuid));
1694 return routerInstanceIdentifier;
1697 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1698 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1699 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1700 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1705 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1706 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1707 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1708 LogicalDatastoreType.CONFIGURATION,
1709 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(Collections.emptyList());
1713 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1714 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1715 Optional<ExternalNetworks> externalNwData =
1716 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1717 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1718 if (externalNwData.isPresent()) {
1719 for (Networks externalNw : externalNwData.get().getNetworks()) {
1720 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1721 return externalNw.getRouterIds();
1725 return Collections.emptyList();
1728 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1731 long ipLo = ipToLong(InetAddress.getByName(start));
1732 long ipHi = ipToLong(InetAddress.getByName(end));
1733 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1734 return ipToTest >= ipLo && ipToTest <= ipHi;
1735 } catch (UnknownHostException e) {
1736 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1742 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1743 if (externalIps == null) {
1744 return Collections.emptySet();
1747 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1751 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1752 if (routerName == null) {
1753 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1754 return Collections.emptySet();
1757 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1758 Optional<Routers> routerData =
1759 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1760 LogicalDatastoreType.CONFIGURATION, id);
1761 if (routerData.isPresent()) {
1762 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1764 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1765 return Collections.emptySet();
1770 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1771 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1772 if (subnetId == null) {
1773 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1774 return Optional.absent();
1777 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1778 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1779 InstanceIdentifier.builder(ExternalSubnets.class)
1780 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1781 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1782 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1783 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1787 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1788 .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1789 if (subnetId == null) {
1790 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1791 return Optional.absent();
1794 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1795 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1796 InstanceIdentifier.builder(ExternalSubnets.class)
1797 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1798 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1800 return tx.read(subnetsIdentifier).get();
1801 } catch (InterruptedException | ExecutionException e) {
1802 LOG.error("Error retrieving external subnets on {}", subnetId, e);
1803 return Optional.absent();
1807 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1808 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1809 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1811 if (optionalExternalSubnets.isPresent()) {
1812 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1815 return NatConstants.INVALID_ID;
1818 protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
1819 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1820 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
1822 if (optionalExternalSubnets.isPresent()) {
1823 return NatUtil.getVpnId(tx, subnetId.getValue());
1826 return NatConstants.INVALID_ID;
1829 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1831 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1832 if (externalSubnetId != null) {
1833 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1836 return NatConstants.INVALID_ID;
1839 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1840 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1841 List<ExternalIps> externalIps = router.getExternalIps();
1842 for (ExternalIps extIp : externalIps) {
1843 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1844 if (extIpString.equals(externalIpAddress)) {
1845 return extIp.getSubnetId();
1848 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1852 private static long ipToLong(InetAddress ip) {
1853 byte[] octets = ip.getAddress();
1855 for (byte octet : octets) {
1857 result |= octet & 0xff;
1863 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1864 if (externalIps == null) {
1865 return Collections.emptyList();
1868 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1871 // elan-instances config container
1872 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1873 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1874 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1875 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1879 public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
1881 return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
1882 } catch (InterruptedException | ExecutionException e) {
1883 LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
1888 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1889 return InstanceIdentifier.builder(ElanInstances.class)
1890 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1893 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1894 IdManagerService idManager, long routerId, String routerName) {
1895 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1896 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1897 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1899 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1903 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1904 short tableId, TypedWriteTransaction<Configuration> confTx) {
1905 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1906 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1908 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1909 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1910 List<MatchInfo> matches = new ArrayList<>();
1911 matches.add(MatchEthernetType.IPV4);
1912 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1913 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1914 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1915 matches, preDnatToSnatInstructions);
1917 mdsalManager.addFlow(confTx, naptDpnId, preDnatToSnatTableFlowEntity);
1918 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1919 preDnatToSnatTableFlowEntity, naptDpnId);
1922 public static void removePreDnatToSnatTableEntry(TypedReadWriteTransaction<Configuration> confTx,
1923 IMdsalApiManager mdsalManager, BigInteger naptDpnId) throws ExecutionException, InterruptedException {
1924 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1925 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1926 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1927 mdsalManager.removeFlow(confTx, naptDpnId, flowRef, NwConstants.PDNAT_TABLE);
1928 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1929 flowRef, naptDpnId);
1932 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1933 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1934 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1937 public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1938 String vpnName, String externalIp,
1939 Boolean isMoreThanOneFipCheckOnDpn) {
1940 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1941 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1942 if (dpnInVpn.isPresent()) {
1943 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1944 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
1946 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1947 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1948 int floatingIpPresentCount = 0;
1949 for (IpAddresses ipAddress: ipAddressList) {
1950 if (!ipAddress.getIpAddress().equals(externalIp)
1951 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1952 floatingIpPresentCount++;
1953 //Add tunnel table check
1954 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1955 return Boolean.TRUE;
1957 //Remove tunnel table check
1958 if (!isMoreThanOneFipCheckOnDpn) {
1959 return Boolean.TRUE;
1964 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
1966 return Boolean.FALSE;
1968 } catch (NullPointerException e) {
1969 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
1970 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
1971 return Boolean.FALSE;
1974 return Boolean.FALSE;
1977 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1978 return InstanceIdentifier.builder(VpnInstanceOpData.class)
1979 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1980 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1984 public static String getPrimaryRd(String vpnName, TypedReadTransaction<Configuration> tx)
1985 throws ExecutionException, InterruptedException {
1986 return tx.read(getVpnInstanceIdentifier(vpnName)).get().toJavaUtil().map(NatUtil::getPrimaryRd).orElse(null);
1989 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
1990 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1991 Optional<VpnInstance> vpnInstance =
1992 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1993 LogicalDatastoreType.CONFIGURATION, id);
1994 if (vpnInstance.isPresent()) {
1995 return getPrimaryRd(vpnInstance.get());
2000 public static String getPrimaryRd(VpnInstance vpnInstance) {
2001 List<String> rds = null;
2002 if (vpnInstance != null) {
2003 rds = getListOfRdsFromVpnInstance(vpnInstance);
2005 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
2008 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
2009 return InstanceIdentifier.builder(VpnInstances.class)
2010 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
2014 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
2015 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
2016 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
2017 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
2020 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
2021 if (routerName != null) {
2022 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
2023 if (extRouter != null) {
2024 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
2028 return NatConstants.INVALID_ID;
2031 public static String validateAndAddNetworkMask(String ipAddress) {
2032 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
2035 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
2036 String vpnInterfaceName, String vpnName) {
2037 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
2038 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
2041 public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
2042 InstanceIdentifier<VpnInstanceOpDataEntry> id = NatUtil.getVpnInstanceOpDataIdentifier(rd);
2043 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
2044 broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
2047 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
2048 String routerName, BigInteger dpnId) {
2049 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
2050 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
2052 if (networkData != null && networkData.isPresent()) {
2053 List<Uuid> routerUuidList = networkData.get().getRouterIds();
2054 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2055 for (Uuid routerUuid : routerUuidList) {
2056 String sharedRouterName = routerUuid.getValue();
2057 if (!routerName.equals(sharedRouterName)) {
2058 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2059 if (switchDpnId == null) {
2061 } else if (switchDpnId.equals(dpnId)) {
2062 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
2063 + "associated with other active router {} on NAPT switch {}", networkId,
2064 sharedRouterName, switchDpnId);
2074 public static boolean checkForRoutersWithSameExtSubnetAndNaptSwitch(DataBroker broker, Uuid externalSubnetId,
2075 String routerName, BigInteger dpnId) {
2076 List<Uuid> routerUuidList = getOptionalExternalSubnets(broker, externalSubnetId).toJavaUtil()
2077 .map(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
2078 .subnets.Subnets::getRouterIds).orElse(Collections.emptyList());
2079 if (routerUuidList != null && !routerUuidList.isEmpty()) {
2080 for (Uuid routerUuid : routerUuidList) {
2081 String sharedRouterName = routerUuid.getValue();
2082 if (!routerName.equals(sharedRouterName)) {
2083 BigInteger switchDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
2084 if (switchDpnId == null) {
2086 } else if (switchDpnId.equals(dpnId)) {
2087 LOG.debug("checkForRoutersWithSameExtSubnetAndNaptSwitch: external-subnetwork {} is "
2088 + "associated with other active router {} on NAPT switch {}", externalSubnetId,
2089 sharedRouterName, switchDpnId);
2098 public static void installRouterGwFlows(ManagedNewTransactionRunner txRunner, IVpnManager vpnManager,
2099 Routers router, BigInteger primarySwitchId, int addOrRemove) {
2100 ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
2101 List<ExternalIps> externalIps = router.getExternalIps();
2102 List<String> externalIpsSting = new ArrayList<>();
2104 if (externalIps.isEmpty()) {
2105 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
2108 for (ExternalIps externalIp : externalIps) {
2109 externalIpsSting.add(externalIp.getIpAddress());
2111 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
2112 if (addOrRemove == NwConstants.ADD_FLOW) {
2113 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2114 router.getNetworkId(), subnetVpnName.getValue(), tx);
2115 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2116 router.getExtGwMacAddress(), primarySwitchId,
2117 router.getNetworkId());
2119 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
2120 router.getNetworkId(), subnetVpnName.getValue(), tx);
2121 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
2122 router.getExtGwMacAddress(), primarySwitchId,
2123 router.getNetworkId());
2125 }), LOG, "Error installing router gateway flows");
2128 @SuppressWarnings("checkstyle:IllegalCatch")
2129 public static void removeSNATFromDPN(DataBroker dataBroker, IMdsalApiManager mdsalManager,
2130 IdManagerService idManager, NaptSwitchHA naptSwitchHA, BigInteger dpnId,
2131 String routerName, long routerId, long routerVpnId,
2132 ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx)
2133 throws ExecutionException, InterruptedException {
2134 //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
2135 //remove miss entry to NAPT switch
2136 //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
2137 if (extNwProvType == null) {
2140 //Get the external IP labels other than VXLAN provider type. Since label is not applicable for VXLAN
2141 Map<String, Long> externalIpLabel;
2142 if (extNwProvType == ProviderTypes.VXLAN) {
2143 externalIpLabel = null;
2145 externalIpLabel = NatUtil.getExternalIpsLabelForRouter(dataBroker, routerId);
2147 BigInteger naptSwitch = NatUtil.getPrimaryNaptfromRouterName(dataBroker, routerName);
2148 if (naptSwitch == null || naptSwitch.equals(BigInteger.ZERO)) {
2149 LOG.error("removeSNATFromDPN : No naptSwitch is selected for router {}", routerName);
2152 Collection<String> externalIpCache = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
2153 boolean naptStatus =
2154 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
2155 externalIpCache, confTx);
2157 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
2159 long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
2160 FlowEntity flowEntity = null;
2162 flowEntity = naptSwitchHA.buildSnatFlowEntity(dpnId, routerName, groupId, routerVpnId,
2163 NatConstants.DEL_FLOW);
2164 if (flowEntity == null) {
2165 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router:{} "
2166 + "with dpnId:{} groupId:{}", routerName, dpnId, groupId);
2169 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
2170 mdsalManager.removeFlow(confTx, flowEntity);
2172 } catch (Exception ex) {
2173 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2177 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2181 GroupEntity groupEntity = null;
2183 groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
2184 GroupTypes.GroupAll, Collections.emptyList() /*listBucketInfo*/);
2185 LOG.info("removeSNATFromDPN : Removing NAPT GroupEntity:{}", groupEntity);
2186 mdsalManager.removeGroup(groupEntity);
2187 } catch (Exception ex) {
2188 LOG.error("removeSNATFromDPN : Failed to remove group entity {}", groupEntity, ex);
2191 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routerName {}",
2194 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
2195 externalIpLabel, confTx);
2196 //remove table 26 flow ppointing to table46
2197 FlowEntity flowEntity = null;
2199 flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName, routerVpnId,
2200 NatConstants.DEL_FLOW);
2201 if (flowEntity == null) {
2202 LOG.error("removeSNATFromDPN : Failed to populate flowentity for router {} with dpnId {}",
2206 LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
2207 + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
2208 mdsalManager.removeFlow(confTx, flowEntity);
2210 } catch (Exception ex) {
2211 LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
2215 LOG.debug("removeSNATFromDPN : Removed default SNAT miss entry flow for dpnID {} with routername {}",
2218 //best effort to check IntExt model
2219 naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
2223 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
2224 ProviderTypes extNwProvType) {
2225 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
2226 || extNwProvType == ProviderTypes.VXLAN)) {
2232 public static void addPseudoPortToElanDpn(String elanInstanceName, String pseudoPortId,
2233 BigInteger dpnId, DataBroker dataBroker) {
2234 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2235 elanInstanceName,dpnId);
2237 synchronized (elanInstanceName.intern()) {
2238 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2239 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2240 List<String> elanInterfaceList;
2241 DpnInterfaces dpnInterface;
2242 if (!dpnInElanInterfaces.isPresent()) {
2243 elanInterfaceList = new ArrayList<>();
2245 dpnInterface = dpnInElanInterfaces.get();
2246 elanInterfaceList = dpnInterface.getInterfaces();
2248 if (!elanInterfaceList.contains(pseudoPortId)) {
2249 elanInterfaceList.add(pseudoPortId);
2250 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2251 .withKey(new DpnInterfacesKey(dpnId)).build();
2252 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2253 elanDpnInterfaceId, dpnInterface);
2256 } catch (ReadFailedException e) {
2257 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2258 } catch (TransactionCommitFailedException e) {
2259 LOG.warn("Failed to add elanDpnInterface with error {}", e.getMessage());
2263 public static void removePseudoPortFromElanDpn(String elanInstanceName, String pseudoPortId,
2264 BigInteger dpnId, DataBroker dataBroker) {
2265 InstanceIdentifier<DpnInterfaces> elanDpnInterfaceId = getElanDpnInterfaceOperationalDataPath(
2266 elanInstanceName,dpnId);
2268 synchronized (elanInstanceName.intern()) {
2269 Optional<DpnInterfaces> dpnInElanInterfaces = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2270 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
2271 List<String> elanInterfaceList;
2272 DpnInterfaces dpnInterface;
2273 if (!dpnInElanInterfaces.isPresent()) {
2274 LOG.info("No interface in any dpn for {}", elanInstanceName);
2277 dpnInterface = dpnInElanInterfaces.get();
2278 elanInterfaceList = dpnInterface.getInterfaces();
2280 if (!elanInterfaceList.contains(pseudoPortId)) {
2281 LOG.info("Router port not present in DPN {} for VPN {}", dpnId, elanInstanceName);
2284 elanInterfaceList.remove(pseudoPortId);
2285 dpnInterface = new DpnInterfacesBuilder().setDpId(dpnId).setInterfaces(elanInterfaceList)
2286 .withKey(new DpnInterfacesKey(dpnId)).build();
2287 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
2288 elanDpnInterfaceId, dpnInterface);
2290 } catch (ReadFailedException e) {
2291 LOG.warn("Failed to read elanDpnInterface with error {}", e.getMessage());
2292 } catch (TransactionCommitFailedException e) {
2293 LOG.warn("Failed to remove elanDpnInterface with error {}", e.getMessage());
2298 public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId,
2299 DataBroker broker) {
2300 InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId =
2301 getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
2302 DpnInterfaces dpnInterfaces = null;
2304 dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL,
2305 elanDpnInterfacesId);
2307 catch (ReadFailedException e) {
2308 LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
2310 return dpnInterfaces;
2313 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
2314 InstanceIdentifier<T> path) {
2315 try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
2316 return tx.read(datastoreType, path).get();
2317 } catch (InterruptedException | ExecutionException e) {
2318 throw new RuntimeException(e);
2322 public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
2323 Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
2324 for (Map.Entry<String,Routers> router : extRouter) {
2325 if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
2326 .equals(networkid)) {
2333 public static InstanceIdentifier<ExtRouters> buildExtRouters() {
2334 InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
2336 return extRouterInstanceIndentifier;
2339 public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
2340 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = getLearntVpnVipToPortDataId();
2341 LearntVpnVipToPortData learntVpnVipToPortData = null;
2343 learntVpnVipToPortData = SingleTransactionDataBroker.syncRead(dataBroker,
2344 LogicalDatastoreType.OPERATIONAL, learntVpnVipToPortDataId);
2346 catch (ReadFailedException e) {
2347 LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
2349 return learntVpnVipToPortData;
2352 public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
2353 InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
2354 .builder(LearntVpnVipToPortData.class).build();
2355 return learntVpnVipToPortDataId;
2358 public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
2360 return InstanceIdentifier.builder(ElanDpnInterfaces.class)
2361 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName))
2362 .child(DpnInterfaces.class, new DpnInterfacesKey(dpId)).build();
2365 public static InstanceIdentifier<Group> getGroupInstanceId(BigInteger dpnId, long groupId) {
2366 return InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(new NodeId("openflow:" + dpnId)))
2367 .augmentation(FlowCapableNode.class).child(Group.class, new GroupKey(new GroupId(groupId))).build();
2370 public static void createGroupIdPool(IdManagerService idManager) {
2371 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
2372 .setPoolName(NatConstants.SNAT_IDPOOL_NAME)
2373 .setLow(NatConstants.SNAT_ID_LOW_VALUE)
2374 .setHigh(NatConstants.SNAT_ID_HIGH_VALUE)
2377 Future<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
2378 if (result != null && result.get().isSuccessful()) {
2379 LOG.debug("createGroupIdPool : GroupIdPool created successfully");
2381 LOG.error("createGroupIdPool : Unable to create GroupIdPool");
2383 } catch (InterruptedException | ExecutionException e) {
2384 LOG.error("createGroupIdPool : Failed to create PortPool for NAPT Service", e);
2388 public static boolean getSwitchStatus(DataBroker broker, BigInteger switchId) {
2389 NodeId nodeId = new NodeId("openflow:" + switchId);
2390 LOG.debug("getSwitchStatus : Querying switch with dpnId {} is up/down", nodeId);
2391 InstanceIdentifier<Node> nodeInstanceId = InstanceIdentifier.builder(Nodes.class)
2392 .child(Node.class, new NodeKey(nodeId)).build();
2393 Optional<Node> nodeOptional =
2394 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
2395 LogicalDatastoreType.OPERATIONAL, nodeInstanceId);
2396 if (nodeOptional.isPresent()) {
2397 LOG.debug("getSwitchStatus : Switch {} is up", nodeId);
2400 LOG.debug("getSwitchStatus : Switch {} is down", nodeId);