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.ListenableFuture;
13 import java.math.BigInteger;
14 import java.net.InetAddress;
15 import java.net.UnknownHostException;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
23 import java.util.Objects;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26 import java.util.stream.Collectors;
28 import javax.annotation.Nonnull;
29 import javax.annotation.Nullable;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
34 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
35 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
36 import org.opendaylight.genius.mdsalutil.ActionInfo;
37 import org.opendaylight.genius.mdsalutil.FlowEntity;
38 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
39 import org.opendaylight.genius.mdsalutil.InstructionInfo;
40 import org.opendaylight.genius.mdsalutil.MDSALUtil;
41 import org.opendaylight.genius.mdsalutil.MatchInfo;
42 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
43 import org.opendaylight.genius.mdsalutil.NwConstants;
44 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
45 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
46 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
47 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
48 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
49 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
50 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
51 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
52 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
53 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
54 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
55 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
56 import org.opendaylight.netvirt.elanmanager.api.IElanService;
57 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
58 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
59 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
60 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
61 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
62 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
63 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
64 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
65 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
66 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
128 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;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
167 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;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
203 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;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
205 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
206 import org.opendaylight.yangtools.yang.common.RpcResult;
207 import org.slf4j.Logger;
208 import org.slf4j.LoggerFactory;
210 public class NatUtil {
212 private static String OF_URI_SEPARATOR = ":";
213 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
216 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
219 public static BigInteger getCookieSnatFlow(long routerId) {
220 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
221 BigInteger.valueOf(routerId));
225 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
228 public static BigInteger getCookieNaptFlow(long routerId) {
229 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
230 BigInteger.valueOf(routerId));
234 getVpnId() returns the VPN ID from the VPN name
236 public static long getVpnId(DataBroker broker, String vpnName) {
237 if (vpnName == null) {
238 return NatConstants.INVALID_ID;
241 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
242 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
243 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
244 .instance.to.vpn.id.VpnInstance> vpnInstance =
245 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
246 LogicalDatastoreType.CONFIGURATION, id);
248 long vpnId = NatConstants.INVALID_ID;
249 if (vpnInstance.isPresent()) {
250 Long vpnIdAsLong = vpnInstance.get().getVpnId();
251 if (vpnIdAsLong != null) {
258 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
259 //Get the external network ID from the ExternalRouter model
260 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
261 if (networkId == null) {
262 LOG.error("NAT Service : networkId is null");
263 return NatConstants.INVALID_ID;
266 //Get the VPN ID from the ExternalNetworks model
267 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
268 if (vpnUuid == null) {
269 LOG.error("NAT Service : vpnUuid is null");
270 return NatConstants.INVALID_ID;
272 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
276 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
277 return InstanceIdentifier.builder(FloatingIpInfo.class)
278 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
281 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
282 return InstanceIdentifier.builder(RouterToVpnMapping.class)
283 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
286 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
287 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
288 .child(Ports.class, new PortsKey(portName)).build();
291 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
293 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
294 .child(Ports.class, new PortsKey(portName))
295 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
298 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
299 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
300 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
301 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
302 .instance.to.vpn.id.VpnInstance.class,
303 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
304 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
307 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
308 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
309 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
310 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
311 LogicalDatastoreType.CONFIGURATION, id).transform(VpnIds::getVpnInstanceName).orNull();
315 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
317 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
318 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
319 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
322 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
323 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
324 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
327 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
328 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
329 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
333 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
334 String routerName = getRouterName(broker, routerId);
335 if (routerName == null) {
336 LOG.error("getNetworkIdFromRouterId - empty routerName received");
339 return getNetworkIdFromRouterName(broker, routerName);
342 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
343 if (routerName == null) {
344 LOG.error("getNetworkIdFromRouterName - empty routerName received");
347 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
348 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
349 LogicalDatastoreType.CONFIGURATION, id).transform(Routers::getNetworkId).orNull();
352 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
353 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
354 .child(Routers.class, new RoutersKey(routerId)).build();
355 return routerInstanceIndentifier;
358 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
359 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
360 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
365 * Return if SNAT is enabled for the given router.
367 * @param broker The DataBroker
368 * @param routerId The router
369 * @return boolean true if enabled, otherwise false
371 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
372 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
373 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
374 LogicalDatastoreType.CONFIGURATION, id).transform(Routers::isEnableSnat).or(false);
377 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
378 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
379 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
380 LogicalDatastoreType.CONFIGURATION, id).transform(Networks::getVpnid).orNull();
383 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
384 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
385 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
386 LogicalDatastoreType.CONFIGURATION, id).transform(Networks::getProviderNetworkType).orNull();
390 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
391 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
392 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
393 LogicalDatastoreType.CONFIGURATION, id).transform(Networks::getRouterIds).or(Collections.emptyList());
396 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
397 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
398 Optional<Routers> routerData =
399 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
400 LogicalDatastoreType.CONFIGURATION, id);
401 if (routerData.isPresent()) {
402 Uuid networkId = routerData.get().getNetworkId();
403 if (networkId != null) {
404 return networkId.getValue();
410 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
411 return InstanceIdentifier.builder(ExternalNetworks.class)
412 .child(Networks.class, new NetworksKey(networkId)).build();
415 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
416 // convert routerId to Name
417 String routerName = getRouterName(broker, routerId);
418 if (routerName == null) {
419 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
422 return getPrimaryNaptfromRouterName(broker, routerName);
425 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
426 if (routerName == null) {
427 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
430 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
431 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
432 LogicalDatastoreType.CONFIGURATION, id).transform(RouterToNaptSwitch::getPrimarySwitchId).orNull();
435 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
436 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
437 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
441 public static String getRouterName(DataBroker broker, Long routerId) {
442 InstanceIdentifier<RouterIds> id = buildRouterIdentifier(routerId);
443 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
444 LogicalDatastoreType.CONFIGURATION, id).transform(RouterIds::getRouterName).orNull();
447 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
448 return InstanceIdentifier.builder(VpnInstanceOpData.class)
449 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
452 public static long readVpnId(DataBroker broker, String vpnName) {
453 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
454 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
455 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
456 LogicalDatastoreType.CONFIGURATION, id).transform(
457 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
458 .VpnInstance::getVpnId).or(
459 NatConstants.INVALID_ID);
462 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
463 return new FlowEntityBuilder()
471 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
472 return new FlowEntityBuilder()
479 public static long getIpAddress(byte[] rawIpAddress) {
480 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
481 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
484 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
485 String nextHopIp = null;
486 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
487 InstanceIdentifier.builder(DpnEndpoints.class)
488 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
489 Optional<DPNTEPsInfo> tunnelInfo =
490 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
491 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
492 if (tunnelInfo.isPresent()) {
493 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
494 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
495 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
501 public static String getVpnRd(DataBroker broker, String vpnName) {
503 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
504 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
505 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
506 LogicalDatastoreType.CONFIGURATION, id).transform(
507 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
508 .VpnInstance::getVrfId).orNull();
511 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
512 String internalPort, NAPTEntryEvent.Protocol protocol) {
513 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
514 InstanceIdentifier<IpPortMap> ipPortMapId =
515 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
516 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
517 LogicalDatastoreType.CONFIGURATION, ipPortMapId).transform(IpPortMap::getIpPortExternal).orNull();
520 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
522 ProtocolTypes protocolType) {
523 return InstanceIdentifier.builder(IntextIpPortMap.class)
524 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
525 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
526 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
529 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
530 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
531 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
532 LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
535 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
536 return InstanceIdentifier.builder(VpnInterfaces.class)
537 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
540 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
541 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
542 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
543 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
546 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
548 * NodeConnectorId is of form 'openflow:dpnid:portnum'
550 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
551 if (split.length != 3) {
557 public static BigInteger getDpIdFromInterface(
558 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
559 .state.Interface ifState) {
560 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
561 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
562 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
565 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
566 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
567 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
568 Optional<VpnMap> optionalVpnMap =
569 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
570 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
571 if (optionalVpnMap.isPresent()) {
572 Uuid routerId = optionalVpnMap.get().getRouterId();
573 if (routerId != null) {
574 return routerId.getValue();
580 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
581 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
582 Optional<VpnMaps> optionalVpnMaps =
583 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
584 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
585 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
586 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
587 if (routerId != null) {
588 for (VpnMap vpnMap : allMaps) {
589 if (vpnMap.getRouterId() != null
590 && routerId.equals(vpnMap.getRouterId().getValue())
591 && !routerId.equals(vpnMap.getVpnId().getValue())) {
592 return vpnMap.getVpnId();
600 static long getAssociatedVpn(DataBroker broker, String routerName) {
601 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
602 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
603 LogicalDatastoreType.OPERATIONAL, routerMappingId).transform(Routermapping::getVpnId).or(
604 NatConstants.INVALID_ID);
607 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
608 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
609 if (vpnUuid == null) {
610 log.error("No VPN instance associated with ext network {}", networkId);
613 return vpnUuid.getValue();
616 // TODO Clean up the exception handling
617 @SuppressWarnings("checkstyle:IllegalCatch")
618 public static void addPrefixToBGP(DataBroker broker,
619 IBgpManager bgpManager,
620 IFibManager fibManager,
630 Logger log, RouteOrigin origin, BigInteger dpId) {
632 LOG.info("NAT Service : ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
633 prefix, nextHopIp, label);
634 if (nextHopIp == null) {
635 LOG.error("NAT Service : addPrefix prefix {} rd {} failed since nextHopIp cannot be null.", prefix, rd);
639 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId, subnetId,
640 /*isNatPrefix*/ true);
641 fibManager.addOrUpdateFibEntry(broker, rd, macAddress, prefix,
642 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
643 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
644 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
645 /* Publish to Bgp only if its an INTERNET VPN */
646 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
647 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
648 null /*gatewayMac*/);
650 LOG.info("NAT Service : ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
651 prefix, nextHopIp, label);
652 } catch (Exception e) {
653 LOG.error("NAT Service : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
654 prefix, nextHopIp, label, e);
658 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
659 BigInteger dpId, Uuid subnetId, boolean isNatPrefix) {
660 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
661 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
662 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
663 .to._interface.VpnIdsKey(vpnId))
664 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
665 Prefixes prefix = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix).setVpnInterfaceName(interfaceName)
666 .setNatPrefix(isNatPrefix).setSubnetId(subnetId).build();
668 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId, prefix);
669 } catch (TransactionCommitFailedException e) {
670 LOG.error("Failed to write prefxi-to-interface for {} vpn-id {} DPN {}", ipPrefix, vpnId, dpId);
674 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
675 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
676 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
680 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
681 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
682 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
683 return routerInstanceIndentifier;
687 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
688 String internalIpAddress, ProtocolTypes protocolType) {
689 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
690 LogicalDatastoreType.CONFIGURATION,
691 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).transform(
692 IntIpProtoType::getPorts).or(Collections.emptyList());
695 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
696 String internalIpAddress,
697 ProtocolTypes protocolType) {
698 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
699 InstanceIdentifier.builder(SnatintIpPortMap.class)
700 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
701 .child(IpPort.class, new IpPortKey(internalIpAddress))
702 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
703 return intIpProtocolTypeId;
706 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
707 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
708 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
712 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
713 return InstanceIdentifier.create(NaptSwitches.class);
716 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
717 return InstanceIdentifier.create(NaptSwitches.class)
718 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
721 public static String getGroupIdKey(String routerName) {
722 return "snatmiss." + routerName;
725 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
726 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
727 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
730 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
731 RpcResult<AllocateIdOutput> rpcResult = result.get();
732 return rpcResult.getResult().getIdValue();
733 } catch (NullPointerException | InterruptedException | ExecutionException e) {
739 // TODO Clean up the exception handling
740 @SuppressWarnings("checkstyle:IllegalCatch")
741 public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager,
742 String rd, String prefix, String vpnName, Logger log) {
744 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
745 fibManager.removeFibEntry(broker, rd, prefix, null);
746 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
747 bgpManager.withdrawPrefix(rd, prefix);
749 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
750 } catch (Exception e) {
751 log.error("Delete prefix for rd {} prefix {} vpnName {} failed", rd, prefix, vpnName, e);
755 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
756 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
757 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
760 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
761 return InstanceIdentifier.builder(IntextIpPortMap.class)
762 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
765 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
766 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
767 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
768 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
769 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
770 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
771 .intext.ip.map.IpMappingKey(routerId)).build();
776 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
777 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
778 .ip.map.IpMapping> ipMappingOptional =
779 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
780 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
781 // Ensure there are no duplicates
782 Collection<String> externalIps = new HashSet<>();
783 if (ipMappingOptional.isPresent()) {
784 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
785 for (IpMap ipMap : ipMaps) {
786 externalIps.add(ipMap.getExternalIp());
793 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
794 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
795 if (routerData != null) {
796 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
799 return Collections.emptyList();
803 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
804 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
805 .ip.map.IpMapping> ipMappingOptional =
806 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
807 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
808 Map<String, Long> externalIpsLabel = new HashMap<>();
809 if (ipMappingOptional.isPresent()) {
810 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
811 for (IpMap ipMap : ipMaps) {
812 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
815 return externalIpsLabel;
818 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
819 String leastLoadedExternalIp = null;
820 InstanceIdentifier<ExternalCounters> id =
821 InstanceIdentifier.builder(ExternalIpsCounter.class)
822 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
823 Optional<ExternalCounters> externalCountersData =
824 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
825 if (externalCountersData.isPresent()) {
826 ExternalCounters externalCounter = externalCountersData.get();
827 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
828 short countOfLstLoadExtIp = 32767;
829 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
830 String curExternalIp = externalIpCounter.getExternalIp();
831 short countOfCurExtIp = externalIpCounter.getCounter();
832 if (countOfCurExtIp < countOfLstLoadExtIp) {
833 countOfLstLoadExtIp = countOfCurExtIp;
834 leastLoadedExternalIp = curExternalIp;
838 return leastLoadedExternalIp;
841 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
842 String subnetIP = getSubnetIp(dataBroker, subnetId);
843 if (subnetIP != null) {
844 return getSubnetIpAndPrefix(subnetIP);
849 public static String[] getSubnetIpAndPrefix(String subnetString) {
850 String[] subnetSplit = subnetString.split("/");
851 String subnetIp = subnetSplit[0];
852 String subnetPrefix = "0";
853 if (subnetSplit.length == 2) {
854 subnetPrefix = subnetSplit[1];
856 return new String[] {subnetIp, subnetPrefix};
859 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
860 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
861 .builder(Subnetmaps.class)
862 .child(Subnetmap.class, new SubnetmapKey(subnetId))
864 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
865 LogicalDatastoreType.CONFIGURATION, subnetmapId).transform(Subnetmap::getSubnetIp).orNull();
869 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
870 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
871 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
872 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
873 if (leastLoadedExtIpAddrSplit.length == 2) {
874 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
876 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
880 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
881 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
882 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
883 Optional<RouterDpnList> routerDpnListData =
884 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
885 LogicalDatastoreType.OPERATIONAL, id);
886 List<BigInteger> dpns = new ArrayList<>();
887 if (routerDpnListData.isPresent()) {
888 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
889 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
890 dpns.add(dpnVpnInterface.getDpnId());
896 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
897 long bgpVpnId = NatConstants.INVALID_ID;
898 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
899 if (bgpVpnUuid != null) {
900 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
905 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
906 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
907 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
908 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
911 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
912 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
913 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
914 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
915 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
916 .RouterInterface.class,
917 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
918 .RouterInterfaceKey(interfaceName)).build();
921 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
922 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
923 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
924 addToNeutronRouterDpnsMap(broker, routerName, interfaceName, dpId, writeOperTxn);
927 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
928 BigInteger dpId , WriteTransaction writeOperTxn) {
930 if (dpId.equals(BigInteger.ZERO)) {
931 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
932 interfaceName, routerName);
936 LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the "
937 + "ODL-L3VPN : NeutronRouterDpn map",
938 routerName, dpId, interfaceName);
939 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
941 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList =
942 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
943 LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier);
944 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
945 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
946 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
947 .setInterface(interfaceName).build();
948 if (optionalDpnVpninterfacesList.isPresent()) {
949 LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the "
950 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
951 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
952 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
953 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
954 new RouterInterfacesKey(interfaceName)), routerInterface, true);
956 LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the "
957 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
958 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
959 routerDpnListBuilder.setRouterId(routerName);
960 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
961 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
962 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
963 routerInterfaces.add(routerInterface);
964 dpnVpnList.setRouterInterfaces(routerInterfaces);
965 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
966 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
967 getRouterId(routerName),
968 routerDpnListBuilder.build(), true);
973 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
974 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
975 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
976 addToDpnRoutersMap(broker, routerName, interfaceName, dpId, writeOperTxn);
979 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
980 BigInteger dpId, WriteTransaction writeOperTxn) {
981 if (dpId.equals(BigInteger.ZERO)) {
982 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
983 interfaceName, routerName);
987 LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
989 dpId, routerName, interfaceName);
990 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
992 Optional<DpnRoutersList> optionalDpnRoutersList =
993 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
994 LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
996 if (optionalDpnRoutersList.isPresent()) {
997 RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
998 .setRouter(routerName).build();
999 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1000 if (!routersListFromDs.contains(routersList)) {
1001 LOG.debug("NAT Service : Router {} not present for the DPN {}"
1002 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1003 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1004 dpnRoutersListIdentifier
1005 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1007 LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map",
1011 LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} "
1012 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1013 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1014 dpnRoutersListBuilder.setDpnId(dpId);
1015 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1016 routersListBuilder.setRouter(routerName);
1017 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1018 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1019 getDpnRoutersId(dpId),
1020 dpnRoutersListBuilder.build(), true);
1025 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1026 BigInteger dpId, WriteTransaction writeOperTxn) {
1027 if (dpId.equals(BigInteger.ZERO)) {
1028 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1029 interfaceName, routerName);
1032 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1033 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1034 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1035 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1036 if (optionalRouterDpnList.isPresent()) {
1037 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1038 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1039 optionalRouterDpnList.get().getRouterInterfaces();
1040 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1041 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1042 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1043 .setInterface(interfaceName).build();
1044 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1045 if (routerInterfaces.isEmpty()) {
1046 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1048 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1049 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1050 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1051 new RouterInterfacesKey(interfaceName)));
1057 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1058 BigInteger dpId, WriteTransaction writeOperTxn) {
1059 if (dpId.equals(BigInteger.ZERO)) {
1060 LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName);
1064 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1065 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1066 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1067 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1068 if (optionalRouterDpnList.isPresent()) {
1069 LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model "
1070 + "for the router {}", routerName);
1071 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1073 LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model "
1074 + "for the router {}", routerName);
1078 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1079 OdlInterfaceRpcService ifaceMgrRpcService,
1080 WriteTransaction writeOperTxn) {
1081 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1082 if (dpId.equals(BigInteger.ZERO)) {
1083 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1084 vpnInterfaceName, routerName);
1087 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1088 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1089 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1090 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1091 if (optionalRouterDpnList.isPresent()) {
1092 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1093 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1094 optionalRouterDpnList.get().getRouterInterfaces();
1095 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1096 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1097 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1098 .setInterface(vpnInterfaceName).build();
1100 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1101 if (routerInterfaces.isEmpty()) {
1102 if (writeOperTxn != null) {
1103 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1105 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1108 if (writeOperTxn != null) {
1109 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1110 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1111 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1112 new RouterInterfacesKey(vpnInterfaceName)));
1114 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1115 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1116 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1117 new RouterInterfacesKey(vpnInterfaceName)));
1124 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1125 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1126 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1127 if (dpId.equals(BigInteger.ZERO)) {
1128 LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} "
1129 + "to handle router {} dissociation model",
1130 vpnInterfaceName, routerName);
1133 removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1136 static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1137 BigInteger curDpnId,
1138 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1140 1) Get the DpnRoutersList for the DPN.
1141 2) Get the RoutersList identifier for the DPN and router.
1142 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1143 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1144 then remove RouterList.
1147 LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1148 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1150 //Get the dpn-routers-list instance for the current DPN.
1151 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1152 Optional<DpnRoutersList> dpnRoutersListData =
1153 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1154 LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1156 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1157 LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model",
1162 //Get the routers-list instance for the router on the current DPN only
1163 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1164 Optional<RoutersList> routersListData =
1165 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1166 LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1168 if (routersListData == null || !routersListData.isPresent()) {
1169 LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model",
1174 LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map",
1176 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1177 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1178 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1179 .RouterInterfaces> routerInterfacesData =
1180 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1181 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1183 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1184 LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed"
1185 + " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1186 curDpnId, routerName, routerName);
1187 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1191 //Get the VM interfaces for the router on the current DPN only.
1192 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1193 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1194 if (vmInterfaces == null) {
1195 LOG.debug("NAT Service : VM interfaces are not present for the router {} in the "
1196 + "NeutronVPN - router-interfaces-map", routerName);
1200 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1201 // then remove RouterList.
1202 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1203 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1204 String vmInterfaceName = vmInterface.getInterfaceId();
1205 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1206 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1207 LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of "
1208 + "the DPN ID for the checked interface {} ",
1209 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1212 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1213 LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} "
1214 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1218 LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} "
1219 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1220 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1221 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1224 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1225 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1226 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1227 .rev150602.RouterInterfacesMap.class)
1228 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1229 .interfaces.map.RouterInterfaces.class,
1230 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1231 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1234 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1235 return InstanceIdentifier.builder(DpnRouters.class)
1236 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1237 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1240 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1241 BigInteger nodeId = BigInteger.ZERO;
1243 GetDpidFromInterfaceInput
1245 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1246 Future<RpcResult<GetDpidFromInterfaceOutput>>
1248 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1249 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1250 if (dpIdResult.isSuccessful()) {
1251 nodeId = dpIdResult.getResult().getDpid();
1253 LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName);
1255 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1256 LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName, e);
1262 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1264 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1268 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1269 Long tunnelKey, int pos) {
1270 LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1271 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1272 .setIntfName(ifName);
1273 if (tunnelKey != null) {
1274 egressActionsBuilder.setTunnelKey(tunnelKey);
1277 List<ActionInfo> listActionInfo = new ArrayList<>();
1279 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1280 .getEgressActionsForInterface(egressActionsBuilder.build());
1281 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1282 if (!rpcResult.isSuccessful()) {
1283 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1284 rpcResult.getErrors());
1286 List<Action> actions = rpcResult.getResult().getAction();
1287 for (Action action : actions) {
1288 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1289 actionClass = action.getAction();
1290 if (actionClass instanceof OutputActionCase) {
1291 listActionInfo.add(new ActionOutput(pos++,
1292 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1293 } else if (actionClass instanceof PushVlanActionCase) {
1294 listActionInfo.add(new ActionPushVlan(pos++));
1295 } else if (actionClass instanceof SetFieldCase) {
1296 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1297 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1298 .getVlanId().getValue();
1299 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1301 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1302 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1303 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1304 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1305 NxRegLoad nxRegLoad =
1306 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1307 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1308 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1312 } catch (InterruptedException | ExecutionException e) {
1313 LOG.warn("Exception when egress actions for interface {}", ifName, e);
1315 return listActionInfo;
1318 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1319 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1323 public static List<Port> getNeutronPorts(DataBroker broker) {
1324 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1325 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1326 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1327 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1329 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1330 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1332 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1333 LOG.trace("No neutron ports found");
1334 return Collections.emptyList();
1337 return portsOptional.get().getPort();
1340 public static Port getNeutronPortForIp(DataBroker broker,
1341 IpAddress targetIP, String deviceType) {
1342 List<Port> ports = getNeutronPorts(
1345 for (Port port : ports) {
1346 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1347 for (FixedIps ip : port.getFixedIps()) {
1348 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1358 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1362 for (FixedIps ip : port.getFixedIps()) {
1363 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1364 return ip.getSubnetId();
1371 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1372 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1373 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1374 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1375 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1379 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1380 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1381 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1382 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1383 LogicalDatastoreType.CONFIGURATION, id).transform(NetworkMap::getSubnetIdList).or(
1384 Collections.emptyList());
1387 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1388 if (subnetId == null) {
1392 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1393 .child(Subnet.class, new SubnetKey(subnetId));
1394 Optional<Subnet> subnetOpt =
1395 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1396 LogicalDatastoreType.CONFIGURATION, subnetInst);
1397 if (!subnetOpt.isPresent()) {
1401 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1402 if (gatewayIp == null) {
1403 LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1407 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1408 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1410 Optional<VpnPortipToPort> portIpToPortOpt =
1411 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1412 LogicalDatastoreType.CONFIGURATION, portIpInst);
1413 if (portIpToPortOpt.isPresent()) {
1414 return portIpToPortOpt.get().getMacAddress();
1417 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1418 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1420 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1421 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1422 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1423 if (learntIpToPortOpt.isPresent()) {
1424 return learntIpToPortOpt.get().getMacAddress();
1427 LOG.error("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1431 public static boolean isIPv6Subnet(String prefix) {
1432 return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1435 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1436 return InstanceIdentifier.builder(DpnRouters.class)
1437 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1440 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1441 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1442 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1443 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1446 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1447 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1448 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1451 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1452 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1453 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1454 LogicalDatastoreType.CONFIGURATION, id).transform(
1455 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orNull();
1458 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1459 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1460 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1461 LogicalDatastoreType.CONFIGURATION, id).transform(
1462 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orNull();
1465 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1466 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1467 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1470 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1471 InstanceIdentifier<Interface> ifStateId =
1472 buildStateInterfaceId(interfaceName);
1473 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1474 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1477 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1478 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1479 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1480 .interfaces.rev140508.InterfacesState.class)
1481 .child(Interface.class,
1482 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1483 .interfaces.state.InterfaceKey(interfaceName));
1484 InstanceIdentifier<Interface> id = idBuilder.build();
1488 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1489 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1490 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1491 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1494 static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) {
1495 long routerId = NatUtil.getVpnId(dataBroker, routerName);
1496 if (routerId == NatConstants.INVALID_ID) {
1497 LOG.error("NAT Service : createRouterIdsConfigDS - invalid routerId for routerName {}", routerName);
1500 RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1501 .setRouterId(routerId).setRouterName(routerName).build();
1502 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1505 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1506 IdManagerService idManager) {
1507 InetAddress defaultIP = null;
1509 defaultIP = InetAddress.getByName("0.0.0.0");
1510 } catch (UnknownHostException e) {
1511 LOG.error("NAT Service : UnknowHostException in buildDefNATFlowEntityForExternalSubnet. "
1512 + "Failed to build FIB Table Flow for Default Route to NAT.");
1516 List<MatchInfo> matches = new ArrayList<>();
1517 matches.add(MatchEthernetType.IPV4);
1518 //add match for vrfid
1519 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1521 List<InstructionInfo> instructions = new ArrayList<>();
1522 List<ActionInfo> actionsInfo = new ArrayList<>();
1523 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1524 actionsInfo.add(new ActionGroup(groupId));
1525 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1526 instructions.add(new InstructionApplyActions(actionsInfo));
1527 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1528 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1529 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1533 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1534 String routerName = getRouterName(broker, routerId);
1535 if (routerName == null) {
1536 LOG.error("getExtGwMacAddFromRouterId - empty routerName received");
1539 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1540 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1541 LogicalDatastoreType.CONFIGURATION, id).transform(Routers::getExtGwMacAddress).orNull();
1544 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1545 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1546 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1547 .child(Router.class, new RouterKey(routerUuid));
1548 return routerInstanceIdentifier;
1551 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1552 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1553 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1554 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).transform(Router::getName).orNull();
1558 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1559 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1560 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1561 LogicalDatastoreType.CONFIGURATION,
1562 routerPortsIdentifier).transform(RouterPorts::getPorts).or(Collections.emptyList());
1566 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1567 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1568 Optional<ExternalNetworks> externalNwData =
1569 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1570 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1571 if (externalNwData.isPresent()) {
1572 for (Networks externalNw : externalNwData.get().getNetworks()) {
1573 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1574 return externalNw.getRouterIds();
1578 return Collections.emptyList();
1581 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1584 long ipLo = ipToLong(InetAddress.getByName(start));
1585 long ipHi = ipToLong(InetAddress.getByName(end));
1586 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1587 return ipToTest >= ipLo && ipToTest <= ipHi;
1588 } catch (UnknownHostException e) {
1589 LOG.error("NAT Service : isIpInSubnet failed for IP {}. Exception {}", ipAddress, e.getMessage());
1595 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1596 if (externalIps == null) {
1597 return Collections.emptySet();
1600 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1604 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1605 if (routerName == null) {
1606 LOG.error("getExternalSubnetIdsForRouter - empty routerName received");
1607 return Collections.emptySet();
1610 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1611 Optional<Routers> routerData =
1612 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1613 LogicalDatastoreType.CONFIGURATION, id);
1614 if (routerData.isPresent()) {
1615 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1617 LOG.warn("No external router data for router {}", routerName);
1618 return Collections.emptySet();
1623 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1624 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1625 if (subnetId == null) {
1626 LOG.warn("getOptionalExternalSubnets - null subnetId");
1627 return Optional.absent();
1630 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1631 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1632 InstanceIdentifier.builder(ExternalSubnets.class)
1633 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1634 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1635 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1636 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1639 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1640 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1641 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1643 if (optionalExternalSubnets.isPresent()) {
1644 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1647 return NatConstants.INVALID_ID;
1650 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1652 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(dataBroker, externalIpAddress, router);
1653 if (externalSubnetId != null) {
1654 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1657 return NatConstants.INVALID_ID;
1660 protected static Uuid getExternalSubnetForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1662 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1663 List<ExternalIps> externalIps = router.getExternalIps();
1664 for (ExternalIps extIp : externalIps) {
1665 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1666 if (extIpString.equals(externalIpAddress)) {
1667 return extIp.getSubnetId();
1674 private static long ipToLong(InetAddress ip) {
1675 byte[] octets = ip.getAddress();
1677 for (byte octet : octets) {
1679 result |= octet & 0xff;
1685 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1686 if (externalIps == null) {
1687 return Collections.emptyList();
1690 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1693 // elan-instances config container
1694 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1695 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1696 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1697 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1700 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1701 return InstanceIdentifier.builder(ElanInstances.class)
1702 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1705 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1706 IdManagerService idManager, long routerId, String routerName) {
1707 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1708 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1709 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1711 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1715 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1717 LOG.debug("NAT Service : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1718 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1720 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1721 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1722 List<MatchInfo> matches = new ArrayList<>();
1723 matches.add(MatchEthernetType.IPV4);
1724 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1725 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1726 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1727 matches, preDnatToSnatInstructions);
1729 mdsalManager.installFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1730 LOG.debug("NAT Service : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1731 preDnatToSnatTableFlowEntity, naptDpnId);
1734 public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId) {
1735 LOG.debug("NAT Service : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1736 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1737 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1738 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1739 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null);
1740 mdsalManager.removeFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1741 LOG.debug("NAT Service : Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1742 preDnatToSnatTableFlowEntity, naptDpnId);
1745 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1746 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1747 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1750 public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1751 String vpnName, String externalIp,
1752 Boolean isMoreThanOneFipCheckOnDpn) {
1753 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1754 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1755 if (dpnInVpn.isPresent()) {
1756 LOG.debug("vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, rd {} and floatingIp {}",
1757 vpnName, dpnId, rd, externalIp);
1759 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1760 if ((ipAddressList != null) && (ipAddressList.size() > 0)) {
1761 int floatingIpPresentCount = 0;
1762 for (IpAddresses ipAddress : ipAddressList) {
1763 if (!ipAddress.getIpAddress().equals(externalIp)
1764 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1765 floatingIpPresentCount++;
1766 //Add tunnel table check
1767 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1768 return Boolean.TRUE;
1770 //Remove tunnel table check
1771 if (!isMoreThanOneFipCheckOnDpn) {
1772 return Boolean.TRUE;
1777 LOG.debug("vpn-to-dpn-list does not contain any floating IP for DPN {}", dpnId);
1778 return Boolean.FALSE;
1780 } catch (NullPointerException e) {
1781 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
1782 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
1783 return Boolean.FALSE;
1786 return Boolean.FALSE;
1789 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1790 return InstanceIdentifier.builder(VpnInstanceOpData.class)
1791 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1792 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1795 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
1796 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1797 Optional<VpnInstance> vpnInstance =
1798 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1799 LogicalDatastoreType.CONFIGURATION, id);
1800 if (vpnInstance.isPresent()) {
1801 return getPrimaryRd(vpnInstance.get());
1806 public static String getPrimaryRd(VpnInstance vpnInstance) {
1807 List<String> rds = null;
1808 if (vpnInstance != null) {
1809 rds = getListOfRdsFromVpnInstance(vpnInstance);
1811 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
1814 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
1815 return InstanceIdentifier.builder(VpnInstances.class)
1816 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
1820 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
1821 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
1822 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
1823 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
1826 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
1827 if (routerName != null) {
1828 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1829 if (extRouter != null) {
1830 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
1834 return NatConstants.INVALID_ID;
1837 public static void djcFlow(FlowEntity flowEntity, int addOrRemove, IMdsalApiManager mdsalManager) {
1838 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1839 String jobKey = (flowEntity.getFlowName() != null) ? flowEntity.getFlowName() : flowEntity.getFlowId();
1840 dataStoreCoordinator.enqueueJob(jobKey, () -> {
1841 List<ListenableFuture<Void>> futures = new ArrayList<>();
1842 if (addOrRemove == NwConstants.ADD_FLOW) {
1843 futures.add(mdsalManager.installFlow(flowEntity));
1845 futures.add(mdsalManager.removeFlow(flowEntity));
1851 public static String validateAndAddNetworkMask(String ipAddress) {
1852 return ipAddress.contains("/32") ? ipAddress : (ipAddress + "/32");