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 com.google.common.util.concurrent.ListenableFuture;
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;
29 import javax.annotation.Nonnull;
30 import javax.annotation.Nullable;
31 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
32 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
35 import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
36 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
37 import org.opendaylight.genius.mdsalutil.ActionInfo;
38 import org.opendaylight.genius.mdsalutil.FlowEntity;
39 import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
40 import org.opendaylight.genius.mdsalutil.InstructionInfo;
41 import org.opendaylight.genius.mdsalutil.MDSALUtil;
42 import org.opendaylight.genius.mdsalutil.MatchInfo;
43 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
44 import org.opendaylight.genius.mdsalutil.NwConstants;
45 import org.opendaylight.genius.mdsalutil.actions.ActionGroup;
46 import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
47 import org.opendaylight.genius.mdsalutil.actions.ActionOutput;
48 import org.opendaylight.genius.mdsalutil.actions.ActionPushVlan;
49 import org.opendaylight.genius.mdsalutil.actions.ActionRegLoad;
50 import org.opendaylight.genius.mdsalutil.actions.ActionSetFieldVlanVid;
51 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
52 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
53 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
54 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
55 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
56 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
57 import org.opendaylight.netvirt.elanmanager.api.IElanService;
58 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
59 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
60 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
61 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
62 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
63 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
64 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
65 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
66 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
67 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
68 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
69 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
70 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
71 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.DpnRouters;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.PrefixToInterface;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersList;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListBuilder;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.DpnRoutersListKey;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersList;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListBuilder;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.dpn.routers.dpn.routers.list.RoutersListKey;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPortKey;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.PrefixesKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpn.to.dpn.list.IpAddresses;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalSubnets;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpPortInfo;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
146 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
147 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
148 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
149 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
150 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.SubnetsKey;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
156 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
157 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
158 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMapKey;
159 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMapping;
160 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.port.info.FloatingIpIdToPortMappingKey;
161 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
162 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
163 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
164 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
165 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
166 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
167 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
168 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
169 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
170 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
171 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
172 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsBuilder;
173 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
174 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
175 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
176 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
177 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
178 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
179 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
180 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
181 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
182 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
183 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
184 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
185 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
186 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
187 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
188 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
189 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
190 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
191 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
192 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
193 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
194 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
195 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
196 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
197 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
198 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
199 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
200 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
201 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
202 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
203 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
204 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
205 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
206 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
207 import org.opendaylight.yangtools.yang.common.RpcResult;
208 import org.slf4j.Logger;
209 import org.slf4j.LoggerFactory;
211 public class NatUtil {
213 private static String OF_URI_SEPARATOR = ":";
214 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
217 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the
220 public static BigInteger getCookieSnatFlow(long routerId) {
221 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
222 BigInteger.valueOf(routerId));
226 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the
229 public static BigInteger getCookieNaptFlow(long routerId) {
230 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
231 BigInteger.valueOf(routerId));
235 getVpnId() returns the VPN ID from the VPN name
237 public static long getVpnId(DataBroker broker, String vpnName) {
238 if (vpnName == null) {
239 return NatConstants.INVALID_ID;
242 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
243 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
244 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
245 .instance.to.vpn.id.VpnInstance> vpnInstance =
246 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
247 LogicalDatastoreType.CONFIGURATION, id);
249 long vpnId = NatConstants.INVALID_ID;
250 if (vpnInstance.isPresent()) {
251 Long vpnIdAsLong = vpnInstance.get().getVpnId();
252 if (vpnIdAsLong != null) {
259 public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
260 //Get the external network ID from the ExternalRouter model
261 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
262 if (networkId == null) {
263 LOG.error("getNetworkVpnIdFromRouterId : networkId is null");
264 return NatConstants.INVALID_ID;
267 //Get the VPN ID from the ExternalNetworks model
268 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
269 if (vpnUuid == null) {
270 LOG.error("getNetworkVpnIdFromRouterId : vpnUuid is null");
271 return NatConstants.INVALID_ID;
273 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
277 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
278 return InstanceIdentifier.builder(FloatingIpInfo.class)
279 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
282 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
283 return InstanceIdentifier.builder(RouterToVpnMapping.class)
284 .child(Routermapping.class, new RoutermappingKey(routerId)).build();
287 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
288 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
289 .child(Ports.class, new PortsKey(portName)).build();
292 static InstanceIdentifier<InternalToExternalPortMap> getIntExtPortMapIdentifier(String routerId, String portName,
294 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
295 .child(Ports.class, new PortsKey(portName))
296 .child(InternalToExternalPortMap.class, new InternalToExternalPortMapKey(internalIp)).build();
299 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
300 .instance.to.vpn.id.VpnInstance> getVpnInstanceToVpnIdIdentifier(String vpnName) {
301 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
302 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
303 .instance.to.vpn.id.VpnInstance.class,
304 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
305 .instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
308 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
309 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
310 .child(VpnIds.class, new VpnIdsKey(vpnId)).build();
311 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
312 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(VpnIds::getVpnInstanceName).orElse(null);
316 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
318 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
319 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
320 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip;
323 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix, long vpnId) {
324 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
325 .FLOWID_SEPARATOR + destPrefix.getHostAddress() + NatConstants.FLOWID_SEPARATOR + vpnId;
328 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
329 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NatConstants.FLOWID_SEPARATOR + tableId + NatConstants
330 .FLOWID_SEPARATOR + routerID + NatConstants.FLOWID_SEPARATOR + ip + NatConstants.FLOWID_SEPARATOR
334 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
335 String routerName = getRouterName(broker, routerId);
336 if (routerName == null) {
337 LOG.error("getNetworkIdFromRouterId - empty routerName received");
340 return getNetworkIdFromRouterName(broker, routerName);
343 static Uuid getNetworkIdFromRouterName(DataBroker broker, String routerName) {
344 if (routerName == null) {
345 LOG.error("getNetworkIdFromRouterName - empty routerName received");
348 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
349 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
350 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getNetworkId).orElse(null);
353 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
354 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
355 .child(Routers.class, new RoutersKey(routerId)).build();
356 return routerInstanceIndentifier;
359 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
360 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class)
361 .child(RouterIds.class, new RouterIdsKey(routerId)).build();
366 * Return if SNAT is enabled for the given router.
368 * @param broker The DataBroker
369 * @param routerId The router
370 * @return boolean true if enabled, otherwise false
372 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId) {
373 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerId);
374 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
375 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::isEnableSnat).orElse(false);
378 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
379 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
380 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
381 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getVpnid).orElse(null);
384 public static ProviderTypes getProviderTypefromNetworkId(DataBroker broker, Uuid networkId) {
385 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
386 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
387 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
391 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
392 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
393 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
394 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getRouterIds).orElse(
395 Collections.emptyList());
398 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
399 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
400 Optional<Routers> routerData =
401 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
402 LogicalDatastoreType.CONFIGURATION, id);
403 if (routerData.isPresent()) {
404 Uuid networkId = routerData.get().getNetworkId();
405 if (networkId != null) {
406 return networkId.getValue();
409 LOG.error("getAssociatedExternalNetwork : External Network missing for routerid : {}", routerId);
413 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
414 return InstanceIdentifier.builder(ExternalNetworks.class)
415 .child(Networks.class, new NetworksKey(networkId)).build();
418 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
419 // convert routerId to Name
420 String routerName = getRouterName(broker, routerId);
421 if (routerName == null) {
422 LOG.error("getPrimaryNaptfromRouterId - empty routerName received");
425 return getPrimaryNaptfromRouterName(broker, routerName);
428 public static BigInteger getPrimaryNaptfromRouterName(DataBroker broker, String routerName) {
429 if (routerName == null) {
430 LOG.error("getPrimaryNaptfromRouterName - empty routerName received");
433 InstanceIdentifier<RouterToNaptSwitch> id = buildNaptSwitchIdentifier(routerName);
434 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
435 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterToNaptSwitch::getPrimarySwitchId).orElse(
439 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
440 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class)
441 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
445 public static String getRouterName(DataBroker broker, Long routerId) {
446 InstanceIdentifier<RouterIds> id = buildRouterIdentifier(routerId);
447 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
448 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(RouterIds::getRouterName).orElse(null);
451 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
452 return InstanceIdentifier.builder(VpnInstanceOpData.class)
453 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
456 public static long readVpnId(DataBroker broker, String vpnName) {
457 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
458 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
459 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
460 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
461 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
462 .VpnInstance::getVpnId).orElse(
463 NatConstants.INVALID_ID);
466 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
467 return new FlowEntityBuilder()
475 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
476 return new FlowEntityBuilder()
483 public static long getIpAddress(byte[] rawIpAddress) {
484 return ((rawIpAddress[0] & 0xFF) << 3 * 8) + ((rawIpAddress[1] & 0xFF) << 2 * 8)
485 + ((rawIpAddress[2] & 0xFF) << 1 * 8) + (rawIpAddress[3] & 0xFF) & 0xffffffffL;
488 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
489 String nextHopIp = null;
490 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
491 InstanceIdentifier.builder(DpnEndpoints.class)
492 .child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
493 Optional<DPNTEPsInfo> tunnelInfo =
494 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
495 LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
496 if (tunnelInfo.isPresent()) {
497 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
498 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
499 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
505 public static String getVpnRd(DataBroker broker, String vpnName) {
507 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
508 .instance.to.vpn.id.VpnInstance> id = getVpnInstanceToVpnIdIdentifier(vpnName);
509 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
510 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
511 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
512 .VpnInstance::getVrfId).orElse(null);
515 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
516 String internalPort, NAPTEntryEvent.Protocol protocol) {
517 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
518 InstanceIdentifier<IpPortMap> ipPortMapId =
519 buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
520 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
521 LogicalDatastoreType.CONFIGURATION, ipPortMapId).toJavaUtil().map(IpPortMap::getIpPortExternal).orElse(
525 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress,
527 ProtocolTypes protocolType) {
528 return InstanceIdentifier.builder(IntextIpPortMap.class)
529 .child(IpPortMapping.class, new IpPortMappingKey(routerId))
530 .child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
531 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
534 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName) {
535 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
536 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
537 LogicalDatastoreType.CONFIGURATION, interfaceId).isPresent();
540 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
541 return InstanceIdentifier.builder(VpnInterfaces.class)
542 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
545 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
546 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
547 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
548 LogicalDatastoreType.CONFIGURATION, interfaceId).orNull();
551 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
553 * NodeConnectorId is of form 'openflow:dpnid:portnum'
555 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
556 if (split.length != 3) {
557 LOG.error("getDpnFromNodeConnectorId : invalid portid : {}", portId.getValue());
563 public static BigInteger getDpIdFromInterface(
564 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
565 .state.Interface ifState) {
566 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
567 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
568 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
571 public static String getRouterIdfromVpnInstance(DataBroker broker, String vpnName) {
572 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
573 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
574 Optional<VpnMap> optionalVpnMap =
575 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
576 LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
577 if (optionalVpnMap.isPresent()) {
578 Uuid routerId = optionalVpnMap.get().getRouterId();
579 if (routerId != null) {
580 return routerId.getValue();
583 LOG.error("getRouterIdfromVpnInstance : Router not found for vpn : {}", vpnName);
587 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
588 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
589 Optional<VpnMaps> optionalVpnMaps =
590 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
591 LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
592 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
593 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
594 if (routerId != null) {
595 for (VpnMap vpnMap : allMaps) {
596 if (vpnMap.getRouterId() != null
597 && routerId.equals(vpnMap.getRouterId().getValue())
598 && !routerId.equals(vpnMap.getVpnId().getValue())) {
599 return vpnMap.getVpnId();
604 LOG.error("getVpnForRouter : VPN not found for routerID:{}", routerId);
608 static long getAssociatedVpn(DataBroker broker, String routerName) {
609 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
610 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
611 LogicalDatastoreType.OPERATIONAL, routerMappingId).toJavaUtil().map(Routermapping::getVpnId).orElse(
612 NatConstants.INVALID_ID);
615 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
616 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
617 if (vpnUuid == null) {
618 log.error("getAssociatedVPN : No VPN instance associated with ext network {}", networkId);
621 return vpnUuid.getValue();
624 // TODO Clean up the exception handling
625 @SuppressWarnings("checkstyle:IllegalCatch")
626 public static void addPrefixToBGP(DataBroker broker,
627 IBgpManager bgpManager,
628 IFibManager fibManager,
638 Logger log, RouteOrigin origin, BigInteger dpId) {
640 LOG.info("addPrefixToBGP : Adding Fib entry rd {} prefix {} nextHop {} label {}", rd,
641 prefix, nextHopIp, label);
642 if (nextHopIp == null) {
643 LOG.error("addPrefixToBGP : prefix {} rd {} failed since nextHopIp cannot be null.",
648 addPrefixToInterface(broker, getVpnId(broker, vpnName), null /*interfaceName*/,prefix, dpId,
649 subnetId, Prefixes.PrefixCue.Nat);
650 fibManager.addOrUpdateFibEntry(broker, rd, macAddress, prefix,
651 Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, (int)label, l3vni /*l3vni*/,
652 null /*gatewayMacAddress*/, parentVpnRd, origin, null /*writeTxn*/);
653 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
654 /* Publish to Bgp only if its an INTERNET VPN */
655 bgpManager.advertisePrefix(rd, null /*macAddress*/, prefix, Collections.singletonList(nextHopIp),
656 VrfEntry.EncapType.Mplsgre, (int) label, 0 /*l3vni*/, 0 /*l2vni*/,
657 null /*gatewayMac*/);
659 LOG.info("addPrefixToBGP : Added Fib entry rd {} prefix {} nextHop {} label {}", rd,
660 prefix, nextHopIp, label);
661 } catch (Exception e) {
662 LOG.error("addPrefixToBGP : Add prefix rd {} prefix {} nextHop {} label {} failed", rd,
663 prefix, nextHopIp, label, e);
667 static void addPrefixToInterface(DataBroker broker, long vpnId, String interfaceName, String ipPrefix,
668 BigInteger dpId, Uuid subnetId, Prefixes.PrefixCue prefixCue) {
669 InstanceIdentifier<Prefixes> prefixId = InstanceIdentifier.builder(PrefixToInterface.class)
670 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface
671 .VpnIds.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix
672 .to._interface.VpnIdsKey(vpnId))
673 .child(Prefixes.class, new PrefixesKey(ipPrefix)).build();
674 PrefixesBuilder prefixBuilder = new PrefixesBuilder().setDpnId(dpId).setIpAddress(ipPrefix);
675 prefixBuilder.setVpnInterfaceName(interfaceName).setSubnetId(subnetId).setPrefixCue(prefixCue);
677 SingleTransactionDataBroker.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, prefixId,
678 prefixBuilder.build());
679 } catch (TransactionCommitFailedException e) {
680 LOG.error("addPrefixToInterface : Failed to write prefxi-to-interface for {} vpn-id {} DPN {}",
681 ipPrefix, vpnId, dpId, e);
685 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
686 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class)
687 .child(RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
691 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
692 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class)
693 .child(RouterPorts.class, new RouterPortsKey(routerId)).build();
694 return routerInstanceIndentifier;
698 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker, Long routerId,
699 String internalIpAddress, ProtocolTypes protocolType) {
700 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
701 LogicalDatastoreType.CONFIGURATION,
702 buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType)).toJavaUtil().map(
703 IntIpProtoType::getPorts).orElse(Collections.emptyList());
706 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId,
707 String internalIpAddress,
708 ProtocolTypes protocolType) {
709 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId =
710 InstanceIdentifier.builder(SnatintIpPortMap.class)
711 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
712 .child(IpPort.class, new IpPortKey(internalIpAddress))
713 .child(IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
714 return intIpProtocolTypeId;
717 public static InstanceIdentifier<IpPort> buildSnatIntIpPortIdentifier(Long routerId,
718 String internalIpAddress) {
719 InstanceIdentifier<IpPort> intIpProtocolTypeId =
720 InstanceIdentifier.builder(SnatintIpPortMap.class)
721 .child(IntipPortMap.class, new IntipPortMapKey(routerId))
722 .child(IpPort.class, new IpPortKey(internalIpAddress)).build();
723 return intIpProtocolTypeId;
727 public static IpPort getInternalIpPortInfo(DataBroker dataBroker, Long routerId,
728 String internalIpAddress) {
729 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
730 LogicalDatastoreType.CONFIGURATION,
731 buildSnatIntIpPortIdentifier(routerId, internalIpAddress)).orNull();
734 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
735 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString())
736 ? ProtocolTypes.TCP : ProtocolTypes.UDP;
740 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
741 return InstanceIdentifier.create(NaptSwitches.class);
744 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
745 return InstanceIdentifier.create(NaptSwitches.class)
746 .child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
749 public static String getGroupIdKey(String routerName) {
750 return "snatmiss." + routerName;
753 public static long createGroupId(String groupIdKey, IdManagerService idManager) {
754 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
755 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
758 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
759 RpcResult<AllocateIdOutput> rpcResult = result.get();
760 return rpcResult.getResult().getIdValue();
761 } catch (NullPointerException | InterruptedException | ExecutionException e) {
762 LOG.error("createGroupId : Creating Group with Key: {} failed", groupIdKey, e);
767 // TODO Clean up the exception handling
768 @SuppressWarnings("checkstyle:IllegalCatch")
769 public static void removePrefixFromBGP(DataBroker broker, IBgpManager bgpManager, IFibManager fibManager,
770 String rd, String prefix, String vpnName, Logger log) {
772 LOG.debug("removePrefixFromBGP: Removing Fib entry rd {} prefix {}", rd, prefix);
773 fibManager.removeFibEntry(broker, rd, prefix, null);
774 if (rd != null && !rd.equalsIgnoreCase(vpnName)) {
775 bgpManager.withdrawPrefix(rd, prefix);
777 LOG.info("removePrefixFromBGP: Removed Fib entry rd {} prefix {}", rd, prefix);
778 } catch (Exception e) {
779 log.error("removePrefixFromBGP : Delete prefix for rd {} prefix {} vpnName {} failed",
780 rd, prefix, vpnName, e);
784 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
785 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
786 LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId)).orNull();
789 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
790 return InstanceIdentifier.builder(IntextIpPortMap.class)
791 .child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
794 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
795 .natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
796 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
797 .intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
798 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map
799 .IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111
800 .intext.ip.map.IpMappingKey(routerId)).build();
805 public static Collection<String> getExternalIpsForRouter(DataBroker dataBroker, Long routerId) {
806 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
807 .ip.map.IpMapping> ipMappingOptional =
808 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
809 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
810 // Ensure there are no duplicates
811 Collection<String> externalIps = new HashSet<>();
812 if (ipMappingOptional.isPresent()) {
813 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
814 for (IpMap ipMap : ipMaps) {
815 externalIps.add(ipMap.getExternalIp());
822 public static List<String> getExternalIpsForRouter(DataBroker dataBroker, String routerName) {
823 Routers routerData = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
824 if (routerData != null) {
825 return NatUtil.getIpsListFromExternalIps(routerData.getExternalIps());
828 return Collections.emptyList();
832 public static Map<String, Long> getExternalIpsLabelForRouter(DataBroker dataBroker, Long routerId) {
833 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext
834 .ip.map.IpMapping> ipMappingOptional =
835 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
836 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
837 Map<String, Long> externalIpsLabel = new HashMap<>();
838 if (ipMappingOptional.isPresent()) {
839 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
840 for (IpMap ipMap : ipMaps) {
841 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
844 return externalIpsLabel;
847 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId) {
848 String leastLoadedExternalIp = null;
849 InstanceIdentifier<ExternalCounters> id =
850 InstanceIdentifier.builder(ExternalIpsCounter.class)
851 .child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
852 Optional<ExternalCounters> externalCountersData =
853 MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
854 if (externalCountersData.isPresent()) {
855 ExternalCounters externalCounter = externalCountersData.get();
856 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
857 short countOfLstLoadExtIp = 32767;
858 for (ExternalIpCounter externalIpCounter : externalIpCounterList) {
859 String curExternalIp = externalIpCounter.getExternalIp();
860 short countOfCurExtIp = externalIpCounter.getCounter();
861 if (countOfCurExtIp < countOfLstLoadExtIp) {
862 countOfLstLoadExtIp = countOfCurExtIp;
863 leastLoadedExternalIp = curExternalIp;
867 return leastLoadedExternalIp;
870 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId) {
871 String subnetIP = getSubnetIp(dataBroker, subnetId);
872 if (subnetIP != null) {
873 return getSubnetIpAndPrefix(subnetIP);
875 LOG.error("getSubnetIpAndPrefix : SubnetIP and Prefix missing for subnet : {}", subnetId);
879 public static String[] getSubnetIpAndPrefix(String subnetString) {
880 String[] subnetSplit = subnetString.split("/");
881 String subnetIp = subnetSplit[0];
882 String subnetPrefix = "0";
883 if (subnetSplit.length == 2) {
884 subnetPrefix = subnetSplit[1];
886 return new String[] {subnetIp, subnetPrefix};
889 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId) {
890 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
891 .builder(Subnetmaps.class)
892 .child(Subnetmap.class, new SubnetmapKey(subnetId))
894 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
895 LogicalDatastoreType.CONFIGURATION, subnetmapId).toJavaUtil().map(Subnetmap::getSubnetIp).orElse(null);
899 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr) {
900 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
901 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
902 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
903 if (leastLoadedExtIpAddrSplit.length == 2) {
904 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
906 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
910 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid) {
911 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class)
912 .child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
913 Optional<RouterDpnList> routerDpnListData =
914 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
915 LogicalDatastoreType.OPERATIONAL, id);
916 List<BigInteger> dpns = new ArrayList<>();
917 if (routerDpnListData.isPresent()) {
918 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
919 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
920 dpns.add(dpnVpnInterface.getDpnId());
926 public static long getBgpVpnId(DataBroker dataBroker, String routerName) {
927 long bgpVpnId = NatConstants.INVALID_ID;
928 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
929 if (bgpVpnUuid != null) {
930 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
935 static org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
936 .RouterInterface getConfiguredRouterInterface(DataBroker broker, String interfaceName) {
937 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
938 LogicalDatastoreType.CONFIGURATION, NatUtil.getRouterInterfaceId(interfaceName)).orNull();
941 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911
942 .router.interfaces.RouterInterface> getRouterInterfaceId(String interfaceName) {
943 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight
944 .netvirt.l3vpn.rev130911.RouterInterfaces.class)
945 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
946 .RouterInterface.class,
947 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.router.interfaces
948 .RouterInterfaceKey(interfaceName)).build();
951 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
952 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
953 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
954 addToNeutronRouterDpnsMap(broker, routerName, interfaceName, dpId, writeOperTxn);
957 public static void addToNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
958 BigInteger dpId , WriteTransaction writeOperTxn) {
960 if (dpId.equals(BigInteger.ZERO)) {
961 LOG.warn("addToNeutronRouterDpnsMap : Could not retrieve dp id for interface {} "
962 + "to handle router {} association model", interfaceName, routerName);
966 LOG.debug("addToNeutronRouterDpnsMap : Adding the Router {} and DPN {} for the Interface {} in the "
967 + "ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
968 InstanceIdentifier<DpnVpninterfacesList> dpnVpnInterfacesListIdentifier = getRouterDpnId(routerName, dpId);
970 Optional<DpnVpninterfacesList> optionalDpnVpninterfacesList =
971 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
972 LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier);
973 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
974 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
975 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
976 .setInterface(interfaceName).build();
977 if (optionalDpnVpninterfacesList.isPresent()) {
978 LOG.debug("addToNeutronRouterDpnsMap : RouterDpnList already present for the Router {} and DPN {} for the "
979 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
980 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL, dpnVpnInterfacesListIdentifier
981 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
982 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
983 new RouterInterfacesKey(interfaceName)), routerInterface, true);
985 LOG.debug("addToNeutronRouterDpnsMap : Building new RouterDpnList for the Router {} and DPN {} for the "
986 + "Interface {} in the ODL-L3VPN : NeutronRouterDpn map", routerName, dpId, interfaceName);
987 RouterDpnListBuilder routerDpnListBuilder = new RouterDpnListBuilder();
988 routerDpnListBuilder.setRouterId(routerName);
989 DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
990 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
991 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces = new ArrayList<>();
992 routerInterfaces.add(routerInterface);
993 dpnVpnList.setRouterInterfaces(routerInterfaces);
994 routerDpnListBuilder.setDpnVpninterfacesList(Collections.singletonList(dpnVpnList.build()));
995 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
996 getRouterId(routerName),
997 routerDpnListBuilder.build(), true);
1002 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1003 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1004 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, interfaceName);
1005 addToDpnRoutersMap(broker, routerName, interfaceName, dpId, writeOperTxn);
1008 public static void addToDpnRoutersMap(DataBroker broker, String routerName, String interfaceName,
1009 BigInteger dpId, WriteTransaction writeOperTxn) {
1010 if (dpId.equals(BigInteger.ZERO)) {
1011 LOG.error("addToDpnRoutersMap : Could not retrieve dp id for interface {} to handle router {} "
1012 + "association model", interfaceName, routerName);
1016 LOG.debug("addToDpnRoutersMap : Adding the DPN {} and router {} for the Interface {} in the ODL-L3VPN : "
1017 + "DPNRouters map", dpId, routerName, interfaceName);
1018 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(dpId);
1020 Optional<DpnRoutersList> optionalDpnRoutersList =
1021 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1022 LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1024 if (optionalDpnRoutersList.isPresent()) {
1025 RoutersList routersList = new RoutersListBuilder().setKey(new RoutersListKey(routerName))
1026 .setRouter(routerName).build();
1027 List<RoutersList> routersListFromDs = optionalDpnRoutersList.get().getRoutersList();
1028 if (!routersListFromDs.contains(routersList)) {
1029 LOG.debug("addToDpnRoutersMap : Router {} not present for the DPN {}"
1030 + " in the ODL-L3VPN : DPNRouters map", routerName, dpId);
1031 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1032 dpnRoutersListIdentifier
1033 .child(RoutersList.class, new RoutersListKey(routerName)), routersList, true);
1035 LOG.debug("addToDpnRoutersMap : Router {} already mapped to the DPN {} in the ODL-L3VPN : "
1036 + "DPNRouters map", routerName, dpId);
1039 LOG.debug("addToDpnRoutersMap : Building new DPNRoutersList for the Router {} present in the DPN {} "
1040 + "ODL-L3VPN : DPNRouters map", routerName, dpId);
1041 DpnRoutersListBuilder dpnRoutersListBuilder = new DpnRoutersListBuilder();
1042 dpnRoutersListBuilder.setDpnId(dpId);
1043 RoutersListBuilder routersListBuilder = new RoutersListBuilder();
1044 routersListBuilder.setRouter(routerName);
1045 dpnRoutersListBuilder.setRoutersList(Collections.singletonList(routersListBuilder.build()));
1046 writeOperTxn.merge(LogicalDatastoreType.OPERATIONAL,
1047 getDpnRoutersId(dpId),
1048 dpnRoutersListBuilder.build(), true);
1053 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String interfaceName,
1054 BigInteger dpId, WriteTransaction writeOperTxn) {
1055 if (dpId.equals(BigInteger.ZERO)) {
1056 LOG.error("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {} "
1057 + "dissociation model", interfaceName, routerName);
1060 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1061 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1062 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1063 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1064 if (optionalRouterDpnList.isPresent()) {
1065 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1066 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1067 optionalRouterDpnList.get().getRouterInterfaces();
1068 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1069 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1070 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(interfaceName))
1071 .setInterface(interfaceName).build();
1072 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1073 if (routerInterfaces.isEmpty()) {
1074 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1076 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1077 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1078 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1079 new RouterInterfacesKey(interfaceName)));
1085 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName,
1086 BigInteger dpId, WriteTransaction writeOperTxn) {
1087 if (dpId.equals(BigInteger.ZERO)) {
1088 LOG.warn("removeFromNeutronRouterDpnsMap : DPN ID is invalid for the router {} ", 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 LOG.debug("removeFromNeutronRouterDpnsMap : Removing the dpn-vpninterfaces-list from the "
1098 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1099 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1101 LOG.debug("removeFromNeutronRouterDpnsMap : dpn-vpninterfaces-list does not exist in the "
1102 + "odl-l3vpn:neutron-router-dpns model for the router {}", routerName);
1106 public static void removeFromNeutronRouterDpnsMap(DataBroker broker, String routerName, String vpnInterfaceName,
1107 OdlInterfaceRpcService ifaceMgrRpcService,
1108 WriteTransaction writeOperTxn) {
1109 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1110 if (dpId.equals(BigInteger.ZERO)) {
1111 LOG.warn("removeFromNeutronRouterDpnsMap : Could not retrieve dp id for interface {} to handle router {}"
1112 + " dissociation model", vpnInterfaceName, routerName);
1115 InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
1116 Optional<DpnVpninterfacesList> optionalRouterDpnList =
1117 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1118 LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1119 if (optionalRouterDpnList.isPresent()) {
1120 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns
1121 .router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces> routerInterfaces =
1122 optionalRouterDpnList.get().getRouterInterfaces();
1123 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn
1124 .list.dpn.vpninterfaces.list.RouterInterfaces routerInterface =
1125 new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName))
1126 .setInterface(vpnInterfaceName).build();
1128 if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
1129 if (routerInterfaces.isEmpty()) {
1130 if (writeOperTxn != null) {
1131 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1133 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier);
1136 if (writeOperTxn != null) {
1137 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1138 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router
1139 .dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1140 new RouterInterfacesKey(vpnInterfaceName)));
1142 MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, routerDpnListIdentifier.child(
1143 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron
1144 .router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces.class,
1145 new RouterInterfacesKey(vpnInterfaceName)));
1152 public static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1153 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1154 BigInteger dpId = getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
1155 if (dpId.equals(BigInteger.ZERO)) {
1156 LOG.warn("removeFromDpnRoutersMap : removeFromDpnRoutersMap() : Could not retrieve DPN ID for interface {} "
1157 + "to handle router {} dissociation model", vpnInterfaceName, routerName);
1160 removeFromDpnRoutersMap(broker, routerName, vpnInterfaceName, dpId, ifaceMgrRpcService, writeOperTxn);
1163 static void removeFromDpnRoutersMap(DataBroker broker, String routerName, String vpnInterfaceName,
1164 BigInteger curDpnId,
1165 OdlInterfaceRpcService ifaceMgrRpcService, WriteTransaction writeOperTxn) {
1167 1) Get the DpnRoutersList for the DPN.
1168 2) Get the RoutersList identifier for the DPN and router.
1169 3) Get the VPN interfaces for the router (routerList) through which it is connected to the DPN.
1170 4) If the removed VPN interface is the only interface through which the router is connected to the DPN,
1171 then remove RouterList.
1174 LOG.debug("removeFromDpnRoutersMap() : Removing the DPN {} and router {} for the Interface {}"
1175 + " in the ODL-L3VPN : DPNRouters map", curDpnId, routerName, vpnInterfaceName);
1177 //Get the dpn-routers-list instance for the current DPN.
1178 InstanceIdentifier<DpnRoutersList> dpnRoutersListIdentifier = getDpnRoutersId(curDpnId);
1179 Optional<DpnRoutersList> dpnRoutersListData =
1180 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1181 LogicalDatastoreType.OPERATIONAL, dpnRoutersListIdentifier);
1183 if (dpnRoutersListData == null || !dpnRoutersListData.isPresent()) {
1184 LOG.error("removeFromDpnRoutersMap : dpn-routers-list is not present for DPN {} "
1185 + "in the ODL-L3VPN:dpn-routers model", curDpnId);
1189 //Get the routers-list instance for the router on the current DPN only
1190 InstanceIdentifier<RoutersList> routersListIdentifier = getRoutersList(curDpnId, routerName);
1191 Optional<RoutersList> routersListData =
1192 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1193 LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1195 if (routersListData == null || !routersListData.isPresent()) {
1196 LOG.error("removeFromDpnRoutersMap : routers-list is not present for the DPN {} "
1197 + "in the ODL-L3VPN:dpn-routers model",
1202 LOG.debug("removeFromDpnRoutersMap : Get the interfaces for the router {} "
1203 + "from the NeutronVPN - router-interfaces-map", routerName);
1204 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1205 .interfaces.map.RouterInterfaces> routerInterfacesId = getRoutersInterfacesIdentifier(routerName);
1206 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1207 .RouterInterfaces> routerInterfacesData =
1208 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1209 LogicalDatastoreType.CONFIGURATION, routerInterfacesId);
1211 if (routerInterfacesData == null || !routerInterfacesData.isPresent()) {
1212 LOG.debug("removeFromDpnRoutersMap : Unable to get the routers list for the DPN {}. Possibly all subnets "
1213 + "removed from router {} OR Router {} has been deleted. Hence DPN router model WILL be cleared ",
1214 curDpnId, routerName, routerName);
1215 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1219 //Get the VM interfaces for the router on the current DPN only.
1220 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces
1221 .map.router.interfaces.Interfaces> vmInterfaces = routerInterfacesData.get().getInterfaces();
1222 if (vmInterfaces == null) {
1223 LOG.debug("removeFromDpnRoutersMap : VM interfaces are not present for the router {} in the "
1224 + "NeutronVPN - router-interfaces-map", routerName);
1228 // If the removed VPN interface is the only interface through which the router is connected to the DPN,
1229 // then remove RouterList.
1230 for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router.interfaces.map
1231 .router.interfaces.Interfaces vmInterface : vmInterfaces) {
1232 String vmInterfaceName = vmInterface.getInterfaceId();
1233 BigInteger vmDpnId = getDpnForInterface(ifaceMgrRpcService, vmInterfaceName);
1234 if (vmDpnId.equals(BigInteger.ZERO) || !vmDpnId.equals(curDpnId)) {
1235 LOG.debug("removeFromDpnRoutersMap : DPN ID {} for the removed interface {} is not the same as that of "
1236 + "the DPN ID for the checked interface {} ",
1237 curDpnId, vpnInterfaceName, vmDpnId, vmInterfaceName);
1240 if (!vmInterfaceName.equalsIgnoreCase(vpnInterfaceName)) {
1241 LOG.error("removeFromDpnRoutersMap : Router {} is present in the DPN {} through the other interface {} "
1242 + "Hence DPN router model WOULD NOT be cleared", routerName, curDpnId, vmInterfaceName);
1246 LOG.debug("removeFromDpnRoutersMap : Router {} is present in the DPN {} only through the interface {} "
1247 + "Hence DPN router model WILL be cleared. Possibly last VM for the router "
1248 + "deleted in the DPN", routerName, curDpnId, vpnInterfaceName);
1249 writeOperTxn.delete(LogicalDatastoreType.OPERATIONAL, routersListIdentifier);
1252 private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1253 .rev150602.router.interfaces.map.RouterInterfaces> getRoutersInterfacesIdentifier(String routerName) {
1254 return InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn
1255 .rev150602.RouterInterfacesMap.class)
1256 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1257 .interfaces.map.RouterInterfaces.class,
1258 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.router
1259 .interfaces.map.RouterInterfacesKey(new Uuid(routerName))).build();
1262 private static InstanceIdentifier<RoutersList> getRoutersList(BigInteger dpnId, String routerName) {
1263 return InstanceIdentifier.builder(DpnRouters.class)
1264 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId))
1265 .child(RoutersList.class, new RoutersListKey(routerName)).build();
1268 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1269 BigInteger nodeId = BigInteger.ZERO;
1271 GetDpidFromInterfaceInput
1273 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1274 Future<RpcResult<GetDpidFromInterfaceOutput>>
1276 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1277 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1278 if (dpIdResult.isSuccessful()) {
1279 nodeId = dpIdResult.getResult().getDpid();
1281 LOG.error("removeFromDpnRoutersMap : Could not retrieve DPN Id for interface {}", ifName);
1283 } catch (NullPointerException | InterruptedException | ExecutionException e) {
1284 LOG.error("removeFromDpnRoutersMap : Exception when getting dpn for interface {}", ifName, e);
1290 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1292 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1296 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1297 Long tunnelKey, int pos) {
1298 LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
1299 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1300 .setIntfName(ifName);
1301 if (tunnelKey != null) {
1302 egressActionsBuilder.setTunnelKey(tunnelKey);
1305 List<ActionInfo> listActionInfo = new ArrayList<>();
1307 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1308 .getEgressActionsForInterface(egressActionsBuilder.build());
1309 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1310 if (!rpcResult.isSuccessful()) {
1311 LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} "
1312 + "returned with Errors {}", ifName, rpcResult.getErrors());
1314 List<Action> actions = rpcResult.getResult().getAction();
1315 for (Action action : actions) {
1316 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action
1317 actionClass = action.getAction();
1318 if (actionClass instanceof OutputActionCase) {
1319 listActionInfo.add(new ActionOutput(pos++,
1320 ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
1321 } else if (actionClass instanceof PushVlanActionCase) {
1322 listActionInfo.add(new ActionPushVlan(pos++));
1323 } else if (actionClass instanceof SetFieldCase) {
1324 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1325 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1326 .getVlanId().getValue();
1327 listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
1329 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1330 Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
1331 listActionInfo.add(new ActionNxResubmit(pos++, tableId));
1332 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1333 NxRegLoad nxRegLoad =
1334 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
1335 listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(),
1336 nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
1340 } catch (InterruptedException | ExecutionException e) {
1341 LOG.error("Exception when egress actions for interface {}", ifName, e);
1343 return listActionInfo;
1346 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1347 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1351 public static List<Port> getNeutronPorts(DataBroker broker) {
1352 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1353 portsIdentifier = InstanceIdentifier.create(Neutron.class)
1354 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1355 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1357 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1358 LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1360 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1361 LOG.error("getNeutronPorts : No neutron ports found");
1362 return Collections.emptyList();
1365 return portsOptional.get().getPort();
1368 public static Port getNeutronPortForIp(DataBroker broker,
1369 IpAddress targetIP, String deviceType) {
1370 List<Port> ports = getNeutronPorts(
1373 for (Port port : ports) {
1374 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1375 for (FixedIps ip : port.getFixedIps()) {
1376 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1382 LOG.error("getNeutronPortForIp : Neutron Port missing for IP:{} DeviceType:{}", targetIP, deviceType);
1386 public static Uuid getSubnetIdForFloatingIp(Port port, IpAddress targetIP) {
1388 LOG.error("getSubnetIdForFloatingIp : port is null");
1391 for (FixedIps ip : port.getFixedIps()) {
1392 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1393 return ip.getSubnetId();
1396 LOG.error("getSubnetIdForFloatingIp : No Fixed IP configured for targetIP:{}", targetIP);
1400 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1401 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1402 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1403 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1404 LogicalDatastoreType.CONFIGURATION, subnetmapId).orNull();
1408 public static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
1409 InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class)
1410 .child(NetworkMap.class, new NetworkMapKey(networkId)).build();
1411 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1412 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(NetworkMap::getSubnetIdList).orElse(
1413 Collections.emptyList());
1416 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1417 if (subnetId == null) {
1418 LOG.error("getSubnetGwMac : subnetID is null");
1422 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1423 .child(Subnet.class, new SubnetKey(subnetId));
1424 Optional<Subnet> subnetOpt =
1425 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1426 LogicalDatastoreType.CONFIGURATION, subnetInst);
1427 if (!subnetOpt.isPresent()) {
1428 LOG.error("getSubnetGwMac : unable to obtain Subnet for id : {}", subnetId);
1432 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1433 if (gatewayIp == null) {
1434 LOG.error("getSubnetGwMac : No GW ip found for subnet {}", subnetId.getValue());
1438 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1439 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1441 Optional<VpnPortipToPort> portIpToPortOpt =
1442 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1443 LogicalDatastoreType.CONFIGURATION, portIpInst);
1444 if (portIpToPortOpt.isPresent()) {
1445 return portIpToPortOpt.get().getMacAddress();
1448 InstanceIdentifier<LearntVpnVipToPort> learntIpInst = InstanceIdentifier.builder(LearntVpnVipToPortData.class)
1449 .child(LearntVpnVipToPort.class, new LearntVpnVipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1451 Optional<LearntVpnVipToPort> learntIpToPortOpt =
1452 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1453 LogicalDatastoreType.OPERATIONAL, learntIpInst);
1454 if (learntIpToPortOpt.isPresent()) {
1455 return learntIpToPortOpt.get().getMacAddress();
1458 LOG.info("getSubnetGwMac : No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1462 public static boolean isIPv6Subnet(String prefix) {
1463 return new IpPrefix(prefix.toCharArray()).getIpv6Prefix() != null;
1466 static InstanceIdentifier<DpnRoutersList> getDpnRoutersId(BigInteger dpnId) {
1467 return InstanceIdentifier.builder(DpnRouters.class)
1468 .child(DpnRoutersList.class, new DpnRoutersListKey(dpnId)).build();
1471 static InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
1472 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1473 .child(RouterDpnList.class, new RouterDpnListKey(routerName))
1474 .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
1477 static InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
1478 return InstanceIdentifier.builder(NeutronRouterDpns.class)
1479 .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
1482 protected static String getFloatingIpPortMacFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1483 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1484 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1485 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1486 FloatingIpIdToPortMapping::getFloatingIpPortMacAddress).orElse(null);
1489 protected static Uuid getFloatingIpPortSubnetIdFromFloatingIpId(DataBroker broker, Uuid floatingIpId) {
1490 InstanceIdentifier<FloatingIpIdToPortMapping> id = buildfloatingIpIdToPortMappingIdentifier(floatingIpId);
1491 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1492 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(
1493 FloatingIpIdToPortMapping::getFloatingIpPortSubnetId).orElse(null);
1496 static InstanceIdentifier<FloatingIpIdToPortMapping> buildfloatingIpIdToPortMappingIdentifier(Uuid floatingIpId) {
1497 return InstanceIdentifier.builder(FloatingIpPortInfo.class).child(FloatingIpIdToPortMapping.class, new
1498 FloatingIpIdToPortMappingKey(floatingIpId)).build();
1501 static Interface getInterfaceStateFromOperDS(DataBroker dataBroker, String interfaceName) {
1502 InstanceIdentifier<Interface> ifStateId =
1503 buildStateInterfaceId(interfaceName);
1504 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1505 LogicalDatastoreType.OPERATIONAL, ifStateId).orNull();
1508 static InstanceIdentifier<Interface> buildStateInterfaceId(String interfaceName) {
1509 InstanceIdentifier.InstanceIdentifierBuilder<Interface> idBuilder =
1510 InstanceIdentifier.builder(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
1511 .interfaces.rev140508.InterfacesState.class)
1512 .child(Interface.class,
1513 new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508
1514 .interfaces.state.InterfaceKey(interfaceName));
1515 InstanceIdentifier<Interface> id = idBuilder.build();
1519 public static Routers getRoutersFromConfigDS(DataBroker dataBroker, String routerName) {
1520 InstanceIdentifier<Routers> routerIdentifier = NatUtil.buildRouterIdentifier(routerName);
1521 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1522 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
1525 static void createRouterIdsConfigDS(DataBroker dataBroker, String routerName) {
1526 long routerId = NatUtil.getVpnId(dataBroker, routerName);
1527 if (routerId == NatConstants.INVALID_ID) {
1528 LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
1531 RouterIds rtrs = new RouterIdsBuilder().setKey(new RouterIdsKey(routerId))
1532 .setRouterId(routerId).setRouterName(routerName).build();
1533 MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, buildRouterIdentifier(routerId), rtrs);
1536 static FlowEntity buildDefaultNATFlowEntityForExternalSubnet(BigInteger dpId, long vpnId, String subnetId,
1537 IdManagerService idManager) {
1538 InetAddress defaultIP = null;
1540 defaultIP = InetAddress.getByName("0.0.0.0");
1541 } catch (UnknownHostException e) {
1542 LOG.error("buildDefaultNATFlowEntityForExternalSubnet : Failed to build FIB Table Flow for "
1543 + "Default Route to NAT.", e);
1547 List<MatchInfo> matches = new ArrayList<>();
1548 matches.add(MatchEthernetType.IPV4);
1549 //add match for vrfid
1550 matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(vpnId), MetaDataUtil.METADATA_MASK_VRFID));
1552 List<InstructionInfo> instructions = new ArrayList<>();
1553 List<ActionInfo> actionsInfo = new ArrayList<>();
1554 long groupId = createGroupId(NatUtil.getGroupIdKey(subnetId), idManager);
1555 actionsInfo.add(new ActionGroup(groupId));
1556 String flowRef = getFlowRef(dpId, NwConstants.L3_FIB_TABLE, defaultIP, vpnId);
1557 instructions.add(new InstructionApplyActions(actionsInfo));
1558 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.L3_FIB_TABLE, flowRef,
1559 NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef, 0, 0,
1560 NwConstants.COOKIE_DNAT_TABLE, matches, instructions);
1564 static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
1565 String routerName = getRouterName(broker, routerId);
1566 if (routerName == null) {
1567 LOG.error("getExtGwMacAddFromRouterId : empty routerName received");
1570 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1571 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1572 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
1575 static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
1576 InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
1577 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
1578 .child(Router.class, new RouterKey(routerUuid));
1579 return routerInstanceIdentifier;
1582 public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
1583 InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
1584 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1585 LogicalDatastoreType.CONFIGURATION, neutronRouterIdentifier).toJavaUtil().map(Router::getName).orElse(
1590 public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
1591 InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
1592 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1593 LogicalDatastoreType.CONFIGURATION,
1594 routerPortsIdentifier).toJavaUtil().map(RouterPorts::getPorts).orElse(Collections.emptyList());
1598 public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
1599 InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
1600 Optional<ExternalNetworks> externalNwData =
1601 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1602 LogicalDatastoreType.CONFIGURATION, externalNwIdentifier);
1603 if (externalNwData.isPresent()) {
1604 for (Networks externalNw : externalNwData.get().getNetworks()) {
1605 if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
1606 return externalNw.getRouterIds();
1610 return Collections.emptyList();
1613 public static boolean isIpInSubnet(String ipAddress, String start, String end) {
1616 long ipLo = ipToLong(InetAddress.getByName(start));
1617 long ipHi = ipToLong(InetAddress.getByName(end));
1618 long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
1619 return ipToTest >= ipLo && ipToTest <= ipHi;
1620 } catch (UnknownHostException e) {
1621 LOG.error("isIpInSubnet : failed for IP {}", ipAddress, e);
1627 public static Collection<Uuid> getExternalSubnetIdsFromExternalIps(List<ExternalIps> externalIps) {
1628 if (externalIps == null) {
1629 return Collections.emptySet();
1632 return externalIps.stream().map(ExternalIps::getSubnetId).collect(Collectors.toSet());
1636 public static Collection<Uuid> getExternalSubnetIdsForRouter(DataBroker dataBroker, String routerName) {
1637 if (routerName == null) {
1638 LOG.error("getExternalSubnetIdsForRouter : empty routerName received");
1639 return Collections.emptySet();
1642 InstanceIdentifier<Routers> id = buildRouterIdentifier(routerName);
1643 Optional<Routers> routerData =
1644 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1645 LogicalDatastoreType.CONFIGURATION, id);
1646 if (routerData.isPresent()) {
1647 return NatUtil.getExternalSubnetIdsFromExternalIps(routerData.get().getExternalIps());
1649 LOG.warn("getExternalSubnetIdsForRouter : No external router data for router {}", routerName);
1650 return Collections.emptySet();
1655 protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1656 .subnets.Subnets> getOptionalExternalSubnets(DataBroker dataBroker, Uuid subnetId) {
1657 if (subnetId == null) {
1658 LOG.warn("getOptionalExternalSubnets : subnetId is null");
1659 return Optional.absent();
1662 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1663 .rev160111.external.subnets.Subnets> subnetsIdentifier =
1664 InstanceIdentifier.builder(ExternalSubnets.class)
1665 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
1666 .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
1667 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1668 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
1671 protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
1672 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
1673 .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
1675 if (optionalExternalSubnets.isPresent()) {
1676 return NatUtil.getVpnId(dataBroker, subnetId.getValue());
1679 return NatConstants.INVALID_ID;
1682 protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1684 Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(dataBroker, externalIpAddress, router);
1685 if (externalSubnetId != null) {
1686 return NatUtil.getExternalSubnetVpnId(dataBroker,externalSubnetId);
1689 return NatConstants.INVALID_ID;
1692 protected static Uuid getExternalSubnetForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
1694 externalIpAddress = validateAndAddNetworkMask(externalIpAddress);
1695 List<ExternalIps> externalIps = router.getExternalIps();
1696 for (ExternalIps extIp : externalIps) {
1697 String extIpString = validateAndAddNetworkMask(extIp.getIpAddress());
1698 if (extIpString.equals(externalIpAddress)) {
1699 return extIp.getSubnetId();
1702 LOG.error("getExternalSubnetForRouterExternalIp : Missing External Subnet for Ip:{}", externalIpAddress);
1706 private static long ipToLong(InetAddress ip) {
1707 byte[] octets = ip.getAddress();
1709 for (byte octet : octets) {
1711 result |= octet & 0xff;
1717 static List<String> getIpsListFromExternalIps(@Nullable List<ExternalIps> externalIps) {
1718 if (externalIps == null) {
1719 return Collections.emptyList();
1722 return externalIps.stream().map(ExternalIps::getIpAddress).collect(Collectors.toList());
1725 // elan-instances config container
1726 public static ElanInstance getElanInstanceByName(String elanInstanceName, DataBroker broker) {
1727 InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
1728 return SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(broker,
1729 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
1732 public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
1733 return InstanceIdentifier.builder(ElanInstances.class)
1734 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
1737 public static long getTunnelIdForNonNaptToNaptFlow(DataBroker dataBroker, IElanService elanManager,
1738 IdManagerService idManager, long routerId, String routerName) {
1739 if (elanManager.isOpenStackVniSemanticsEnforced()) {
1740 // Router VNI will be set as tun_id if OpenStackSemantics is enabled
1741 return NatOverVxlanUtil.getRouterVni(idManager, routerName, routerId).longValue();
1743 return NatEvpnUtil.getTunnelIdForRouter(idManager, dataBroker, routerName, routerId);
1747 public static void makePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1748 short tableId, WriteTransaction writeFlowTx) {
1749 LOG.debug("makePreDnatToSnatTableEntry : Create Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1750 NwConstants.PDNAT_TABLE, tableId, naptDpnId);
1752 List<Instruction> preDnatToSnatInstructions = new ArrayList<>();
1753 preDnatToSnatInstructions.add(new InstructionGotoTable(tableId).buildInstruction(0));
1754 List<MatchInfo> matches = new ArrayList<>();
1755 matches.add(MatchEthernetType.IPV4);
1756 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1757 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1758 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE,
1759 matches, preDnatToSnatInstructions);
1761 mdsalManager.addFlowToTx(naptDpnId, preDnatToSnatTableFlowEntity, writeFlowTx);
1762 LOG.debug("makePreDnatToSnatTableEntry : Successfully installed Pre-DNAT flow {} on NAPT DpnId {} ",
1763 preDnatToSnatTableFlowEntity, naptDpnId);
1766 public static void removePreDnatToSnatTableEntry(IMdsalApiManager mdsalManager, BigInteger naptDpnId,
1767 WriteTransaction removeFlowInvTx) {
1768 LOG.debug("removePreDnatToSnatTableEntry : Remove Pre-DNAT table {} --> table {} flow on NAPT DpnId {} ",
1769 NwConstants.PDNAT_TABLE, NwConstants.INBOUND_NAPT_TABLE, naptDpnId);
1770 String flowRef = getFlowRefPreDnatToSnat(naptDpnId, NwConstants.PDNAT_TABLE, "PreDNATToSNAT");
1771 Flow preDnatToSnatTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.PDNAT_TABLE,flowRef,
1772 5, flowRef, 0, 0, NwConstants.COOKIE_DNAT_TABLE, null, null);
1773 mdsalManager.removeFlowToTx(naptDpnId, preDnatToSnatTableFlowEntity, removeFlowInvTx);
1774 LOG.debug("removePreDnatToSnatTableEntry: Successfully removed Pre-DNAT flow {} on NAPT DpnId = {}",
1775 preDnatToSnatTableFlowEntity, naptDpnId);
1778 private static String getFlowRefPreDnatToSnat(BigInteger dpnId, short tableId, String uniqueId) {
1779 return NatConstants.NAPT_FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
1780 + NwConstants.FLOWID_SEPARATOR + uniqueId;
1783 public static Boolean isFloatingIpPresentForDpn(DataBroker dataBroker, BigInteger dpnId, String rd,
1784 String vpnName, String externalIp,
1785 Boolean isMoreThanOneFipCheckOnDpn) {
1786 InstanceIdentifier<VpnToDpnList> id = getVpnToDpnListIdentifier(rd, dpnId);
1787 Optional<VpnToDpnList> dpnInVpn = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
1788 if (dpnInVpn.isPresent()) {
1789 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list is not empty for vpnName {}, dpn id {}, "
1790 + "rd {} and floatingIp {}", vpnName, dpnId, rd, externalIp);
1792 List<IpAddresses> ipAddressList = dpnInVpn.get().getIpAddresses();
1793 if (ipAddressList != null && !ipAddressList.isEmpty()) {
1794 int floatingIpPresentCount = 0;
1795 for (IpAddresses ipAddress: ipAddressList) {
1796 if (!ipAddress.getIpAddress().equals(externalIp)
1797 && IpAddresses.IpAddressSource.FloatingIP.equals(ipAddress.getIpAddressSource())) {
1798 floatingIpPresentCount++;
1799 //Add tunnel table check
1800 if (isMoreThanOneFipCheckOnDpn && floatingIpPresentCount > 1) {
1801 return Boolean.TRUE;
1803 //Remove tunnel table check
1804 if (!isMoreThanOneFipCheckOnDpn) {
1805 return Boolean.TRUE;
1810 LOG.debug("isFloatingIpPresentForDpn : vpn-to-dpn-list does not contain any floating IP for DPN {}",
1812 return Boolean.FALSE;
1814 } catch (NullPointerException e) {
1815 LOG.error("isFloatingIpPresentForDpn: Exception occurred on getting external IP address from "
1816 + "vpn-to-dpn-list on Dpn {}", dpnId, e);
1817 return Boolean.FALSE;
1820 return Boolean.FALSE;
1823 private static InstanceIdentifier<VpnToDpnList> getVpnToDpnListIdentifier(String rd, BigInteger dpnId) {
1824 return InstanceIdentifier.builder(VpnInstanceOpData.class)
1825 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(rd))
1826 .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
1829 public static String getPrimaryRd(DataBroker dataBroker, String vpnName) {
1830 InstanceIdentifier<VpnInstance> id = getVpnInstanceIdentifier(vpnName);
1831 Optional<VpnInstance> vpnInstance =
1832 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
1833 LogicalDatastoreType.CONFIGURATION, id);
1834 if (vpnInstance.isPresent()) {
1835 return getPrimaryRd(vpnInstance.get());
1840 public static String getPrimaryRd(VpnInstance vpnInstance) {
1841 List<String> rds = null;
1842 if (vpnInstance != null) {
1843 rds = getListOfRdsFromVpnInstance(vpnInstance);
1845 return rds == null || rds.isEmpty() ? vpnInstance.getVpnInstanceName() : rds.get(0);
1848 public static InstanceIdentifier<VpnInstance> getVpnInstanceIdentifier(String vpnName) {
1849 return InstanceIdentifier.builder(VpnInstances.class)
1850 .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
1854 public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
1855 VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
1856 return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
1857 vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
1860 public static long getVpnIdFromExternalSubnet(DataBroker dataBroker, String routerName, String externalIpAddress) {
1861 if (routerName != null) {
1862 Routers extRouter = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
1863 if (extRouter != null) {
1864 return getExternalSubnetVpnIdForRouterExternalIp(dataBroker, externalIpAddress, extRouter);
1868 return NatConstants.INVALID_ID;
1871 public static void djcFlow(FlowEntity flowEntity, int addOrRemove, IMdsalApiManager mdsalManager) {
1872 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
1873 String jobKey = (flowEntity.getFlowName() != null) ? flowEntity.getFlowName() : flowEntity.getFlowId();
1874 dataStoreCoordinator.enqueueJob(jobKey, () -> {
1875 List<ListenableFuture<Void>> futures = new ArrayList<>();
1876 if (addOrRemove == NwConstants.ADD_FLOW) {
1877 futures.add(mdsalManager.installFlow(flowEntity));
1879 futures.add(mdsalManager.removeFlow(flowEntity));
1885 public static String validateAndAddNetworkMask(String ipAddress) {
1886 return ipAddress.contains("/32") ? ipAddress : (ipAddress + "/32");
1889 public static boolean checkForRoutersWithSameExtNetAndNaptSwitch(DataBroker broker, Uuid networkId,
1890 String routerName, BigInteger dpnId) {
1891 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
1892 Optional<Networks> networkData = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
1894 if (networkData != null && networkData.isPresent()) {
1895 List<Uuid> routerUuidList = networkData.get().getRouterIds();
1896 if (routerUuidList != null && !routerUuidList.isEmpty()) {
1897 for (Uuid routerUuid : routerUuidList) {
1898 String sharedRouterName = routerUuid.getValue();
1899 if (!routerName.equals(sharedRouterName)) {
1900 BigInteger swtichDpnId = NatUtil.getPrimaryNaptfromRouterName(broker, sharedRouterName);
1901 if (swtichDpnId == null) {
1903 } else if (swtichDpnId.equals(dpnId)) {
1904 LOG.debug("checkForRoutersWithSameExtNetAndNaptSwitch: external-network {} is "
1905 + "associated with other active router {} on NAPT switch {}", networkId,
1906 sharedRouterName, swtichDpnId);
1916 public static CheckedFuture<Void, TransactionCommitFailedException> waitForTransactionToComplete(
1917 WriteTransaction tx) {
1918 CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
1921 } catch (InterruptedException | ExecutionException e) {
1922 LOG.error("Error writing to datastore {}", e);