2 * Copyright © 2016, 2017 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 com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import java.math.BigInteger;
16 import java.net.InetAddress;
17 import java.net.UnknownHostException;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
23 import java.util.Objects;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.Future;
27 import java.util.stream.Collectors;
29 import javax.annotation.Nonnull;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
32 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
35 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
36 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
37 import org.opendaylight.genius.mdsalutil.ActionInfo;
38 import org.opendaylight.genius.mdsalutil.FlowEntity;
39 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
40 import org.opendaylight.genius.mdsalutil.InstructionInfo;
41 import org.opendaylight.genius.mdsalutil.MDSALUtil;
42 import org.opendaylight.genius.mdsalutil.MatchInfo;
43 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
44 import org.opendaylight.genius.mdsalutil.NwConstants;
45 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
46 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
47 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
48 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
49 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
50 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
51 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
52 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
53 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
54 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
55 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
56 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
57 import org.opendaylight.netvirt.elanmanager.api.IElanService;
58 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
59 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
60 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
61 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
62 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
63 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
64 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
65 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
66 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
67 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
130 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;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
171 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;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
206 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
207 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;
208 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
209 import org.opendaylight.yangtools.yang.binding.DataObject;
210 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
211 import org.opendaylight.yangtools.yang.common.RpcResult;
212 import org.slf4j.Logger;
213 import org.slf4j.LoggerFactory;
215 public class NatUtil {
217 private static String OF_URI_SEPARATOR = ":";
218 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
221 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
224 public static BigInteger getCookieSnatFlow(long routerId) {
225 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
226 BigInteger.valueOf(routerId));
230 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
233 public static BigInteger getCookieNaptFlow(long routerId) {
234 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
235 BigInteger.valueOf(routerId));
239 getVpnId() returns the VPN ID from the VPN name
241 public static long getVpnId(DataBroker broker, String vpnName) {
242 if (vpnName == null) {
243 return NatConstants.INVALID_ID;
246 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
247 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
248 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
249 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
251 long vpnId = NatConstants.INVALID_ID;
252 if (vpnInstance.isPresent()) {
253 Long vpnIdAsLong = vpnInstance.get().getVpnId();
254 if (vpnIdAsLong != null) {
261 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
262 //Get the external network ID from the ExternalRouter model
263 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
264 if (networkId == null) {
265 LOG.error("NAT Service : networkId is null");
266 return NatConstants.INVALID_ID;
269 //Get the VPN ID from the ExternalNetworks model
270 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
271 if (vpnUuid == null) {
272 LOG.error("NAT Service : vpnUuid is null");
273 return NatConstants.INVALID_ID;
275 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
279 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
280 return InstanceIdentifier.builder(FloatingIpInfo.class)
281 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
284 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
285 return InstanceIdentifier.builder(RouterToVpnMapping.class)
286 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
289 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
290 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
291 .child(Ports.class, new PortsKey(portName)).build();
294 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
296 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
297 .child(Ports.class, new PortsKey(portName))
298 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
301 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
302 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
303 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
304 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
305 .instance.to.vpn.id.VpnInstance.class,
306 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
307 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
310 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
311 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
312 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
313 Optional<VpnIds> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
314 return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : null;
318 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
320 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
321 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
322 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
325 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
326 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
327 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
330 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
331 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
332 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
336 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
337 String routerName = getRouterName(broker, routerId);
338 return getNetworkIdFromRouterName(broker, routerName);
341 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
342 if (routerName == null) {
343 LOG.error("getNetworkIdFromRouterName - empty routerName received");
346 InstanceIdentifier id = buildRouterIdentifier(routerName);
347 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
348 if (routerData.isPresent()) {
349 return routerData.get().getNetworkId();
354 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
355 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
356 .child(Routers.class, new RoutersKey(routerId)).build();
357 return routerInstanceIndentifier;
360 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
361 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
362 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
367 * Return if SNAT is enabled for the given router.
369 * @param broker The DataBroker
370 * @param routerId The router
371 * @return boolean true if enabled, otherwise false
373 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
374 InstanceIdentifier id = buildRouterIdentifier(routerId);
375 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
376 if (routerData.isPresent()) {
377 return routerData.get().isEnableSnat();
382 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
383 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
384 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
385 if (networkData.isPresent()) {
386 return networkData.get().getVpnid();
391 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
392 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
393 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
394 if (networkData.isPresent() && networkData.get() != null) {
395 return networkData.get().getProviderNetworkType();
400 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
401 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
402 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
403 return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList();
406 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
407 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
408 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
409 if (routerData.isPresent()) {
410 Uuid networkId = routerData.get().getNetworkId();
411 if (networkId != null) {
412 return networkId.getValue();
418 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
419 InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class)
420 .child(Networks.class, new NetworksKey(networkId)).build();
424 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
425 // convert routerId to Name
426 String routerName = getRouterName(broker, routerId);
427 return getPrimaryNaptfromRouterName(broker, routerName);
430 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
431 if (routerName == null) {
432 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
435 InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
436 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
437 if (routerToNaptSwitchData.isPresent()) {
438 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
439 return routerToNaptSwitchInstance.getPrimarySwitchId();
444 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
445 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
446 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
450 public static String getRouterName(DataBroker broker, Long routerId) {
451 InstanceIdentifier id = buildRouterIdentifier(routerId);
452 Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
453 if (routerIdsData.isPresent()) {
454 RouterIds routerIdsInstance = routerIdsData.get();
455 return routerIdsInstance.getRouterName();
460 // TODO Clean up the exception handling
461 @SuppressWarnings("checkstyle:IllegalCatch")
462 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
463 InstanceIdentifier<T> path) {
465 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
468 return tx.read(datastoreType, path).get();
469 } catch (Exception e) {
470 throw new RuntimeException(e);
474 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
475 return InstanceIdentifier.builder(VpnInstanceOpData.class)
476 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
479 public static long readVpnId(DataBroker broker, String vpnName) {
480 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
481 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
482 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
483 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
485 long vpnId = NatConstants.INVALID_ID;
486 if (vpnInstance.isPresent()) {
487 vpnId = vpnInstance.get().getVpnId();
493 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
494 return new FlowEntityBuilder()
502 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
503 return new FlowEntityBuilder()
510 public static long getIpAddress(byte[] rawIpAddress) {
511 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
512 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
515 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
516 String nextHopIp = null;
517 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
518 InstanceIdentifier.builder(DpnEndpoints.class)
519 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
520 Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
521 if (tunnelInfo.isPresent()) {
522 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
523 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
524 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
530 public static String getVpnRd(DataBroker broker, String vpnName) {
532 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
533 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
534 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
535 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
538 if (vpnInstance.isPresent()) {
539 rd = vpnInstance.get().getVrfId();
544 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
545 String internalPort, NAPTEntryEvent.Protocol protocol) {
546 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
547 InstanceIdentifier ipPortMapId =
548 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
549 Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
550 if (ipPortMapData.isPresent()) {
551 IpPortMap ipPortMapInstance = ipPortMapData.get();
552 return ipPortMapInstance.getIpPortExternal();
557 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
559 ProtocolTypes protocolType) {
560 InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class)
561 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
562 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
563 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
567 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
568 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
569 return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
572 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
573 return InstanceIdentifier.builder(VpnInterfaces.class)
574 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
577 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
578 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
579 return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
582 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
584 * NodeConnectorId is of form 'openflow:dpnid:portnum'
586 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
587 if (split == null || split.length != 3) {
593 public static BigInteger getDpIdFromInterface(
594 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
595 .state.Interface ifState) {
596 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
597 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
598 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
601 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
602 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
603 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
604 Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
606 if (optionalVpnMap.isPresent()) {
607 Uuid routerId = optionalVpnMap.get().getRouterId();
608 if (routerId != null) {
609 return routerId.getValue();
615 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
616 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
617 Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
619 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
620 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
621 if (routerId != null) {
622 for (VpnMap vpnMap : allMaps) {
623 if (vpnMap.getRouterId() != null
624 && routerId.equals(vpnMap.getRouterId().getValue())
625 && !routerId.equals(vpnMap.getVpnId().getValue())) {
626 return vpnMap.getVpnId();
634 static long getAssociatedVpn(DataBroker broker, String routerName) {
635 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
636 Optional<Routermapping> optRouterMapping =
637 NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
638 if (optRouterMapping.isPresent()) {
639 Routermapping routerMapping = optRouterMapping.get();
640 return routerMapping.getVpnId();
642 return NatConstants.INVALID_ID;
645 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
646 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
647 if (vpnUuid == null) {
648 log.error("No VPN instance associated with ext network {}", networkId);
651 return vpnUuid.getValue();
654 // TODO Clean up the exception handling
655 @SuppressWarnings("checkstyle:IllegalCatch")
656 public static void addPrefixToBGP(DataBroker broker,
657 IBgpManager bgpManager,
658 IFibManager fibManager,
668 Logger log, RouteOrigin origin, BigInteger dpId) {
670 LOG.info("NAT Service : ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
671 prefix, nextHopIp, label);
672 if (nextHopIp == null) {
673 LOG.error("NAT Service : addPrefix prefix {} rd {} failed since nextHopIp cannot be null.", prefix, rd);
677 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId, subnetId,
678 /*isNatPrefix*/ true);
679 fibManager.addOrUpdateFibEntry(broker, rd, macAddress, prefix,
680 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
681 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
682 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
683 /* Publish to Bgp only if its an INTERNET VPN */
684 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
685 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
686 null /*gatewayMac*/);
688 LOG.info("NAT Service : ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
689 prefix, nextHopIp, label);
690 } catch (Exception e) {
691 LOG.error("NAT Service : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
692 prefix, nextHopIp, label, e);
696 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
697 BigInteger dpId, Uuid subnetId, boolean isNatPrefix) {
698 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
699 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
700 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
701 .to._interface.VpnIdsKey(vpnId))
702 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
703 Prefixes prefix = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix).setVpnInterfaceName(interfaceName)
704 .setNatPrefix(isNatPrefix).setSubnetId(subnetId).build();
706 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId, prefix);
707 } catch (TransactionCommitFailedException e) {
708 LOG.error("Failed to write prefxi-to-interface for {} vpn-id {} DPN {}", ipPrefix, vpnId, dpId);
712 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
713 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
714 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
718 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
719 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
720 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
721 return routerInstanceIndentifier;
724 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
725 String internalIpAddress, ProtocolTypes protocolType) {
726 Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION,
727 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
728 if (optionalIpProtoType.isPresent()) {
729 return optionalIpProtoType.get().getPorts();
734 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
735 String internalIpAddress,
736 ProtocolTypes protocolType) {
737 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
738 InstanceIdentifier.builder(SnatintIpPortMap.class)
739 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
740 .child(IpPort.class, new IpPortKey(internalIpAddress))
741 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
742 return intIpProtocolTypeId;
745 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
746 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
747 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
751 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
752 return InstanceIdentifier.create(NaptSwitches.class);
755 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
756 return InstanceIdentifier.create(NaptSwitches.class)
757 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
760 public static String getGroupIdKey(String routerName) {
761 return "snatmiss." + routerName;
764 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
765 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
766 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
769 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
770 RpcResult<AllocateIdOutput> rpcResult = result.get();
771 return rpcResult.getResult().getIdValue();
772 } catch (NullPointerException | InterruptedException | ExecutionException e) {
778 // TODO Clean up the exception handling
779 @SuppressWarnings("checkstyle:IllegalCatch")
780 public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager,
781 String rd, String prefix, String vpnName, Logger log) {
783 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
784 fibManager.removeFibEntry(broker, rd, prefix, null);
785 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
786 bgpManager.withdrawPrefix(rd, prefix);
788 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
789 } catch (Exception e) {
790 log.error("Delete prefix for rd {} prefix {} vpnName {} failed", rd, prefix, vpnName, e);
794 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
795 return read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
798 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
799 return InstanceIdentifier.builder(IntextIpPortMap.class)
800 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
803 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
804 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
805 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
806 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
807 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
808 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
809 .intext.ip.map.IpMappingKey(routerId)).build();
813 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
814 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
815 .ip.map.IpMapping> ipMappingOptional =
816 read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
817 List<String> externalIps = new ArrayList<>();
818 if (ipMappingOptional.isPresent()) {
819 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
820 for (IpMap ipMap : ipMaps) {
821 externalIps.add(ipMap.getExternalIp());
824 return new ArrayList<>(new HashSet<>(externalIps));
829 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
830 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
831 if (routerData != null) {
832 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
835 return Collections.emptyList();
838 public static HashMap<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
839 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
840 .ip.map.IpMapping> ipMappingOptional =
841 read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
842 HashMap<String, Long> externalIpsLabel = new HashMap<>();
843 if (ipMappingOptional.isPresent()) {
844 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
845 for (IpMap ipMap : ipMaps) {
846 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
848 return externalIpsLabel;
853 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
854 String leastLoadedExternalIp = null;
855 InstanceIdentifier<ExternalCounters> id =
856 InstanceIdentifier.builder(ExternalIpsCounter.class)
857 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
858 Optional<ExternalCounters> externalCountersData =
859 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
860 if (externalCountersData.isPresent()) {
861 ExternalCounters externalCounter = externalCountersData.get();
862 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
863 short countOfLstLoadExtIp = 32767;
864 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
865 String curExternalIp = externalIpCounter.getExternalIp();
866 short countOfCurExtIp = externalIpCounter.getCounter();
867 if (countOfCurExtIp < countOfLstLoadExtIp) {
868 countOfLstLoadExtIp = countOfCurExtIp;
869 leastLoadedExternalIp = curExternalIp;
873 return leastLoadedExternalIp;
876 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
877 String subnetIP = getSubnetIp(dataBroker, subnetId);
878 if (subnetIP != null) {
879 return getSubnetIpAndPrefix(subnetIP);
884 public static String[] getSubnetIpAndPrefix(String subnetString) {
885 String[] subnetSplit = subnetString.split("/");
886 String subnetIp = subnetSplit[0];
887 String subnetPrefix = "0";
888 if (subnetSplit.length == 2) {
889 subnetPrefix = subnetSplit[1];
891 return new String[] {subnetIp, subnetPrefix};
894 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
895 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
896 .builder(Subnetmaps.class)
897 .child(Subnetmap.class, new SubnetmapKey(subnetId))
899 Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
900 if (removedSubnet.isPresent()) {
901 Subnetmap subnetMapEntry = removedSubnet.get();
902 return subnetMapEntry.getSubnetIp();
908 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
909 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
910 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
911 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
912 if (leastLoadedExtIpAddrSplit.length == 2) {
913 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
915 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
918 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
919 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
920 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
921 Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
922 List<BigInteger> dpns = new ArrayList<>();
923 if (routerDpnListData.isPresent()) {
924 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
925 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
926 dpns.add(dpnVpnInterface.getDpnId());
933 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
934 long bgpVpnId = NatConstants.INVALID_ID;
935 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
936 if (bgpVpnUuid != null) {
937 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
942 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
943 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
944 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router
945 .interfaces.RouterInterface> optRouterInterface =
946 read(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName));
947 if (optRouterInterface.isPresent()) {
948 return optRouterInterface.get();
953 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
954 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
955 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
956 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
957 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
958 .RouterInterface.class,
959 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
960 .RouterInterfaceKey(interfaceName)).build();
963 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
964 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
965 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
966 addToNeutronRouterDpnsMap(broker, routerName, interfaceName, dpId, writeOperTxn);
969 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
970 BigInteger dpId , WriteTransaction writeOperTxn) {
972 if (dpId.equals(BigInteger.ZERO)) {
973 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
974 interfaceName, routerName);
978 LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the "
979 + "ODL-L3VPN : NeutronRouterDpn map",
980 routerName, dpId, interfaceName);
981 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
983 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = read(broker, LogicalDatastoreType
984 .OPERATIONAL, dpnVpnInterfacesListIdentifier);
985 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
986 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
987 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
988 .setInterface(interfaceName).build();
989 if (optionalDpnVpninterfacesList.isPresent()) {
990 LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the "
991 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
992 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
993 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
994 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
995 new RouterInterfacesKey(interfaceName)), routerInterface, true);
997 LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the "
998 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
999 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
1000 routerDpnListBuilder.setRouterId(routerName);
1001 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
1002 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1003 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1004 routerInterfaces.add(routerInterface);
1005 dpnVpnList.setRouterInterfaces(routerInterfaces);
1006 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1007 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1008 getRouterId(routerName),
1009 routerDpnListBuilder.build(), true);
1014 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1015 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1016 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1017 addToDpnRoutersMap(broker, routerName, interfaceName, dpId, writeOperTxn);
1020 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1021 BigInteger dpId, WriteTransaction writeOperTxn) {
1022 if (dpId.equals(BigInteger.ZERO)) {
1023 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
1024 interfaceName, routerName);
1028 LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1030 dpId, routerName, interfaceName);
1031 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1033 Optional<DpnRoutersList> optionalDpnRoutersList = read(broker, LogicalDatastoreType.OPERATIONAL,
1034 dpnRoutersListIdentifier);
1036 if (optionalDpnRoutersList.isPresent()) {
1037 RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
1038 .setRouter(routerName).build();
1039 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1040 if (!routersListFromDs.contains(routersList)) {
1041 LOG.debug("NAT Service : Router {} not present for the DPN {}"
1042 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1043 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1044 dpnRoutersListIdentifier
1045 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1047 LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map",
1051 LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} "
1052 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1053 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1054 dpnRoutersListBuilder.setDpnId(dpId);
1055 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1056 routersListBuilder.setRouter(routerName);
1057 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1058 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1059 getDpnRoutersId(dpId),
1060 dpnRoutersListBuilder.build(), true);
1065 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1066 BigInteger dpId, WriteTransaction writeOperTxn) {
1067 if (dpId.equals(BigInteger.ZERO)) {
1068 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1069 interfaceName, routerName);
1072 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1073 Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1074 .OPERATIONAL, routerDpnListIdentifier);
1075 if (optionalRouterDpnList.isPresent()) {
1076 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1077 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1078 optionalRouterDpnList.get().getRouterInterfaces();
1079 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1080 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1081 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1082 .setInterface(interfaceName).build();
1083 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1084 if (routerInterfaces.isEmpty()) {
1085 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1087 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1088 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1089 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1090 new RouterInterfacesKey(interfaceName)));
1096 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1097 BigInteger dpId, WriteTransaction writeOperTxn) {
1098 if (dpId.equals(BigInteger.ZERO)) {
1099 LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName);
1103 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1104 Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1105 .OPERATIONAL, routerDpnListIdentifier);
1106 if (optionalRouterDpnList.isPresent()) {
1107 LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model "
1108 + "for the router {}", routerName);
1109 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1111 LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model "
1112 + "for the router {}", routerName);
1116 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1117 OdlInterfaceRpcService ifaceMgrRpcService,
1118 WriteTransaction writeOperTxn) {
1119 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1120 if (dpId.equals(BigInteger.ZERO)) {
1121 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1122 vpnInterfaceName, routerName);
1125 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1126 Optional<DpnVpninterfacesList> optionalRouterDpnList = read(broker, LogicalDatastoreType
1127 .OPERATIONAL, routerDpnListIdentifier);
1128 if (optionalRouterDpnList.isPresent()) {
1129 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1130 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1131 optionalRouterDpnList.get().getRouterInterfaces();
1132 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1133 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1134 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1135 .setInterface(vpnInterfaceName).build();
1137 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1138 if (routerInterfaces.isEmpty()) {
1139 if (writeOperTxn != null) {
1140 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1142 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1145 if (writeOperTxn != null) {
1146 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1147 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1148 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1149 new RouterInterfacesKey(vpnInterfaceName)));
1151 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1152 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1153 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1154 new RouterInterfacesKey(vpnInterfaceName)));
1161 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1162 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1163 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1164 if (dpId.equals(BigInteger.ZERO)) {
1165 LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} "
1166 + "to handle router {} dissociation model",
1167 vpnInterfaceName, routerName);
1170 removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1173 static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1174 BigInteger curDpnId,
1175 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1177 1) Get the DpnRoutersList for the DPN.
1178 2) Get the RoutersList identifier for the DPN and router.
1179 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1180 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1181 then remove RouterList.
1184 LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1185 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1187 //Get the dpn-routers-list instance for the current DPN.
1188 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1189 Optional<DpnRoutersList> dpnRoutersListData = read(broker, LogicalDatastoreType.OPERATIONAL,
1190 dpnRoutersListIdentifier);
1192 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1193 LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model",
1198 //Get the routers-list instance for the router on the current DPN only
1199 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1200 Optional<RoutersList> routersListData = read(broker, LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1202 if (routersListData == null || !routersListData.isPresent()) {
1203 LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model",
1208 LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map",
1210 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1211 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1212 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1213 .RouterInterfaces> routerInterfacesData = read(broker, LogicalDatastoreType.CONFIGURATION,
1214 routerInterfacesId);
1216 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1217 LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed"
1218 + " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1219 curDpnId, routerName, routerName);
1220 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1224 //Get the VM interfaces for the router on the current DPN only.
1225 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1226 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1227 if (vmInterfaces == null) {
1228 LOG.debug("NAT Service : VM interfaces are not present for the router {} in the "
1229 + "NeutronVPN - router-interfaces-map", routerName);
1233 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1234 // then remove RouterList.
1235 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1236 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1237 String vmInterfaceName = vmInterface.getInterfaceId();
1238 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1239 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1240 LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of "
1241 + "the DPN ID for the checked interface {} ",
1242 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1245 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1246 LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} "
1247 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1251 LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} "
1252 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1253 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1254 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1257 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1258 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1259 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1260 .rev150602.RouterInterfacesMap.class)
1261 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1262 .interfaces.map.RouterInterfaces.class,
1263 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1264 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1267 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1268 return InstanceIdentifier.builder(DpnRouters.class)
1269 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1270 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1273 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1274 BigInteger nodeId = BigInteger.ZERO;
1276 GetDpidFromInterfaceInput
1278 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1279 Future<RpcResult<GetDpidFromInterfaceOutput>>
1281 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1282 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1283 if (dpIdResult.isSuccessful()) {
1284 nodeId = dpIdResult.getResult().getDpid();
1286 LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName);
1288 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1289 LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName, e);
1294 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1296 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1299 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1300 Long tunnelKey, int pos) {
1301 LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1302 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1303 .setIntfName(ifName);
1304 if (tunnelKey != null) {
1305 egressActionsBuilder.setTunnelKey(tunnelKey);
1308 List<ActionInfo> listActionInfo = new ArrayList<>();
1310 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1311 .getEgressActionsForInterface(egressActionsBuilder.build());
1312 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1313 if (!rpcResult.isSuccessful()) {
1314 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1315 rpcResult.getErrors());
1317 List<Action> actions = rpcResult.getResult().getAction();
1318 for (Action action : actions) {
1319 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1320 actionClass = action.getAction();
1321 if (actionClass instanceof OutputActionCase) {
1322 listActionInfo.add(new ActionOutput(pos++,
1323 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1324 } else if (actionClass instanceof PushVlanActionCase) {
1325 listActionInfo.add(new ActionPushVlan(pos++));
1326 } else if (actionClass instanceof SetFieldCase) {
1327 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1328 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1329 .getVlanId().getValue();
1330 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1332 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1333 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1334 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1335 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1336 NxRegLoad nxRegLoad =
1337 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1338 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1339 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1343 } catch (InterruptedException | ExecutionException e) {
1344 LOG.warn("Exception when egress actions for interface {}", ifName, e);
1346 return listActionInfo;
1349 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1350 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1353 public static List<Port> getNeutronPorts(DataBroker broker) {
1354 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1355 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1356 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1357 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1358 portsOptional = read(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1360 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1361 LOG.trace("No neutron ports found");
1362 return Collections.EMPTY_LIST;
1365 return portsOptional.get().getPort();
1368 public static Port getNeutronPortForIp(DataBroker broker,
1369 IpAddress targetIP, String deviceType) {
1370 List<Port> ports = getNeutronPorts(
1373 for (Port port : ports) {
1374 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1375 for (FixedIps ip : port.getFixedIps()) {
1376 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1386 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1390 for (FixedIps ip : port.getFixedIps()) {
1391 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1392 return ip.getSubnetId();
1399 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1400 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1401 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1402 return read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1405 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1406 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1407 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1408 Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1409 return optionalNetworkMap.isPresent() ? optionalNetworkMap.get().getSubnetIdList() : null;
1412 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1413 if (subnetId == null) {
1417 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1418 .child(Subnet.class, new SubnetKey(subnetId));
1419 Optional<Subnet> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst);
1420 if (!subnetOpt.isPresent()) {
1424 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1425 if (gatewayIp == null) {
1426 LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1430 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1431 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1433 Optional<VpnPortipToPort> portIpToPortOpt = read(broker, LogicalDatastoreType.CONFIGURATION, portIpInst);
1434 if (portIpToPortOpt.isPresent()) {
1435 return portIpToPortOpt.get().getMacAddress();
1438 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1439 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1441 Optional<LearntVpnVipToPort> learntIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, learntIpInst);
1442 if (learntIpToPortOpt.isPresent()) {
1443 return learntIpToPortOpt.get().getMacAddress();
1446 LOG.error("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1450 public static boolean isIPv6Subnet(String prefix) {
1451 return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1454 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1455 return InstanceIdentifier.builder(DpnRouters.class)
1456 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1459 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1460 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1461 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1462 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1465 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1466 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1467 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1470 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1471 InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1472 Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1473 .CONFIGURATION, id);
1474 if (optFloatingIpIdToPortMapping.isPresent()) {
1475 return optFloatingIpIdToPortMapping.get().getFloatingIpPortMacAddress();
1480 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1481 InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1482 Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1483 .CONFIGURATION, id);
1484 if (optFloatingIpIdToPortMapping.isPresent()) {
1485 return optFloatingIpIdToPortMapping.get().getFloatingIpPortSubnetId();
1490 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1491 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1492 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1495 static final FutureCallback<Void> DEFAULT_CALLBACK =
1496 new FutureCallback<Void>() {
1498 public void onSuccess(Void result) {
1499 LOG.debug("NAT Service : Success in Datastore operation");
1503 public void onFailure(Throwable error) {
1504 LOG.error("NAT Service : Error in Datastore operation", error);
1510 static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1511 InstanceIdentifier<T> path) {
1512 delete(broker, datastoreType, path, DEFAULT_CALLBACK);
1515 static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1516 InstanceIdentifier<T> path, FutureCallback<Void> callback) {
1517 WriteTransaction tx = broker.newWriteOnlyTransaction();
1518 tx.delete(datastoreType, path);
1519 Futures.addCallback(tx.submit(), callback);
1522 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1523 InstanceIdentifier<Interface> ifStateId =
1524 buildStateInterfaceId(interfaceName);
1525 Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
1526 if (ifStateOptional.isPresent()) {
1527 return ifStateOptional.get();
1533 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1534 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1535 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1536 .interfaces.rev140508.InterfacesState.class)
1537 .child(Interface.class,
1538 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1539 .interfaces.state.InterfaceKey(interfaceName));
1540 InstanceIdentifier<Interface> id = idBuilder.build();
1544 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1545 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1546 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerIdentifier);
1547 if (routerData.isPresent()) {
1548 return routerData.get();
1553 static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) {
1554 long routerId = NatUtil.getVpnId(dataBroker, routerName);
1555 if (routerId == NatConstants.INVALID_ID) {
1556 LOG.error("NAT Service : createRouterIdsConfigDS - invalid routerId for routerName {}", routerName);
1559 RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1560 .setRouterId(routerId).setRouterName(routerName).build();
1561 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1564 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1565 IdManagerService idManager) {
1566 InetAddress defaultIP = null;
1568 defaultIP = InetAddress.getByName("0.0.0.0");
1569 } catch (UnknownHostException e) {
1570 LOG.error("NAT Service : UnknowHostException in buildDefNATFlowEntityForExternalSubnet. "
1571 + "Failed to build FIB Table Flow for Default Route to NAT.");
1575 List<MatchInfo> matches = new ArrayList<>();
1576 matches.add(MatchEthernetType.IPV4);
1577 //add match for vrfid
1578 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1580 List<InstructionInfo> instructions = new ArrayList<>();
1581 List<ActionInfo> actionsInfo = new ArrayList<>();
1582 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1583 actionsInfo.add(new ActionGroup(groupId));
1584 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1585 instructions.add(new InstructionApplyActions(actionsInfo));
1586 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1587 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1588 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1592 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1593 String routerName = getRouterName(broker, routerId);
1594 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1595 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1596 if (routerData.isPresent()) {
1597 return routerData.get().getExtGwMacAddress();
1602 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1603 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1604 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1605 .child(Router.class, new RouterKey(routerUuid));
1606 return routerInstanceIdentifier;
1609 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1610 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1611 Optional<Router> neutronRouterData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1612 neutronRouterIdentifier);
1613 if (neutronRouterData.isPresent()) {
1614 return neutronRouterData.get().getName();
1619 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1621 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1622 Optional<RouterPorts> routerPortsData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1623 routerPortsIdentifier);
1624 if (routerPortsData.isPresent()) {
1625 return routerPortsData.get().getPorts();
1630 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1631 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1632 Optional<ExternalNetworks> externalNwData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1633 externalNwIdentifier);
1634 if (externalNwData.isPresent()) {
1635 for (Networks externalNw : externalNwData.get().getNetworks()) {
1636 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1637 return externalNw.getRouterIds();
1644 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1647 long ipLo = ipToLong(InetAddress.getByName(start));
1648 long ipHi = ipToLong(InetAddress.getByName(end));
1649 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1650 return ipToTest >= ipLo && ipToTest <= ipHi;
1651 } catch (UnknownHostException e) {
1652 LOG.error("NAT Service : isIpInSubnet failed for IP {}. Exception {}", ipAddress, e.getMessage());
1657 public static List<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1658 if (externalIps == null) {
1659 return Collections.emptyList();
1662 Set<Uuid> subnetsSet = externalIps.stream().map(externalIp -> externalIp.getSubnetId())
1663 .collect(Collectors.toSet());
1664 return new ArrayList<>(subnetsSet);
1667 public static List<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1668 if (routerName == null) {
1669 LOG.error("getExternalSubnetIdsForRouter - empty routerName received");
1673 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1674 Optional<Routers> routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1675 if (routerData.isPresent()) {
1676 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1678 LOG.warn("No external router data for router {}", routerName);
1679 return Collections.emptyList();
1684 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1685 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1686 if (subnetId == null) {
1687 LOG.warn("getOptionalExternalSubnets - null subnetId");
1688 return Optional.absent();
1691 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1692 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1693 InstanceIdentifier.builder(ExternalSubnets.class)
1694 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1695 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1696 return read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1699 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1700 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1701 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1703 if (optionalExternalSubnets.isPresent()) {
1704 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1707 return NatConstants.INVALID_ID;
1710 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1712 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(dataBroker, externalIpAddress, router);
1713 if (externalSubnetId != null) {
1714 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1717 return NatConstants.INVALID_ID;
1720 protected static Uuid getExternalSubnetForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1722 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1723 List<ExternalIps> externalIps = router.getExternalIps();
1724 for (ExternalIps extIp : externalIps) {
1725 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1726 if (extIpString.equals(externalIpAddress)) {
1727 return extIp.getSubnetId();
1734 private static long ipToLong(InetAddress ip) {
1735 byte[] octets = ip.getAddress();
1737 for (byte octet : octets) {
1739 result |= octet & 0xff;
1744 static List<String> getIpsListFromExternalIps(List<ExternalIps> externalIps) {
1745 if (externalIps == null) {
1746 return Collections.emptyList();
1749 return externalIps.stream().map(externalIp -> externalIp.getIpAddress()).collect(Collectors.toList());
1752 // elan-instances config container
1753 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1754 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1755 return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1758 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1759 return InstanceIdentifier.builder(ElanInstances.class)
1760 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1764 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1765 IdManagerService idManager, long routerId, String routerName) {
1766 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1767 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1768 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1770 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1774 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1776 LOG.debug("NAT Service : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1777 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1779 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1780 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1781 List<MatchInfo> matches = new ArrayList<>();
1782 matches.add(MatchEthernetType.IPV4);
1783 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1784 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1785 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1786 matches, preDnatToSnatInstructions);
1788 mdsalManager.installFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1789 LOG.debug("NAT Service : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1790 preDnatToSnatTableFlowEntity, naptDpnId);
1793 public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId) {
1794 LOG.debug("NAT Service : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1795 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1796 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1797 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1798 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null);
1799 mdsalManager.removeFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1800 LOG.debug("NAT Service : Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1801 preDnatToSnatTableFlowEntity, naptDpnId);
1804 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1805 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1806 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1809 public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1810 String vpnName, String externalIp,
1811 Boolean isMoreThanOneFipCheckOnDpn) {
1812 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1813 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1814 if (dpnInVpn.isPresent()) {
1815 LOG.debug("vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, rd {} and floatingIp {}",
1816 vpnName, dpnId, rd, externalIp);
1817 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1818 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1819 int floatingIpPresentCount = 0;
1820 for (IpAddresses ipAddress: ipAddressList) {
1821 if (!ipAddress.getIpAddress().equals(externalIp)
1822 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1823 floatingIpPresentCount++;
1824 //Add tunnel table check
1825 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1826 return Boolean.TRUE;
1828 //Remove tunnel table check
1829 if (!isMoreThanOneFipCheckOnDpn) {
1830 return Boolean.TRUE;
1835 LOG.debug("vpn-to-dpn-list does not contain any floating IP for DPN {}", dpnId);
1836 return Boolean.FALSE;
1839 return Boolean.FALSE;
1842 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1843 return InstanceIdentifier.builder(VpnInstanceOpData.class)
1844 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1845 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1848 public static void createOrUpdateVpnToDpnList(DataBroker dataBroker, long vpnId, BigInteger dpnId, String intfName,
1849 String vpnName, WriteTransaction writeTxn) {
1850 String primaryRd = getPrimaryRd(dataBroker, vpnName);
1851 Boolean newDpnOnVpn = Boolean.FALSE;
1853 synchronized (vpnName.intern()) {
1854 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(primaryRd, dpnId);
1855 Optional<VpnToDpnList> dpnInVpn = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1856 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance
1857 .op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface = new VpnInterfacesBuilder()
1858 .setInterfaceName(intfName).build();
1860 if (dpnInVpn.isPresent()) {
1861 VpnToDpnList vpnToDpnList = dpnInVpn.get();
1862 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1863 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = vpnToDpnList
1864 .getVpnInterfaces();
1865 if (vpnInterfaces == null) {
1866 vpnInterfaces = new ArrayList<>();
1868 vpnInterfaces.add(vpnInterface);
1869 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
1870 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
1872 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
1873 /* If earlier state was inactive, it is considered new DPN coming back to the
1876 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
1877 newDpnOnVpn = Boolean.TRUE;
1880 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1881 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces>
1882 vpnInterfaces = new ArrayList<>();
1883 vpnInterfaces.add(vpnInterface);
1884 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
1885 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
1887 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
1888 newDpnOnVpn = Boolean.TRUE;
1893 public static void removeOrUpdateVpnToDpnList(DataBroker dataBroker, long vpnId, BigInteger dpnId, String intfName,
1894 String vpnName, WriteTransaction writeTxn) {
1895 Boolean lastDpnOnVpn = Boolean.FALSE;
1896 String rd = getVpnRd(dataBroker, vpnName);
1897 synchronized (vpnName.intern()) {
1898 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1899 VpnToDpnList dpnInVpn = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
1900 if (dpnInVpn == null) {
1901 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
1902 + " and dpnId={}", vpnName, rd, id, dpnId);
1905 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1906 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
1907 if (vpnInterfaces == null) {
1908 LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
1909 vpnName, rd, id, dpnId);
1913 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1914 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces currVpnInterface = new VpnInterfacesBuilder()
1915 .setInterfaceName(intfName).build();
1916 if (vpnInterfaces.remove(currVpnInterface)) {
1917 if (vpnInterfaces.isEmpty()) {
1918 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
1919 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
1920 if (ipAddresses == null || ipAddresses.isEmpty()) {
1921 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
1922 lastDpnOnVpn = Boolean.TRUE;
1924 LOG.warn("vpn interfaces are empty but ip addresses are present for the vpn {} in dpn {}",
1927 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
1930 writeTxn.delete(LogicalDatastoreType.OPERATIONAL, id.child(org.opendaylight.yang.gen.v1.urn
1931 .opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry
1932 .vpn.to.dpn.list.VpnInterfaces.class, new VpnInterfacesKey(intfName)));
1935 } // Ends synchronized block
1937 /* if (lastDpnOnVpn) {
1938 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
1939 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd, new DpnEnterExitVpnWorker(dpnId, vpnName, rd,
1944 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
1945 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1946 Optional<VpnInstance> vpnInstance = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1947 if (vpnInstance.isPresent()) {
1948 return getPrimaryRd(vpnInstance.get());
1953 public static String getPrimaryRd(VpnInstance vpnInstance) {
1954 List<String> rds = null;
1955 if (vpnInstance != null) {
1956 rds = getListOfRdsFromVpnInstance(vpnInstance);
1958 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
1961 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
1962 return InstanceIdentifier.builder(VpnInstances.class)
1963 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
1966 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
1967 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
1968 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
1969 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
1972 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
1973 if (routerName != null) {
1974 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1975 if (extRouter != null) {
1976 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
1980 return NatConstants.INVALID_ID;
1983 public static void djcFlow(FlowEntity flowEntity, int addOrRemove, IMdsalApiManager mdsalManager) {
1984 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1985 String jobKey = (flowEntity.getFlowName() != null) ? flowEntity.getFlowName() : flowEntity.getFlowId();
1986 dataStoreCoordinator.enqueueJob(jobKey, () -> {
1987 List<ListenableFuture<Void>> futures = new ArrayList<>();
1988 if (addOrRemove == NwConstants.ADD_FLOW) {
1989 futures.add(mdsalManager.installFlow(flowEntity));
1991 futures.add(mdsalManager.removeFlow(flowEntity));
1997 public static String validateAndAddNetworkMask(String ipAddress) {
1998 return ipAddress.contains("/32") ? ipAddress : (ipAddress + "/32");