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.CheckedFuture;
13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
14 import java.math.BigInteger;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
24 import java.util.Objects;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.Future;
27 import java.util.stream.Collectors;
28 import javax.annotation.Nonnull;
29 import javax.annotation.Nullable;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
34 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
35 import org.opendaylight.genius.mdsalutil.ActionInfo;
36 import org.opendaylight.genius.mdsalutil.FlowEntity;
37 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
38 import org.opendaylight.genius.mdsalutil.InstructionInfo;
39 import org.opendaylight.genius.mdsalutil.MDSALUtil;
40 import org.opendaylight.genius.mdsalutil.MatchInfo;
41 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
42 import org.opendaylight.genius.mdsalutil.NwConstants;
43 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
44 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
45 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
46 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
47 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
48 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
49 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
50 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
51 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
52 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
53 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
54 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
55 import org.opendaylight.netvirt.elanmanager.api.IElanService;
56 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
57 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
58 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
59 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
60 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
61 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
62 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
63 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
64 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
65 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
66 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
67 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntryKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
170 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;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
206 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;
207 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
208 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
209 import org.opendaylight.yangtools.yang.common.RpcResult;
210 import org.slf4j.Logger;
211 import org.slf4j.LoggerFactory;
213 public final class NatUtil {
215 private static String OF_URI_SEPARATOR = ":";
216 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
218 private NatUtil() { }
221 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
224 public static BigInteger getCookieSnatFlow(long routerId) {
225 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
226 BigInteger.valueOf(routerId));
230 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
233 public static BigInteger getCookieNaptFlow(long routerId) {
234 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
235 BigInteger.valueOf(routerId));
239 getVpnId() returns the VPN ID from the VPN name
241 public static long getVpnId(DataBroker broker, String vpnName) {
242 if (vpnName == null) {
243 return NatConstants.INVALID_ID;
246 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
247 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
248 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
249 .instance.to.vpn.id.VpnInstance> vpnInstance =
250 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
251 LogicalDatastoreType.CONFIGURATION, id);
253 long vpnId = NatConstants.INVALID_ID;
254 if (vpnInstance.isPresent()) {
255 Long vpnIdAsLong = vpnInstance.get().getVpnId();
256 if (vpnIdAsLong != null) {
263 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
264 //Get the external network ID from the ExternalRouter model
265 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
266 if (networkId == null) {
267 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
268 return NatConstants.INVALID_ID;
271 //Get the VPN ID from the ExternalNetworks model
272 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
273 if (vpnUuid == null) {
274 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
275 return NatConstants.INVALID_ID;
277 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
281 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
282 return InstanceIdentifier.builder(FloatingIpInfo.class)
283 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
286 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
287 return InstanceIdentifier.builder(RouterToVpnMapping.class)
288 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
291 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
292 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
293 .child(Ports.class, new PortsKey(portName)).build();
296 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
298 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
299 .child(Ports.class, new PortsKey(portName))
300 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
303 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
304 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
305 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
306 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
307 .instance.to.vpn.id.VpnInstance.class,
308 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
309 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
312 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
313 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
314 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
315 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
316 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
320 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
322 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
323 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
324 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
327 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
328 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
329 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
332 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
333 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
334 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
338 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
339 String routerName = getRouterName(broker, routerId);
340 if (routerName == null) {
341 LOG.error("getNetworkIdFromRouterId - empty routerName received");
344 return getNetworkIdFromRouterName(broker, routerName);
347 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
348 if (routerName == null) {
349 LOG.error("getNetworkIdFromRouterName - empty routerName received");
352 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
353 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
354 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
357 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
358 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
359 .child(Routers.class, new RoutersKey(routerId)).build();
360 return routerInstanceIndentifier;
363 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
364 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
365 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
370 * Return if SNAT is enabled for the given router.
372 * @param broker The DataBroker
373 * @param routerId The router
374 * @return boolean true if enabled, otherwise false
376 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
377 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
378 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
379 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
382 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
383 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
384 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
385 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
388 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
389 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
390 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
391 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
395 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
396 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
397 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
398 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse(
399 Collections.emptyList());
402 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
403 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
404 Optional<Routers> routerData =
405 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
406 LogicalDatastoreType.CONFIGURATION, id);
407 if (routerData.isPresent()) {
408 Uuid networkId = routerData.get().getNetworkId();
409 if (networkId != null) {
410 return networkId.getValue();
413 LOG.info("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
417 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
418 return InstanceIdentifier.builder(ExternalNetworks.class)
419 .child(Networks.class, new NetworksKey(networkId)).build();
422 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
423 // convert routerId to Name
424 String routerName = getRouterName(broker, routerId);
425 if (routerName == null) {
426 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
429 return getPrimaryNaptfromRouterName(broker, routerName);
432 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
433 if (routerName == null) {
434 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
437 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
438 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
439 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
443 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
444 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
445 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
449 public static String getRouterName(DataBroker broker, Long routerId) {
450 InstanceIdentifier<RouterIds> id = buildRouterIdentifier(routerId);
451 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
452 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterIds::getRouterName).orElse(null);
455 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
456 return InstanceIdentifier.builder(VpnInstanceOpData.class)
457 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
460 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
461 return new FlowEntityBuilder()
469 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
470 return new FlowEntityBuilder()
477 public static long getIpAddress(byte[] rawIpAddress) {
478 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
479 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
482 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
483 String nextHopIp = null;
484 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
485 InstanceIdentifier.builder(DpnEndpoints.class)
486 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
487 Optional<DPNTEPsInfo> tunnelInfo =
488 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
489 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
490 if (tunnelInfo.isPresent()) {
491 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
492 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
493 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
499 public static String getVpnRd(DataBroker broker, String vpnName) {
501 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
502 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
503 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
504 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
505 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
506 .VpnInstance::getVrfId).orElse(null);
509 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
510 String internalPort, NAPTEntryEvent.Protocol protocol) {
511 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
512 InstanceIdentifier<IpPortMap> ipPortMapId =
513 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
514 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
515 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
519 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
521 ProtocolTypes protocolType) {
522 return InstanceIdentifier.builder(IntextIpPortMap.class)
523 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
524 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
525 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
528 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
529 return InstanceIdentifier.builder(VpnInterfaces.class)
530 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
533 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
534 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
535 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
536 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
539 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
541 * NodeConnectorId is of form 'openflow:dpnid:portnum'
543 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
544 if (split.length != 3) {
545 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
551 public static BigInteger getDpIdFromInterface(
552 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
553 .state.Interface ifState) {
554 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
555 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
556 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
559 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
560 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
561 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
562 Optional<VpnMap> optionalVpnMap =
563 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
564 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
565 if (optionalVpnMap.isPresent()) {
566 Uuid routerId = optionalVpnMap.get().getRouterId();
567 if (routerId != null) {
568 return routerId.getValue();
571 LOG.info("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
575 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
576 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
577 Optional<VpnMaps> optionalVpnMaps =
578 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
579 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
580 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
581 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
582 if (routerId != null) {
583 for (VpnMap vpnMap : allMaps) {
584 if (vpnMap.getRouterId() != null
585 && routerId.equals(vpnMap.getRouterId().getValue())
586 && !routerId.equals(vpnMap.getVpnId().getValue())) {
587 return vpnMap.getVpnId();
592 LOG.debug("getVpnForRouter : VPN not found for routerID:{}", routerId);
596 static long getAssociatedVpn(DataBroker broker, String routerName) {
597 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
598 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
599 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
600 NatConstants.INVALID_ID);
603 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId) {
604 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
605 if (vpnUuid == null) {
606 LOG.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
609 return vpnUuid.getValue();
612 // TODO Clean up the exception handling
613 @SuppressWarnings("checkstyle:IllegalCatch")
614 public static void addPrefixToBGP(DataBroker broker,
615 IBgpManager bgpManager,
616 IFibManager fibManager,
629 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
630 prefix, nextHopIp, label);
631 if (nextHopIp == null) {
632 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
637 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId,
638 subnetId, Prefixes.PrefixCue.Nat);
639 fibManager.addOrUpdateFibEntry(rd, macAddress, prefix,
640 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
641 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
642 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
643 /* Publish to Bgp only if its an INTERNET VPN */
644 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
645 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
646 null /*gatewayMac*/);
648 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
649 prefix, nextHopIp, label);
650 } catch (Exception e) {
651 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
652 prefix, nextHopIp, label, e);
656 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
657 BigInteger dpId, Uuid subnetId, Prefixes.PrefixCue prefixCue) {
658 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
659 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
660 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
661 .to._interface.VpnIdsKey(vpnId))
662 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
663 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
664 prefixBuilder.setVpnInterfaceName(interfaceName).setSubnetId(subnetId).setPrefixCue(prefixCue);
666 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
667 prefixBuilder.build());
668 } catch (TransactionCommitFailedException e) {
669 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
670 ipPrefix, vpnId, dpId, e);
674 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
675 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
676 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
680 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
681 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
682 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
683 return routerInstanceIndentifier;
687 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
688 String internalIpAddress, ProtocolTypes protocolType) {
689 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
690 LogicalDatastoreType.CONFIGURATION,
691 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
692 IntIpProtoType::getPorts).orElse(Collections.emptyList());
695 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
696 String internalIpAddress,
697 ProtocolTypes protocolType) {
698 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
699 InstanceIdentifier.builder(SnatintIpPortMap.class)
700 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
701 .child(IpPort.class, new IpPortKey(internalIpAddress))
702 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
703 return intIpProtocolTypeId;
706 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
707 String internalIpAddress) {
708 InstanceIdentifier<IpPort> intIpProtocolTypeId =
709 InstanceIdentifier.builder(SnatintIpPortMap.class)
710 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
711 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
712 return intIpProtocolTypeId;
716 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
717 String internalIpAddress) {
718 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
719 LogicalDatastoreType.CONFIGURATION,
720 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
723 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
724 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
725 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
729 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
730 return InstanceIdentifier.create(NaptSwitches.class);
733 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
734 return InstanceIdentifier.create(NaptSwitches.class)
735 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
738 public static String getGroupIdKey(String routerName) {
739 return "snatmiss." + routerName;
742 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
743 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
744 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
747 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
748 RpcResult<AllocateIdOutput> rpcResult = result.get();
749 return rpcResult.getResult().getIdValue();
750 } catch (NullPointerException | InterruptedException | ExecutionException e) {
751 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
756 // TODO Clean up the exception handling
757 @SuppressWarnings("checkstyle:IllegalCatch")
758 public static void removePrefixFromBGP(IBgpManager bgpManager, IFibManager fibManager,
759 String rd, String prefix, String vpnName, Logger log) {
761 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
762 fibManager.removeFibEntry(rd, prefix, null);
763 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
764 bgpManager.withdrawPrefix(rd, prefix);
766 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
767 } catch (Exception e) {
768 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
769 rd, prefix, vpnName, e);
773 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
774 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
775 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
778 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
779 return InstanceIdentifier.builder(IntextIpPortMap.class)
780 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
783 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
784 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
785 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
786 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
787 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
788 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
789 .intext.ip.map.IpMappingKey(routerId)).build();
794 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
795 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
796 .ip.map.IpMapping> ipMappingOptional =
797 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
798 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
799 // Ensure there are no duplicates
800 Collection<String> externalIps = new HashSet<>();
801 if (ipMappingOptional.isPresent()) {
802 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
803 for (IpMap ipMap : ipMaps) {
804 externalIps.add(ipMap.getExternalIp());
811 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
812 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
813 if (routerData != null) {
814 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
817 return Collections.emptyList();
821 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
822 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
823 .ip.map.IpMapping> ipMappingOptional =
824 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
825 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
826 Map<String, Long> externalIpsLabel = new HashMap<>();
827 if (ipMappingOptional.isPresent()) {
828 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
829 for (IpMap ipMap : ipMaps) {
830 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
833 return externalIpsLabel;
836 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
837 String leastLoadedExternalIp = null;
838 InstanceIdentifier<ExternalCounters> id =
839 InstanceIdentifier.builder(ExternalIpsCounter.class)
840 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
841 Optional<ExternalCounters> externalCountersData =
842 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
843 if (externalCountersData.isPresent()) {
844 ExternalCounters externalCounter = externalCountersData.get();
845 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
846 short countOfLstLoadExtIp = 32767;
847 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
848 String curExternalIp = externalIpCounter.getExternalIp();
849 short countOfCurExtIp = externalIpCounter.getCounter();
850 if (countOfCurExtIp < countOfLstLoadExtIp) {
851 countOfLstLoadExtIp = countOfCurExtIp;
852 leastLoadedExternalIp = curExternalIp;
856 return leastLoadedExternalIp;
859 @SuppressFBWarnings("PZLA_PREFER_ZERO_LENGTH_ARRAYS")
860 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
861 String subnetIP = getSubnetIp(dataBroker, subnetId);
862 if (subnetIP != null) {
863 return getSubnetIpAndPrefix(subnetIP);
865 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
869 public static String[] getSubnetIpAndPrefix(String subnetString) {
870 String[] subnetSplit = subnetString.split("/");
871 String subnetIp = subnetSplit[0];
872 String subnetPrefix = "0";
873 if (subnetSplit.length == 2) {
874 subnetPrefix = subnetSplit[1];
876 return new String[] {subnetIp, subnetPrefix};
879 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
880 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
881 .builder(Subnetmaps.class)
882 .child(Subnetmap.class, new SubnetmapKey(subnetId))
884 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
885 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
889 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
890 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
891 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
892 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
893 if (leastLoadedExtIpAddrSplit.length == 2) {
894 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
896 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
900 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
901 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
902 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
903 Optional<RouterDpnList> routerDpnListData =
904 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
905 LogicalDatastoreType.OPERATIONAL, id);
906 List<BigInteger> dpns = new ArrayList<>();
907 if (routerDpnListData.isPresent()) {
908 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
909 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
910 dpns.add(dpnVpnInterface.getDpnId());
916 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
917 long bgpVpnId = NatConstants.INVALID_ID;
918 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
919 if (bgpVpnUuid != null) {
920 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
925 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
926 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
927 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
928 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
931 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
932 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
933 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
934 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
935 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
936 .RouterInterface.class,
937 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
938 .RouterInterfaceKey(interfaceName)).build();
941 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
942 BigInteger dpId , WriteTransaction writeOperTxn) {
944 if (dpId.equals(BigInteger.ZERO)) {
945 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
946 + "to handle router {} association model", interfaceName, routerName);
950 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
951 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
952 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
954 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList =
955 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
956 LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier);
957 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
958 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
959 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
960 .setInterface(interfaceName).build();
961 if (optionalDpnVpninterfacesList.isPresent()) {
962 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
963 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
964 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
965 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
966 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
967 new RouterInterfacesKey(interfaceName)), routerInterface, true);
969 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
970 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
971 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
972 routerDpnListBuilder.setRouterId(routerName);
973 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
974 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
975 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
976 routerInterfaces.add(routerInterface);
977 dpnVpnList.setRouterInterfaces(routerInterfaces);
978 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
979 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
980 getRouterId(routerName),
981 routerDpnListBuilder.build(), true);
985 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
986 BigInteger dpId, WriteTransaction writeOperTxn) {
987 if (dpId.equals(BigInteger.ZERO)) {
988 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
989 + "association model", interfaceName, routerName);
993 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
994 + "DPNRouters map", dpId, routerName, interfaceName);
995 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
997 Optional<DpnRoutersList> optionalDpnRoutersList =
998 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
999 LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1001 if (optionalDpnRoutersList.isPresent()) {
1002 RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
1003 .setRouter(routerName).build();
1004 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1005 if (!routersListFromDs.contains(routersList)) {
1006 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1007 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1008 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1009 dpnRoutersListIdentifier
1010 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1012 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1013 + "DPNRouters map", routerName, dpId);
1016 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1017 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1018 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1019 dpnRoutersListBuilder.setDpnId(dpId);
1020 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1021 routersListBuilder.setRouter(routerName);
1022 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1023 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1024 getDpnRoutersId(dpId),
1025 dpnRoutersListBuilder.build(), true);
1030 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1031 BigInteger dpId, WriteTransaction writeOperTxn) {
1032 if (dpId.equals(BigInteger.ZERO)) {
1033 LOG.error("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {} "
1034 + "dissociation model", interfaceName, routerName);
1037 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1038 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1039 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1040 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1041 if (optionalRouterDpnList.isPresent()) {
1042 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1043 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1044 optionalRouterDpnList.get().getRouterInterfaces();
1045 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1046 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1047 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1048 .setInterface(interfaceName).build();
1049 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1050 if (routerInterfaces.isEmpty()) {
1051 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1053 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1054 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1055 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1056 new RouterInterfacesKey(interfaceName)));
1062 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1063 BigInteger dpId, WriteTransaction writeOperTxn) {
1064 if (dpId.equals(BigInteger.ZERO)) {
1065 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", routerName);
1069 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1070 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1071 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1072 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1073 if (optionalRouterDpnList.isPresent()) {
1074 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1075 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1076 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1078 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1079 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1083 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1084 OdlInterfaceRpcService ifaceMgrRpcService,
1085 WriteTransaction writeOperTxn) {
1086 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1087 if (dpId.equals(BigInteger.ZERO)) {
1088 LOG.debug("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {}"
1089 + " dissociation model", vpnInterfaceName, routerName);
1092 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1093 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1094 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1095 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1096 if (optionalRouterDpnList.isPresent()) {
1097 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1098 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1099 optionalRouterDpnList.get().getRouterInterfaces();
1100 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1101 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1102 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1103 .setInterface(vpnInterfaceName).build();
1105 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1106 if (routerInterfaces.isEmpty()) {
1107 if (writeOperTxn != null) {
1108 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1110 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1113 if (writeOperTxn != null) {
1114 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1115 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1116 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1117 new RouterInterfacesKey(vpnInterfaceName)));
1119 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1120 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1121 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1122 new RouterInterfacesKey(vpnInterfaceName)));
1129 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1130 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1131 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1132 if (dpId.equals(BigInteger.ZERO)) {
1133 LOG.debug("removeFromDpnRoutersMap : removeFromDpnRoutersMap() : "
1134 + "Could not retrieve DPN ID for interface {} to handle router {} dissociation model",
1135 vpnInterfaceName, routerName);
1138 removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1141 static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1142 BigInteger curDpnId,
1143 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1145 1) Get the DpnRoutersList for the DPN.
1146 2) Get the RoutersList identifier for the DPN and router.
1147 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1148 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1149 then remove RouterList.
1152 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1153 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1155 //Get the dpn-routers-list instance for the current DPN.
1156 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1157 Optional<DpnRoutersList> dpnRoutersListData =
1158 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1159 LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1161 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1162 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1163 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1167 //Get the routers-list instance for the router on the current DPN only
1168 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1169 Optional<RoutersList> routersListData =
1170 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1171 LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1173 if (routersListData == null || !routersListData.isPresent()) {
1174 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1175 + "in the ODL-L3VPN:dpn-routers model",
1180 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1181 + "from the NeutronVPN - router-interfaces-map", routerName);
1182 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1183 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1184 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1185 .RouterInterfaces> routerInterfacesData =
1186 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1187 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1189 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1190 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1191 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1192 curDpnId, routerName, routerName);
1193 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1197 //Get the VM interfaces for the router on the current DPN only.
1198 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1199 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1200 if (vmInterfaces == null) {
1201 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1202 + "NeutronVPN - router-interfaces-map", routerName);
1206 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1207 // then remove RouterList.
1208 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1209 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1210 String vmInterfaceName = vmInterface.getInterfaceId();
1211 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1212 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1213 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1214 + "the DPN ID {} for the checked interface {}",
1215 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1218 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1219 LOG.info("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1220 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1224 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1225 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1226 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1227 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1230 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1231 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1232 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1233 .rev150602.RouterInterfacesMap.class)
1234 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1235 .interfaces.map.RouterInterfaces.class,
1236 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1237 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1240 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1241 return InstanceIdentifier.builder(DpnRouters.class)
1242 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1243 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1246 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1247 BigInteger nodeId = BigInteger.ZERO;
1249 GetDpidFromInterfaceInput
1251 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1252 Future<RpcResult<GetDpidFromInterfaceOutput>>
1254 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1255 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1256 if (dpIdResult.isSuccessful()) {
1257 nodeId = dpIdResult.getResult().getDpid();
1259 LOG.debug("removeFromDpnRoutersMap : Could not retrieve DPN Id for interface {}", ifName);
1261 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1262 LOG.error("removeFromDpnRoutersMap : Exception when getting dpn for interface {}", ifName, e);
1268 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1270 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1274 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1275 Long tunnelKey, int pos) {
1276 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1277 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1278 .setIntfName(ifName);
1279 if (tunnelKey != null) {
1280 egressActionsBuilder.setTunnelKey(tunnelKey);
1283 List<ActionInfo> listActionInfo = new ArrayList<>();
1285 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1286 .getEgressActionsForInterface(egressActionsBuilder.build());
1287 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1288 if (!rpcResult.isSuccessful()) {
1289 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1290 + "returned with Errors {}", ifName, rpcResult.getErrors());
1292 List<Action> actions = rpcResult.getResult().getAction();
1293 for (Action action : actions) {
1294 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1295 actionClass = action.getAction();
1296 if (actionClass instanceof OutputActionCase) {
1297 listActionInfo.add(new ActionOutput(pos++,
1298 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1299 } else if (actionClass instanceof PushVlanActionCase) {
1300 listActionInfo.add(new ActionPushVlan(pos++));
1301 } else if (actionClass instanceof SetFieldCase) {
1302 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1303 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1304 .getVlanId().getValue();
1305 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1307 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1308 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1309 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1310 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1311 NxRegLoad nxRegLoad =
1312 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1313 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1314 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1318 } catch (InterruptedException | ExecutionException e) {
1319 LOG.error("Exception when egress actions for interface {}", ifName, e);
1321 return listActionInfo;
1324 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1325 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1329 public static List<Port> getNeutronPorts(DataBroker broker) {
1330 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1331 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1332 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1333 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1335 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1336 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1338 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1339 LOG.error("getNeutronPorts : No neutron ports found");
1340 return Collections.emptyList();
1343 return portsOptional.get().getPort();
1346 public static Port getNeutronPortForIp(DataBroker broker,
1347 IpAddress targetIP, String deviceType) {
1348 List<Port> ports = getNeutronPorts(
1351 for (Port port : ports) {
1352 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1353 for (FixedIps ip : port.getFixedIps()) {
1354 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1360 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1364 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1366 LOG.error("getSubnetIdForFloatingIp : port is null");
1369 for (FixedIps ip : port.getFixedIps()) {
1370 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1371 return ip.getSubnetId();
1374 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1378 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1379 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1380 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1381 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1382 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1386 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1387 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1388 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1389 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1390 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1391 Collections.emptyList());
1394 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1395 if (subnetId == null) {
1396 LOG.error("getSubnetGwMac : subnetID is null");
1400 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1401 .child(Subnet.class, new SubnetKey(subnetId));
1402 Optional<Subnet> subnetOpt =
1403 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1404 LogicalDatastoreType.CONFIGURATION, subnetInst);
1405 if (!subnetOpt.isPresent()) {
1406 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1410 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1411 if (gatewayIp == null) {
1412 LOG.warn("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1416 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1417 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1419 Optional<VpnPortipToPort> portIpToPortOpt =
1420 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1421 LogicalDatastoreType.CONFIGURATION, portIpInst);
1422 if (portIpToPortOpt.isPresent()) {
1423 return portIpToPortOpt.get().getMacAddress();
1426 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1427 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1429 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1430 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1431 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1432 if (learntIpToPortOpt.isPresent()) {
1433 return learntIpToPortOpt.get().getMacAddress();
1436 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1440 public static boolean isIPv6Subnet(String prefix) {
1441 return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1444 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1445 return InstanceIdentifier.builder(DpnRouters.class)
1446 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1449 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1450 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1451 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1452 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1455 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1456 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1457 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1460 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1461 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1462 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1463 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1464 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1467 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1468 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1469 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1470 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1471 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1474 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1475 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1476 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1479 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1480 InstanceIdentifier<Interface> ifStateId =
1481 buildStateInterfaceId(interfaceName);
1482 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1483 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1486 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1487 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1488 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1489 .interfaces.rev140508.InterfacesState.class)
1490 .child(Interface.class,
1491 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1492 .interfaces.state.InterfaceKey(interfaceName));
1493 InstanceIdentifier<Interface> id = idBuilder.build();
1497 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1498 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1499 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1500 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1503 static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
1504 if (routerId == NatConstants.INVALID_ID) {
1505 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1508 RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1509 .setRouterId(routerId).setRouterName(routerName).build();
1510 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1513 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1514 IdManagerService idManager) {
1515 InetAddress defaultIP = null;
1517 defaultIP = InetAddress.getByName("0.0.0.0");
1518 } catch (UnknownHostException e) {
1519 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1520 + "Default Route to NAT.", e);
1524 List<MatchInfo> matches = new ArrayList<>();
1525 matches.add(MatchEthernetType.IPV4);
1526 //add match for vrfid
1527 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1529 List<InstructionInfo> instructions = new ArrayList<>();
1530 List<ActionInfo> actionsInfo = new ArrayList<>();
1531 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1532 actionsInfo.add(new ActionGroup(groupId));
1533 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1534 instructions.add(new InstructionApplyActions(actionsInfo));
1535 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1536 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1537 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1541 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1542 String routerName = getRouterName(broker, routerId);
1543 if (routerName == null) {
1544 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1547 return getExtGwMacAddFromRouterName(broker, routerName);
1550 static String getExtGwMacAddFromRouterName(DataBroker broker, String routerName) {
1551 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1552 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1553 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1557 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1558 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1559 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1560 .child(Router.class, new RouterKey(routerUuid));
1561 return routerInstanceIdentifier;
1564 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1565 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1566 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1567 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1572 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1573 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1574 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1575 LogicalDatastoreType.CONFIGURATION,
1576 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(Collections.emptyList());
1580 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1581 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1582 Optional<ExternalNetworks> externalNwData =
1583 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1584 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1585 if (externalNwData.isPresent()) {
1586 for (Networks externalNw : externalNwData.get().getNetworks()) {
1587 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1588 return externalNw.getRouterIds();
1592 return Collections.emptyList();
1595 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1598 long ipLo = ipToLong(InetAddress.getByName(start));
1599 long ipHi = ipToLong(InetAddress.getByName(end));
1600 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1601 return ipToTest >= ipLo && ipToTest <= ipHi;
1602 } catch (UnknownHostException e) {
1603 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1609 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1610 if (externalIps == null) {
1611 return Collections.emptySet();
1614 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1618 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1619 if (routerName == null) {
1620 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1621 return Collections.emptySet();
1624 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1625 Optional<Routers> routerData =
1626 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1627 LogicalDatastoreType.CONFIGURATION, id);
1628 if (routerData.isPresent()) {
1629 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1631 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1632 return Collections.emptySet();
1637 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1638 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1639 if (subnetId == null) {
1640 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1641 return Optional.absent();
1644 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1645 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1646 InstanceIdentifier.builder(ExternalSubnets.class)
1647 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1648 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1649 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1650 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1653 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1654 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1655 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1657 if (optionalExternalSubnets.isPresent()) {
1658 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1661 return NatConstants.INVALID_ID;
1664 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1666 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
1667 if (externalSubnetId != null) {
1668 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1671 return NatConstants.INVALID_ID;
1674 protected static Uuid getExternalSubnetForRouterExternalIp(String externalIpAddress, Routers router) {
1675 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1676 List<ExternalIps> externalIps = router.getExternalIps();
1677 for (ExternalIps extIp : externalIps) {
1678 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1679 if (extIpString.equals(externalIpAddress)) {
1680 return extIp.getSubnetId();
1683 LOG.warn("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1687 private static long ipToLong(InetAddress ip) {
1688 byte[] octets = ip.getAddress();
1690 for (byte octet : octets) {
1692 result |= octet & 0xff;
1698 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1699 if (externalIps == null) {
1700 return Collections.emptyList();
1703 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1706 // elan-instances config container
1707 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1708 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1709 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1710 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1713 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1714 return InstanceIdentifier.builder(ElanInstances.class)
1715 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1718 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1719 IdManagerService idManager, long routerId, String routerName) {
1720 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1721 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1722 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1724 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1728 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1729 short tableId, WriteTransaction writeFlowTx) {
1730 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1731 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1733 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1734 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1735 List<MatchInfo> matches = new ArrayList<>();
1736 matches.add(MatchEthernetType.IPV4);
1737 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1738 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1739 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1740 matches, preDnatToSnatInstructions);
1742 mdsalManager.addFlowToTx(naptDpnId, preDnatToSnatTableFlowEntity, writeFlowTx);
1743 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1744 preDnatToSnatTableFlowEntity, naptDpnId);
1747 public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1748 WriteTransaction removeFlowInvTx) {
1749 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1750 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1751 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1752 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1753 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null);
1754 mdsalManager.removeFlowToTx(naptDpnId, preDnatToSnatTableFlowEntity, removeFlowInvTx);
1755 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1756 preDnatToSnatTableFlowEntity, naptDpnId);
1759 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1760 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1761 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1764 public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1765 String vpnName, String externalIp,
1766 Boolean isMoreThanOneFipCheckOnDpn) {
1767 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1768 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1769 if (dpnInVpn.isPresent()) {
1770 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1771 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
1773 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1774 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1775 int floatingIpPresentCount = 0;
1776 for (IpAddresses ipAddress: ipAddressList) {
1777 if (!ipAddress.getIpAddress().equals(externalIp)
1778 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1779 floatingIpPresentCount++;
1780 //Add tunnel table check
1781 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1782 return Boolean.TRUE;
1784 //Remove tunnel table check
1785 if (!isMoreThanOneFipCheckOnDpn) {
1786 return Boolean.TRUE;
1791 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
1793 return Boolean.FALSE;
1795 } catch (NullPointerException e) {
1796 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
1797 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
1798 return Boolean.FALSE;
1801 return Boolean.FALSE;
1804 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1805 return InstanceIdentifier.builder(VpnInstanceOpData.class)
1806 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1807 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1810 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
1811 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1812 Optional<VpnInstance> vpnInstance =
1813 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1814 LogicalDatastoreType.CONFIGURATION, id);
1815 if (vpnInstance.isPresent()) {
1816 return getPrimaryRd(vpnInstance.get());
1821 public static String getPrimaryRd(VpnInstance vpnInstance) {
1822 List<String> rds = null;
1823 if (vpnInstance != null) {
1824 rds = getListOfRdsFromVpnInstance(vpnInstance);
1826 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
1829 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
1830 return InstanceIdentifier.builder(VpnInstances.class)
1831 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
1835 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
1836 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
1837 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
1838 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
1841 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
1842 if (routerName != null) {
1843 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1844 if (extRouter != null) {
1845 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
1849 return NatConstants.INVALID_ID;
1852 public static String validateAndAddNetworkMask(String ipAddress) {
1853 return ipAddress.contains("/32") ? ipAddress : ipAddress + "/32";
1856 public static InstanceIdentifier<VpnInterfaceOpDataEntry> getVpnInterfaceOpDataEntryIdentifier(
1857 String vpnInterfaceName, String vpnName) {
1858 return InstanceIdentifier.builder(VpnInterfaceOpData.class).child(VpnInterfaceOpDataEntry.class,
1859 new VpnInterfaceOpDataEntryKey(vpnInterfaceName, vpnName)).build();
1862 public static VpnInstanceOpDataEntry getVpnInstanceOpData(DataBroker broker, String rd) {
1863 InstanceIdentifier<VpnInstanceOpDataEntry> id = NatUtil.getVpnInstanceOpDataIdentifier(rd);
1864 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(
1865 broker, LogicalDatastoreType.OPERATIONAL, id).orNull();
1868 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
1869 String routerName, BigInteger dpnId) {
1870 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
1871 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
1873 if (networkData != null && networkData.isPresent()) {
1874 List<Uuid> routerUuidList = networkData.get().getRouterIds();
1875 if (routerUuidList != null && !routerUuidList.isEmpty()) {
1876 for (Uuid routerUuid : routerUuidList) {
1877 String sharedRouterName = routerUuid.getValue();
1878 if (!routerName.equals(sharedRouterName)) {
1879 BigInteger swtichDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
1880 if (swtichDpnId == null) {
1882 } else if (swtichDpnId.equals(dpnId)) {
1883 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
1884 + "associated with other active router {} on NAPT switch {}", networkId,
1885 sharedRouterName, swtichDpnId);
1895 public static void installRouterGwFlows(DataBroker dataBroker, IVpnManager vpnManager, Routers router,
1896 BigInteger primarySwitchId, int addOrRemove) {
1897 WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
1898 List<ExternalIps> externalIps = router.getExternalIps();
1899 List<String> externalIpsSting = new ArrayList<>();
1901 if (externalIps.isEmpty()) {
1902 LOG.error("installRouterGwFlows: setupRouterGwFlows no externalIP present");
1905 for (ExternalIps externalIp : externalIps) {
1906 externalIpsSting.add(externalIp.getIpAddress());
1908 Uuid subnetVpnName = externalIps.get(0).getSubnetId();
1909 if (addOrRemove == NwConstants.ADD_FLOW) {
1910 vpnManager.addRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
1911 router.getNetworkId(), subnetVpnName.getValue(), writeTx);
1912 vpnManager.addArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
1913 router.getExtGwMacAddress(), primarySwitchId,
1914 router.getNetworkId(), writeTx);
1916 vpnManager.removeRouterGwMacFlow(router.getRouterName(), router.getExtGwMacAddress(), primarySwitchId,
1917 router.getNetworkId(), subnetVpnName.getValue(), writeTx);
1918 vpnManager.removeArpResponderFlowsToExternalNetworkIps(router.getRouterName(), externalIpsSting,
1919 router.getExtGwMacAddress(), primarySwitchId,
1920 router.getNetworkId());
1925 public static CheckedFuture<Void, TransactionCommitFailedException> waitForTransactionToComplete(
1926 WriteTransaction tx) {
1927 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
1930 } catch (InterruptedException | ExecutionException e) {
1931 LOG.error("Error writing to datastore {}", e);
1936 public static Boolean isOpenStackVniSemanticsEnforcedForGreAndVxlan(IElanService elanManager,
1937 ProviderTypes extNwProvType) {
1938 if (elanManager.isOpenStackVniSemanticsEnforced() && (extNwProvType == ProviderTypes.GRE
1939 || extNwProvType == ProviderTypes.VXLAN)) {