2 * Copyright © 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.natservice.internal;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import java.math.BigInteger;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
22 import java.util.Objects;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Future;
26 import java.util.stream.Collectors;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
30 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
33 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
34 import org.opendaylight.genius.mdsalutil.ActionInfo;
35 import org.opendaylight.genius.mdsalutil.FlowEntity;
36 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
37 import org.opendaylight.genius.mdsalutil.InstructionInfo;
38 import org.opendaylight.genius.mdsalutil.MDSALUtil;
39 import org.opendaylight.genius.mdsalutil.MatchInfo;
40 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
41 import org.opendaylight.genius.mdsalutil.NwConstants;
42 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
43 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
44 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
45 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
46 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
47 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
48 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
49 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
50 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
51 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
52 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
53 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
54 import org.opendaylight.netvirt.elanmanager.api.IElanService;
55 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
56 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
57 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
58 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
59 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
60 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
61 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
62 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
63 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
64 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
65 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
127 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;
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.VpnInterfacesBuilder;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfacesKey;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
168 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;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
204 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;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
206 import org.opendaylight.yangtools.yang.binding.DataObject;
207 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
208 import org.opendaylight.yangtools.yang.common.RpcResult;
209 import org.slf4j.Logger;
210 import org.slf4j.LoggerFactory;
212 public class NatUtil {
214 private static String OF_URI_SEPARATOR = ":";
215 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
218 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
221 public static BigInteger getCookieSnatFlow(long routerId) {
222 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
223 BigInteger.valueOf(routerId));
227 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
230 public static BigInteger getCookieNaptFlow(long routerId) {
231 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
232 BigInteger.valueOf(routerId));
236 getVpnId() returns the VPN ID from the VPN name
238 public static long getVpnId(DataBroker broker, String vpnName) {
239 if (vpnName == null) {
240 return NatConstants.INVALID_ID;
243 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
244 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
245 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
246 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, 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 Optional<VpnIds> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
311 return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : null;
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 return getNetworkIdFromRouterName(broker, routerName);
338 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
339 if (routerName == null) {
340 LOG.error("getNetworkIdFromRouterName - empty routerName received");
343 InstanceIdentifier id = buildRouterIdentifier(routerName);
344 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
345 if (routerData.isPresent()) {
346 return routerData.get().getNetworkId();
351 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
352 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
353 .child(Routers.class, new RoutersKey(routerId)).build();
354 return routerInstanceIndentifier;
357 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
358 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
359 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
364 * Return if SNAT is enabled for the given router.
366 * @param broker The DataBroker
367 * @param routerId The router
368 * @return boolean true if enabled, otherwise false
370 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
371 InstanceIdentifier id = buildRouterIdentifier(routerId);
372 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
373 if (routerData.isPresent()) {
374 return routerData.get().isEnableSnat();
379 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
380 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
381 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
382 if (networkData.isPresent()) {
383 return networkData.get().getVpnid();
388 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
389 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
390 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
391 if (networkData.isPresent() && networkData.get() != null) {
392 return networkData.get().getProviderNetworkType();
397 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
398 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
399 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
400 return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList();
403 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
404 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
405 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
406 if (routerData.isPresent()) {
407 Uuid networkId = routerData.get().getNetworkId();
408 if (networkId != null) {
409 return networkId.getValue();
415 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
416 InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class)
417 .child(Networks.class, new NetworksKey(networkId)).build();
421 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
422 // convert routerId to Name
423 String routerName = getRouterName(broker, routerId);
424 return getPrimaryNaptfromRouterName(broker, routerName);
427 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
428 if (routerName == null) {
429 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
432 InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
433 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
434 if (routerToNaptSwitchData.isPresent()) {
435 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
436 return routerToNaptSwitchInstance.getPrimarySwitchId();
441 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
442 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
443 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
447 public static String getRouterName(DataBroker broker, Long routerId) {
448 InstanceIdentifier id = buildRouterIdentifier(routerId);
449 Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
450 if (routerIdsData.isPresent()) {
451 RouterIds routerIdsInstance = routerIdsData.get();
452 return routerIdsInstance.getRouterName();
457 // TODO Clean up the exception handling
458 @SuppressWarnings("checkstyle:IllegalCatch")
459 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
460 InstanceIdentifier<T> path) {
462 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
465 return tx.read(datastoreType, path).get();
466 } catch (Exception e) {
467 throw new RuntimeException(e);
471 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
472 return InstanceIdentifier.builder(VpnInstanceOpData.class)
473 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
476 public static long readVpnId(DataBroker broker, String vpnName) {
477 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
478 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
479 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
480 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
482 long vpnId = NatConstants.INVALID_ID;
483 if (vpnInstance.isPresent()) {
484 vpnId = vpnInstance.get().getVpnId();
490 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
491 return new FlowEntityBuilder()
499 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
500 return new FlowEntityBuilder()
507 public static long getIpAddress(byte[] rawIpAddress) {
508 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
509 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
512 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
513 String nextHopIp = null;
514 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
515 InstanceIdentifier.builder(DpnEndpoints.class)
516 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
517 Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
518 if (tunnelInfo.isPresent()) {
519 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
520 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
521 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
527 public static String getVpnRd(DataBroker broker, String vpnName) {
529 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
530 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
531 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
532 .instance.to.vpn.id.VpnInstance> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
535 if (vpnInstance.isPresent()) {
536 rd = vpnInstance.get().getVrfId();
541 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
542 String internalPort, NAPTEntryEvent.Protocol protocol) {
543 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
544 InstanceIdentifier ipPortMapId =
545 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
546 Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
547 if (ipPortMapData.isPresent()) {
548 IpPortMap ipPortMapInstance = ipPortMapData.get();
549 return ipPortMapInstance.getIpPortExternal();
554 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
556 ProtocolTypes protocolType) {
557 InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class)
558 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
559 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
560 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
564 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
565 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
566 return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
569 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
570 return InstanceIdentifier.builder(VpnInterfaces.class)
571 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
574 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
575 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
576 return read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
579 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
581 * NodeConnectorId is of form 'openflow:dpnid:portnum'
583 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
584 if (split == null || split.length != 3) {
590 public static BigInteger getDpIdFromInterface(
591 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
592 .state.Interface ifState) {
593 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
594 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
595 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
598 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
599 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
600 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
601 Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
603 if (optionalVpnMap.isPresent()) {
604 Uuid routerId = optionalVpnMap.get().getRouterId();
605 if (routerId != null) {
606 return routerId.getValue();
612 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
613 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
614 Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
616 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
617 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
618 if (routerId != null) {
619 for (VpnMap vpnMap : allMaps) {
620 if (vpnMap.getRouterId() != null
621 && routerId.equals(vpnMap.getRouterId().getValue())
622 && !routerId.equals(vpnMap.getVpnId().getValue())) {
623 return vpnMap.getVpnId();
631 static long getAssociatedVpn(DataBroker broker, String routerName) {
632 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
633 Optional<Routermapping> optRouterMapping =
634 NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
635 if (optRouterMapping.isPresent()) {
636 Routermapping routerMapping = optRouterMapping.get();
637 return routerMapping.getVpnId();
639 return NatConstants.INVALID_ID;
642 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
643 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
644 if (vpnUuid == null) {
645 log.error("No VPN instance associated with ext network {}", networkId);
648 return vpnUuid.getValue();
651 // TODO Clean up the exception handling
652 @SuppressWarnings("checkstyle:IllegalCatch")
653 public static void addPrefixToBGP(DataBroker broker,
654 IBgpManager bgpManager,
655 IFibManager fibManager,
665 Logger log, RouteOrigin origin, BigInteger dpId) {
667 LOG.info("NAT Service : ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
668 prefix, nextHopIp, label);
669 if (nextHopIp == null) {
670 LOG.error("NAT Service : addPrefix prefix {} rd {} failed since nextHopIp cannot be null.", prefix, rd);
674 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId, subnetId,
675 /*isNatPrefix*/ true);
676 fibManager.addOrUpdateFibEntry(broker, rd, macAddress, prefix,
677 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
678 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
679 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
680 /* Publish to Bgp only if its an INTERNET VPN */
681 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
682 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/, null /*gatewayMac*/);
684 LOG.info("NAT Service : ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
685 prefix, nextHopIp, label);
686 } catch (Exception e) {
687 LOG.error("NAT Service : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
688 prefix, nextHopIp, label, e);
692 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
693 BigInteger dpId, Uuid subnetId, boolean isNatPrefix) {
694 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
695 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
696 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
697 .to._interface.VpnIdsKey(vpnId))
698 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
699 Prefixes prefix = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix).setVpnInterfaceName(interfaceName)
700 .setNatPrefix(isNatPrefix).setSubnetId(subnetId).build();
702 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId, prefix);
703 } catch (TransactionCommitFailedException e) {
704 LOG.error("Failed to write prefxi-to-interface for {} vpn-id {} DPN {}", ipPrefix, vpnId, dpId);
708 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
709 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
710 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
714 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
715 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
716 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
717 return routerInstanceIndentifier;
720 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
721 String internalIpAddress, ProtocolTypes protocolType) {
722 Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION,
723 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
724 if (optionalIpProtoType.isPresent()) {
725 return optionalIpProtoType.get().getPorts();
730 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
731 String internalIpAddress,
732 ProtocolTypes protocolType) {
733 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
734 InstanceIdentifier.builder(SnatintIpPortMap.class)
735 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
736 .child(IpPort.class, new IpPortKey(internalIpAddress))
737 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
738 return intIpProtocolTypeId;
741 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
742 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
743 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
747 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
748 return InstanceIdentifier.create(NaptSwitches.class);
751 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
752 return InstanceIdentifier.create(NaptSwitches.class)
753 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
756 public static String getGroupIdKey(String routerName) {
757 return "snatmiss." + routerName;
760 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
761 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
762 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
765 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
766 RpcResult<AllocateIdOutput> rpcResult = result.get();
767 return rpcResult.getResult().getIdValue();
768 } catch (NullPointerException | InterruptedException | ExecutionException e) {
774 // TODO Clean up the exception handling
775 @SuppressWarnings("checkstyle:IllegalCatch")
776 public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager,
777 String rd, String prefix, String vpnName, Logger log) {
779 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
780 fibManager.removeFibEntry(broker, rd, prefix, null);
781 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
782 bgpManager.withdrawPrefix(rd, prefix);
784 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
785 } catch (Exception e) {
786 log.error("Delete prefix for rd {} prefix {} vpnName {} failed", rd, prefix, vpnName, e);
790 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
791 return read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
794 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
795 return InstanceIdentifier.builder(IntextIpPortMap.class)
796 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
799 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
800 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
801 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
802 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
803 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
804 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
805 .intext.ip.map.IpMappingKey(routerId)).build();
809 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
810 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
811 .ip.map.IpMapping> ipMappingOptional =
812 read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
813 List<String> externalIps = new ArrayList<>();
814 if (ipMappingOptional.isPresent()) {
815 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
816 for (IpMap ipMap : ipMaps) {
817 externalIps.add(ipMap.getExternalIp());
820 return new ArrayList<>(new HashSet<>(externalIps));
825 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
826 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
827 if (routerData != null) {
828 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
831 return Collections.emptyList();
834 public static HashMap<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
835 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
836 .ip.map.IpMapping> ipMappingOptional =
837 read(dataBroker, LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
838 HashMap<String, Long> externalIpsLabel = new HashMap<>();
839 if (ipMappingOptional.isPresent()) {
840 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
841 for (IpMap ipMap : ipMaps) {
842 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
844 return externalIpsLabel;
849 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
850 String leastLoadedExternalIp = null;
851 InstanceIdentifier<ExternalCounters> id =
852 InstanceIdentifier.builder(ExternalIpsCounter.class)
853 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
854 Optional<ExternalCounters> externalCountersData =
855 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
856 if (externalCountersData.isPresent()) {
857 ExternalCounters externalCounter = externalCountersData.get();
858 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
859 short countOfLstLoadExtIp = 32767;
860 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
861 String curExternalIp = externalIpCounter.getExternalIp();
862 short countOfCurExtIp = externalIpCounter.getCounter();
863 if (countOfCurExtIp < countOfLstLoadExtIp) {
864 countOfLstLoadExtIp = countOfCurExtIp;
865 leastLoadedExternalIp = curExternalIp;
869 return leastLoadedExternalIp;
872 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
873 String subnetIP = getSubnetIp(dataBroker, subnetId);
874 if (subnetIP != null) {
875 return getSubnetIpAndPrefix(subnetIP);
880 public static String[] getSubnetIpAndPrefix(String subnetString) {
881 String[] subnetSplit = subnetString.split("/");
882 String subnetIp = subnetSplit[0];
883 String subnetPrefix = "0";
884 if (subnetSplit.length == 2) {
885 subnetPrefix = subnetSplit[1];
887 return new String[] {subnetIp, subnetPrefix};
890 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
891 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
892 .builder(Subnetmaps.class)
893 .child(Subnetmap.class, new SubnetmapKey(subnetId))
895 Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
896 if (removedSubnet.isPresent()) {
897 Subnetmap subnetMapEntry = removedSubnet.get();
898 return subnetMapEntry.getSubnetIp();
904 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
905 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
906 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
907 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
908 if (leastLoadedExtIpAddrSplit.length == 2) {
909 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
911 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
914 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
915 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
916 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
917 Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
918 List<BigInteger> dpns = new ArrayList<>();
919 if (routerDpnListData.isPresent()) {
920 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
921 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
922 dpns.add(dpnVpnInterface.getDpnId());
929 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
930 long bgpVpnId = NatConstants.INVALID_ID;
931 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
932 if (bgpVpnUuid != null) {
933 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
938 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
939 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
940 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router
941 .interfaces.RouterInterface> optRouterInterface =
942 read(broker, LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName));
943 if (optRouterInterface.isPresent()) {
944 return optRouterInterface.get();
949 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
950 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
951 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
952 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
953 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
954 .RouterInterface.class,
955 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
956 .RouterInterfaceKey(interfaceName)).build();
959 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
960 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
961 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
962 addToNeutronRouterDpnsMap(broker, routerName, interfaceName, dpId, writeOperTxn);
965 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
966 BigInteger dpId , WriteTransaction writeOperTxn) {
968 if (dpId.equals(BigInteger.ZERO)) {
969 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
970 interfaceName, routerName);
974 LOG.debug("NAT Service : Adding the Router {} and DPN {} for the Interface {} in the "
975 + "ODL-L3VPN : NeutronRouterDpn map",
976 routerName, dpId, interfaceName);
977 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
979 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList = read(broker, LogicalDatastoreType
980 .OPERATIONAL, dpnVpnInterfacesListIdentifier);
981 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
982 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
983 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
984 .setInterface(interfaceName).build();
985 if (optionalDpnVpninterfacesList.isPresent()) {
986 LOG.debug("NAT Service : RouterDpnList already present for the Router {} and DPN {} for the "
987 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
988 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
989 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
990 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
991 new RouterInterfacesKey(interfaceName)), routerInterface, true);
993 LOG.debug("NAT Service : Building new RouterDpnList for the Router {} and DPN {} for the "
994 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
995 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
996 routerDpnListBuilder.setRouterId(routerName);
997 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
998 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
999 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
1000 routerInterfaces.add(routerInterface);
1001 dpnVpnList.setRouterInterfaces(routerInterfaces);
1002 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
1003 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1004 getRouterId(routerName),
1005 routerDpnListBuilder.build(), true);
1010 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1011 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1012 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1013 addToDpnRoutersMap(broker, routerName, interfaceName, dpId, writeOperTxn);
1016 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1017 BigInteger dpId, WriteTransaction writeOperTxn) {
1018 if (dpId.equals(BigInteger.ZERO)) {
1019 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} association model",
1020 interfaceName, routerName);
1024 LOG.debug("NAT Service : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1026 dpId, routerName, interfaceName);
1027 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1029 Optional<DpnRoutersList> optionalDpnRoutersList = read(broker, LogicalDatastoreType.OPERATIONAL,
1030 dpnRoutersListIdentifier);
1032 if (optionalDpnRoutersList.isPresent()) {
1033 RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
1034 .setRouter(routerName).build();
1035 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1036 if (!routersListFromDs.contains(routersList)) {
1037 LOG.debug("NAT Service : Router {} not present for the DPN {}"
1038 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1039 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1040 dpnRoutersListIdentifier
1041 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1043 LOG.debug("NAT Service : Router {} already mapped to the DPN {} in the ODL-L3VPN : DPNRouters map",
1047 LOG.debug("NAT Service : Building new DPNRoutersList for the Router {} present in the DPN {} "
1048 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1049 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1050 dpnRoutersListBuilder.setDpnId(dpId);
1051 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1052 routersListBuilder.setRouter(routerName);
1053 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1054 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1055 getDpnRoutersId(dpId),
1056 dpnRoutersListBuilder.build(), true);
1061 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1062 BigInteger dpId, WriteTransaction writeOperTxn) {
1063 if (dpId.equals(BigInteger.ZERO)) {
1064 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1065 interfaceName, routerName);
1068 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1069 Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1070 .OPERATIONAL, routerDpnListIdentifier);
1071 if (optionalRouterDpnList.isPresent()) {
1072 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1073 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1074 optionalRouterDpnList.get().getRouterInterfaces();
1075 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1076 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1077 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1078 .setInterface(interfaceName).build();
1079 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1080 if (routerInterfaces.isEmpty()) {
1081 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1083 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1084 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1085 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1086 new RouterInterfacesKey(interfaceName)));
1092 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1093 BigInteger dpId, WriteTransaction writeOperTxn) {
1094 if (dpId.equals(BigInteger.ZERO)) {
1095 LOG.warn("NAT Service : DPN ID is invalid for the router {} ", routerName);
1099 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1100 Optional<DpnVpninterfacesList> optionalRouterDpnList = NatUtil.read(broker, LogicalDatastoreType
1101 .OPERATIONAL, routerDpnListIdentifier);
1102 if (optionalRouterDpnList.isPresent()) {
1103 LOG.debug("NAT Service : Removing the dpn-vpninterfaces-list from the odl-l3vpn:neutron-router-dpns model "
1104 + "for the router {}", routerName);
1105 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1107 LOG.debug("NAT Service : dpn-vpninterfaces-list does not exist in the odl-l3vpn:neutron-router-dpns model "
1108 + "for the router {}", routerName);
1112 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1113 OdlInterfaceRpcService ifaceMgrRpcService,
1114 WriteTransaction writeOperTxn) {
1115 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1116 if (dpId.equals(BigInteger.ZERO)) {
1117 LOG.warn("NAT Service : Could not retrieve dp id for interface {} to handle router {} dissociation model",
1118 vpnInterfaceName, routerName);
1121 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1122 Optional<DpnVpninterfacesList> optionalRouterDpnList = read(broker, LogicalDatastoreType
1123 .OPERATIONAL, routerDpnListIdentifier);
1124 if (optionalRouterDpnList.isPresent()) {
1125 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1126 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1127 optionalRouterDpnList.get().getRouterInterfaces();
1128 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1129 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1130 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1131 .setInterface(vpnInterfaceName).build();
1133 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1134 if (routerInterfaces.isEmpty()) {
1135 if (writeOperTxn != null) {
1136 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1138 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1141 if (writeOperTxn != null) {
1142 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1143 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1144 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1145 new RouterInterfacesKey(vpnInterfaceName)));
1147 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1148 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1149 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1150 new RouterInterfacesKey(vpnInterfaceName)));
1157 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1158 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1159 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1160 if (dpId.equals(BigInteger.ZERO)) {
1161 LOG.warn("NAT Service : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} "
1162 + "to handle router {} dissociation model",
1163 vpnInterfaceName, routerName);
1166 removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1169 static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1170 BigInteger curDpnId,
1171 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1173 1) Get the DpnRoutersList for the DPN.
1174 2) Get the RoutersList identifier for the DPN and router.
1175 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1176 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1177 then remove RouterList.
1180 LOG.debug("NAT Service : removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1181 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1183 //Get the dpn-routers-list instance for the current DPN.
1184 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1185 Optional<DpnRoutersList> dpnRoutersListData = read(broker, LogicalDatastoreType.OPERATIONAL,
1186 dpnRoutersListIdentifier);
1188 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1189 LOG.debug("NAT Service : dpn-routers-list is not present for DPN {} in the ODL-L3VPN:dpn-routers model",
1194 //Get the routers-list instance for the router on the current DPN only
1195 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1196 Optional<RoutersList> routersListData = read(broker, LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1198 if (routersListData == null || !routersListData.isPresent()) {
1199 LOG.debug("NAT Service : routers-list is not present for the DPN {} in the ODL-L3VPN:dpn-routers model",
1204 LOG.debug("NAT Service : Get the interfaces for the router {} from the NeutronVPN - router-interfaces-map",
1206 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1207 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1208 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1209 .RouterInterfaces> routerInterfacesData = read(broker, LogicalDatastoreType.CONFIGURATION,
1210 routerInterfacesId);
1212 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1213 LOG.debug("NAT Service : Unable to get the routers list for the DPN {}. Possibly all subnets removed"
1214 + " from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1215 curDpnId, routerName, routerName);
1216 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1220 //Get the VM interfaces for the router on the current DPN only.
1221 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1222 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1223 if (vmInterfaces == null) {
1224 LOG.debug("NAT Service : VM interfaces are not present for the router {} in the "
1225 + "NeutronVPN - router-interfaces-map", routerName);
1229 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1230 // then remove RouterList.
1231 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1232 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1233 String vmInterfaceName = vmInterface.getInterfaceId();
1234 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1235 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1236 LOG.debug("NAT Service : DPN ID {} for the removed interface {} is not the same as that of "
1237 + "the DPN ID for the checked interface {} ",
1238 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1241 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1242 LOG.debug("NAT Service : Router {} is present in the DPN {} through the other interface {} "
1243 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1247 LOG.debug("NAT Service : Router {} is present in the DPN {} only through the interface {} "
1248 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1249 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1250 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1253 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1254 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1255 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1256 .rev150602.RouterInterfacesMap.class)
1257 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1258 .interfaces.map.RouterInterfaces.class,
1259 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1260 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1263 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1264 return InstanceIdentifier.builder(DpnRouters.class)
1265 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1266 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1269 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1270 BigInteger nodeId = BigInteger.ZERO;
1272 GetDpidFromInterfaceInput
1274 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1275 Future<RpcResult<GetDpidFromInterfaceOutput>>
1277 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1278 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1279 if (dpIdResult.isSuccessful()) {
1280 nodeId = dpIdResult.getResult().getDpid();
1282 LOG.error("NAT Service : Could not retrieve DPN Id for interface {}", ifName);
1284 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1285 LOG.error("NAT Service : Exception when getting dpn for interface {}", ifName, e);
1290 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1292 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1295 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1296 Long tunnelKey, int pos) {
1297 LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1298 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1299 .setIntfName(ifName);
1300 if (tunnelKey != null) {
1301 egressActionsBuilder.setTunnelKey(tunnelKey);
1304 List<ActionInfo> listActionInfo = new ArrayList<>();
1306 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1307 .getEgressActionsForInterface(egressActionsBuilder.build());
1308 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1309 if (!rpcResult.isSuccessful()) {
1310 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1311 rpcResult.getErrors());
1313 List<Action> actions = rpcResult.getResult().getAction();
1314 for (Action action : actions) {
1315 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1316 actionClass = action.getAction();
1317 if (actionClass instanceof OutputActionCase) {
1318 listActionInfo.add(new ActionOutput(pos++,
1319 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1320 } else if (actionClass instanceof PushVlanActionCase) {
1321 listActionInfo.add(new ActionPushVlan(pos++));
1322 } else if (actionClass instanceof SetFieldCase) {
1323 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1324 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1325 .getVlanId().getValue();
1326 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1328 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1329 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1330 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1331 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1332 NxRegLoad nxRegLoad =
1333 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1334 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1335 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1339 } catch (InterruptedException | ExecutionException e) {
1340 LOG.warn("Exception when egress actions for interface {}", ifName, e);
1342 return listActionInfo;
1345 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1346 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1349 public static List<Port> getNeutronPorts(DataBroker broker) {
1350 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1351 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1352 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1353 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1354 portsOptional = read(broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1356 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1357 LOG.trace("No neutron ports found");
1358 return Collections.EMPTY_LIST;
1361 return portsOptional.get().getPort();
1364 public static Port getNeutronPortForIp(DataBroker broker,
1365 IpAddress targetIP, String deviceType) {
1366 List<Port> ports = getNeutronPorts(
1369 for (Port port : ports) {
1370 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1371 for (FixedIps ip : port.getFixedIps()) {
1372 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1382 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1386 for (FixedIps ip : port.getFixedIps()) {
1387 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1388 return ip.getSubnetId();
1395 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1396 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1397 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1398 return read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1401 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1402 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1403 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1404 Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1405 return optionalNetworkMap.isPresent() ? optionalNetworkMap.get().getSubnetIdList() : null;
1408 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1409 if (subnetId == null) {
1413 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1414 .child(Subnet.class, new SubnetKey(subnetId));
1415 Optional<Subnet> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst);
1416 if (!subnetOpt.isPresent()) {
1420 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1421 if (gatewayIp == null) {
1422 LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1426 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1427 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1429 Optional<VpnPortipToPort> portIpToPortOpt = read(broker, LogicalDatastoreType.CONFIGURATION, portIpInst);
1430 if (portIpToPortOpt.isPresent()) {
1431 return portIpToPortOpt.get().getMacAddress();
1434 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1435 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1437 Optional<LearntVpnVipToPort> learntIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, learntIpInst);
1438 if (learntIpToPortOpt.isPresent()) {
1439 return learntIpToPortOpt.get().getMacAddress();
1442 LOG.error("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1446 public static boolean isIPv6Subnet(String prefix) {
1447 return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1450 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1451 return InstanceIdentifier.builder(DpnRouters.class)
1452 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1455 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1456 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1457 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1458 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1461 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1462 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1463 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1466 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1467 InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1468 Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1469 .CONFIGURATION, id);
1470 if (optFloatingIpIdToPortMapping.isPresent()) {
1471 return optFloatingIpIdToPortMapping.get().getFloatingIpPortMacAddress();
1476 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1477 InstanceIdentifier id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1478 Optional<FloatingIpIdToPortMapping> optFloatingIpIdToPortMapping = read(broker, LogicalDatastoreType
1479 .CONFIGURATION, id);
1480 if (optFloatingIpIdToPortMapping.isPresent()) {
1481 return optFloatingIpIdToPortMapping.get().getFloatingIpPortSubnetId();
1486 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1487 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1488 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1491 static final FutureCallback<Void> DEFAULT_CALLBACK =
1492 new FutureCallback<Void>() {
1494 public void onSuccess(Void result) {
1495 LOG.debug("NAT Service : Success in Datastore operation");
1499 public void onFailure(Throwable error) {
1500 LOG.error("NAT Service : Error in Datastore operation", error);
1506 static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1507 InstanceIdentifier<T> path) {
1508 delete(broker, datastoreType, path, DEFAULT_CALLBACK);
1511 static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
1512 InstanceIdentifier<T> path, FutureCallback<Void> callback) {
1513 WriteTransaction tx = broker.newWriteOnlyTransaction();
1514 tx.delete(datastoreType, path);
1515 Futures.addCallback(tx.submit(), callback);
1518 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1519 InstanceIdentifier<Interface> ifStateId =
1520 buildStateInterfaceId(interfaceName);
1521 Optional<Interface> ifStateOptional = read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
1522 if (ifStateOptional.isPresent()) {
1523 return ifStateOptional.get();
1529 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1530 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1531 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1532 .interfaces.rev140508.InterfacesState.class)
1533 .child(Interface.class,
1534 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1535 .interfaces.state.InterfaceKey(interfaceName));
1536 InstanceIdentifier<Interface> id = idBuilder.build();
1540 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1541 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1542 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, routerIdentifier);
1543 if (routerData.isPresent()) {
1544 return routerData.get();
1549 static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) {
1550 long routerId = NatUtil.getVpnId(dataBroker, routerName);
1551 if (routerId == NatConstants.INVALID_ID) {
1552 LOG.error("NAT Service : createRouterIdsConfigDS - invalid routerId for routerName {}", routerName);
1555 RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1556 .setRouterId(routerId).setRouterName(routerName).build();
1557 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1560 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1561 IdManagerService idManager) {
1562 InetAddress defaultIP = null;
1564 defaultIP = InetAddress.getByName("0.0.0.0");
1565 } catch (UnknownHostException e) {
1566 LOG.error("NAT Service : UnknowHostException in buildDefNATFlowEntityForExternalSubnet. "
1567 + "Failed to build FIB Table Flow for Default Route to NAT.");
1571 List<MatchInfo> matches = new ArrayList<>();
1572 matches.add(MatchEthernetType.IPV4);
1573 //add match for vrfid
1574 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1576 List<InstructionInfo> instructions = new ArrayList<>();
1577 List<ActionInfo> actionsInfo = new ArrayList<>();
1578 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1579 actionsInfo.add(new ActionGroup(groupId));
1580 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1581 instructions.add(new InstructionApplyActions(actionsInfo));
1582 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1583 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1584 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1588 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1589 String routerName = getRouterName(broker, routerId);
1590 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1591 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
1592 if (routerData.isPresent()) {
1593 return routerData.get().getExtGwMacAddress();
1598 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1599 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1600 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1601 .child(Router.class, new RouterKey(routerUuid));
1602 return routerInstanceIdentifier;
1605 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1606 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1607 Optional<Router> neutronRouterData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1608 neutronRouterIdentifier);
1609 if (neutronRouterData.isPresent()) {
1610 return neutronRouterData.get().getName();
1615 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1617 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1618 Optional<RouterPorts> routerPortsData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1619 routerPortsIdentifier);
1620 if (routerPortsData.isPresent()) {
1621 return routerPortsData.get().getPorts();
1626 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1627 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1628 Optional<ExternalNetworks> externalNwData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
1629 externalNwIdentifier);
1630 if (externalNwData.isPresent()) {
1631 for (Networks externalNw : externalNwData.get().getNetworks()) {
1632 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1633 return externalNw.getRouterIds();
1640 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1643 long ipLo = ipToLong(InetAddress.getByName(start));
1644 long ipHi = ipToLong(InetAddress.getByName(end));
1645 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1646 return ipToTest >= ipLo && ipToTest <= ipHi;
1647 } catch (UnknownHostException e) {
1648 LOG.error("NAT Service : isIpInSubnet failed for IP {}. Exception {}", ipAddress, e.getMessage());
1653 public static List<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1654 if (externalIps == null) {
1655 return Collections.emptyList();
1658 Set<Uuid> subnetsSet = externalIps.stream().map(externalIp -> externalIp.getSubnetId())
1659 .collect(Collectors.toSet());
1660 return new ArrayList<>(subnetsSet);
1663 public static List<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1664 if (routerName == null) {
1665 LOG.error("getExternalSubnetIdsForRouter - empty routerName received");
1669 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1670 Optional<Routers> routerData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1671 if (routerData.isPresent()) {
1672 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1674 LOG.warn("No external router data for router {}", routerName);
1675 return Collections.emptyList();
1679 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1680 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1681 if (subnetId == null) {
1682 LOG.warn("getOptionalExternalSubnets - null subnetId");
1686 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1687 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1688 InstanceIdentifier.builder(ExternalSubnets.class)
1689 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1690 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1691 return read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1694 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1695 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1696 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1698 if (optionalExternalSubnets.isPresent()) {
1699 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1702 return NatConstants.INVALID_ID;
1705 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1707 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(dataBroker, externalIpAddress, router);
1708 if (externalSubnetId != null) {
1709 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1712 return NatConstants.INVALID_ID;
1715 protected static Uuid getExternalSubnetForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1717 List<ExternalIps> externalIps = router.getExternalIps();
1718 for (ExternalIps extIp : externalIps) {
1719 String extIpString = extIp.getIpAddress().contains("/32") ? extIp.getIpAddress() + "/32" :
1720 extIp.getIpAddress();
1721 if (extIpString.equals(externalIpAddress)) {
1722 return extIp.getSubnetId();
1729 private static long ipToLong(InetAddress ip) {
1730 byte[] octets = ip.getAddress();
1732 for (byte octet : octets) {
1734 result |= octet & 0xff;
1739 static List<String> getIpsListFromExternalIps(List<ExternalIps> externalIps) {
1740 if (externalIps == null) {
1741 return Collections.emptyList();
1744 return externalIps.stream().map(externalIp -> externalIp.getIpAddress()).collect(Collectors.toList());
1747 // elan-instances config container
1748 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1749 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1750 return read(broker, LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1753 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1754 return InstanceIdentifier.builder(ElanInstances.class)
1755 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1758 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1759 IdManagerService idManager, long routerId, String routerName) {
1760 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1761 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1762 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1764 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1768 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1770 LOG.debug("NAT Service : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1771 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1773 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1774 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1775 List<MatchInfo> matches = new ArrayList<>();
1776 matches.add(MatchEthernetType.IPV4);
1777 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1778 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1779 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1780 matches, preDnatToSnatInstructions);
1782 mdsalManager.installFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1783 LOG.debug("NAT Service : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1784 preDnatToSnatTableFlowEntity, naptDpnId);
1787 public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId) {
1788 LOG.debug("NAT Service : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1789 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1790 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1791 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1792 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null);
1793 mdsalManager.removeFlow(naptDpnId, preDnatToSnatTableFlowEntity);
1794 LOG.debug("NAT Service : Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1795 preDnatToSnatTableFlowEntity, naptDpnId);
1798 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1799 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1800 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1803 public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1804 String vpnName, String externalIp,
1805 Boolean isMoreThanOneFipCheckOnDpn) {
1806 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1807 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1808 if (dpnInVpn.isPresent()) {
1809 LOG.debug("vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, rd {} and floatingIp {}",
1810 vpnName, dpnId, rd, externalIp);
1811 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1812 if (ipAddressList.size() > 0) {
1813 int floatingIpPresentCount = 0;
1814 for (IpAddresses ipAddress: ipAddressList) {
1815 if (!ipAddress.getIpAddress().equals(externalIp)
1816 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1817 floatingIpPresentCount++;
1818 //Add tunnel table check
1819 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1820 return Boolean.TRUE;
1822 //Remove tunnel table check
1823 if (!isMoreThanOneFipCheckOnDpn) {
1824 return Boolean.TRUE;
1829 LOG.debug("vpn-to-dpn-list does not contain any floating IP for DPN {}", dpnId);
1830 return Boolean.FALSE;
1833 return Boolean.FALSE;
1836 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1837 return InstanceIdentifier.builder(VpnInstanceOpData.class)
1838 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1839 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1842 public static void createOrUpdateVpnToDpnList(DataBroker dataBroker, long vpnId, BigInteger dpnId, String intfName,
1844 String primaryRd = getPrimaryRd(dataBroker, vpnName);
1845 Boolean newDpnOnVpn = Boolean.FALSE;
1847 synchronized (vpnName.intern()) {
1848 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
1849 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(primaryRd, dpnId);
1850 Optional<VpnToDpnList> dpnInVpn = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1851 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance
1852 .op.data.entry.vpn.to.dpn.list.VpnInterfaces vpnInterface = new VpnInterfacesBuilder()
1853 .setInterfaceName(intfName).build();
1855 if (dpnInVpn.isPresent()) {
1856 VpnToDpnList vpnToDpnList = dpnInVpn.get();
1857 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1858 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = vpnToDpnList
1859 .getVpnInterfaces();
1860 if (vpnInterfaces == null) {
1861 vpnInterfaces = new ArrayList<>();
1863 vpnInterfaces.add(vpnInterface);
1864 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder(vpnToDpnList);
1865 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
1867 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
1868 /* If earlier state was inactive, it is considered new DPN coming back to the
1871 if (vpnToDpnList.getDpnState() == VpnToDpnList.DpnState.Inactive) {
1872 newDpnOnVpn = Boolean.TRUE;
1875 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1876 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces>
1877 vpnInterfaces = new ArrayList<>();
1878 vpnInterfaces.add(vpnInterface);
1879 VpnToDpnListBuilder vpnToDpnListBuilder = new VpnToDpnListBuilder().setDpnId(dpnId);
1880 vpnToDpnListBuilder.setDpnState(VpnToDpnList.DpnState.Active).setVpnInterfaces(vpnInterfaces);
1882 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, vpnToDpnListBuilder.build(), true);
1883 newDpnOnVpn = Boolean.TRUE;
1888 public static void removeOrUpdateVpnToDpnList(DataBroker dataBroker, long vpnId, BigInteger dpnId, String intfName,
1890 Boolean lastDpnOnVpn = Boolean.FALSE;
1891 String rd = getVpnRd(dataBroker, vpnName);
1892 synchronized (vpnName.intern()) {
1893 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1894 VpnToDpnList dpnInVpn = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id).orNull();
1895 if (dpnInVpn == null) {
1896 LOG.error("removeOrUpdateVpnToDpnList: Could not find DpnToVpn map for VPN=[name={} rd={} id={}]"
1897 + " and dpnId={}", vpnName, rd, id, dpnId);
1900 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1901 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces> vpnInterfaces = dpnInVpn.getVpnInterfaces();
1902 if (vpnInterfaces == null) {
1903 LOG.error("Could not find vpnInterfaces for DpnInVpn map for VPN=[name={} rd={} id={}] and dpnId={}",
1904 vpnName, rd, id, dpnId);
1908 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
1909 .instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces currVpnInterface = new VpnInterfacesBuilder()
1910 .setInterfaceName(intfName).build();
1911 if (vpnInterfaces.remove(currVpnInterface)) {
1912 WriteTransaction writeTxn = dataBroker.newWriteOnlyTransaction();
1913 if (vpnInterfaces.isEmpty()) {
1914 List<IpAddresses> ipAddresses = dpnInVpn.getIpAddresses();
1915 VpnToDpnListBuilder dpnInVpnBuilder = new VpnToDpnListBuilder(dpnInVpn).setVpnInterfaces(null);
1916 if (ipAddresses == null || ipAddresses.isEmpty()) {
1917 dpnInVpnBuilder.setDpnState(VpnToDpnList.DpnState.Inactive);
1918 lastDpnOnVpn = Boolean.TRUE;
1920 LOG.warn("vpn interfaces are empty but ip addresses are present for the vpn {} in dpn {}",
1923 writeTxn.put(LogicalDatastoreType.OPERATIONAL, id, dpnInVpnBuilder.build(), true);
1926 writeTxn.delete(LogicalDatastoreType.OPERATIONAL, id.child(org.opendaylight.yang.gen.v1.urn
1927 .opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry
1928 .vpn.to.dpn.list.VpnInterfaces.class, new VpnInterfacesKey(intfName)));
1931 } // Ends synchronized block
1933 /* if (lastDpnOnVpn) {
1934 LOG.debug("Sending cleanup event for dpn {} in VPN {}", dpnId, vpnName);
1935 fibManager.cleanUpDpnForVpn(dpnId, vpnId, rd, new DpnEnterExitVpnWorker(dpnId, vpnName, rd,
1940 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
1941 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1942 Optional<VpnInstance> vpnInstance = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
1943 if (vpnInstance.isPresent()) {
1944 return getPrimaryRd(vpnInstance.get());
1949 public static String getPrimaryRd(VpnInstance vpnInstance) {
1950 List<String> rds = null;
1951 if (vpnInstance != null) {
1952 rds = getListOfRdsFromVpnInstance(vpnInstance);
1954 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
1957 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
1958 return InstanceIdentifier.builder(VpnInstances.class)
1959 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
1962 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
1963 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
1964 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
1965 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();