2 * Copyright (c) 2016 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 java.math.BigInteger;
13 import com.google.common.collect.Lists;
14 import com.google.common.collect.Sets;
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.genius.mdsalutil.MDSALUtil;
18 import org.opendaylight.genius.mdsalutil.NwConstants;
19 import org.opendaylight.genius.mdsalutil.ActionInfo;
20 import org.opendaylight.genius.mdsalutil.ActionType;
21 import org.opendaylight.genius.mdsalutil.FlowEntity;
22 import org.opendaylight.genius.mdsalutil.MatchInfo;
23 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
24 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
25 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
27 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
28 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceOpData;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalIpsCounter;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpMap;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProtocolTypes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterIdName;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.SnatintIpPortMap;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
67 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;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnIdToVpnInstance;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronVpnPortipPortData;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPortKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
99 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;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
102 import org.opendaylight.yangtools.yang.binding.DataObject;
103 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
104 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
105 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
106 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
107 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
109 import com.google.common.base.Optional;
111 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
112 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
134 import org.opendaylight.yangtools.yang.common.RpcResult;
135 import org.slf4j.Logger;
136 import org.slf4j.LoggerFactory;
138 import java.net.InetAddress;
139 import java.net.UnknownHostException;
140 import java.util.ArrayList;
141 import java.util.Arrays;
142 import java.util.Collections;
143 import java.util.HashMap;
144 import java.util.List;
145 import java.util.Objects;
146 import java.util.Set;
147 import java.util.concurrent.ExecutionException;
148 import java.util.concurrent.Future;
152 public class NatUtil {
154 private static String OF_URI_SEPARATOR = ":";
155 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
158 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the reference value.
160 public static BigInteger getCookieSnatFlow(long routerId) {
161 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
162 BigInteger.valueOf(routerId));
166 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the reference value.
168 public static BigInteger getCookieNaptFlow(long routerId) {
169 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
170 BigInteger.valueOf(routerId));
174 getVpnId() returns the VPN ID from the VPN name
176 public static long getVpnId(DataBroker broker, String vpnName) {
177 if(vpnName == null) {
178 return NatConstants.INVALID_ID;
181 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
182 = getVpnInstanceToVpnIdIdentifier(vpnName);
183 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
184 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
187 long vpnId = NatConstants.INVALID_ID;
188 if(vpnInstance.isPresent()) {
189 Long vpnIdAsLong = vpnInstance.get().getVpnId();
190 if(vpnIdAsLong != null){
197 public static Long getVpnId(DataBroker broker, long routerId){
198 //Get the external network ID from the ExternalRouter model
199 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
200 if(networkId == null ){
201 LOG.error("NAT Service : networkId is null");
205 //Get the VPN ID from the ExternalNetworks model
206 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
207 if(vpnUuid == null ){
208 LOG.error("NAT Service : vpnUuid is null");
211 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
215 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
216 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)).build();
219 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
220 return InstanceIdentifier.builder(RouterToVpnMapping.class).child(Routermapping.class, new RoutermappingKey(routerId)).build();
223 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
224 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
225 .child(Ports.class, new PortsKey(portName)).build();
228 static InstanceIdentifier<IpMapping> getIpMappingIdentifier(String routerId, String portName, String internalIp) {
229 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
230 .child(Ports.class, new PortsKey(portName))
231 .child(IpMapping.class, new IpMappingKey(internalIp)).build();
235 getVpnInstanceToVpnIdIdentifier() returns the VPN instance from the below model using the VPN name as the key.
237 key "vpn-instance-name"
238 leaf vpn-instance-name {
250 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
251 getVpnInstanceToVpnIdIdentifier(String vpnName) {
252 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
253 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
254 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
257 static String getVpnInstanceFromVpnIdentifier(DataBroker broker, long vpnId) {
258 InstanceIdentifier<VpnIds> id = InstanceIdentifier.builder(VpnIdToVpnInstance.class)
259 .child(VpnIds.class, new VpnIdsKey(Long.valueOf(vpnId))).build();
260 Optional<VpnIds> vpnInstance = read(broker, LogicalDatastoreType.CONFIGURATION, id);
261 return vpnInstance.isPresent() ? vpnInstance.get().getVpnInstanceName() : null;
265 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
267 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
268 return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
269 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID)
270 .append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
273 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
274 return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
275 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).
276 append(NatConstants.FLOWID_SEPARATOR).append(port).toString();
280 getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key
281 container ext-routers {
284 leaf router-name { type string; }
285 leaf network-id { type yang:uuid; }
286 leaf enable-snat { type boolean; }
287 leaf-list external-ips {
288 type string; //format - ipaddress\prefixlength
290 leaf-list subnet-ids { type yang:uuid; }
295 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
296 String routerName = getRouterName(broker, routerId);
297 InstanceIdentifier id = buildRouterIdentifier(routerName);
298 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
299 if (routerData.isPresent()) {
300 return routerData.get().getNetworkId();
305 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
306 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class).child
307 (Routers.class, new RoutersKey(routerId)).build();
308 return routerInstanceIndentifier;
312 * getEnableSnatFromRouterId() returns IsSnatEnabled true is routerID is present in external n/w otherwise returns false
314 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId){
315 InstanceIdentifier id = buildRouterIdentifier(routerId);
316 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
317 if (routerData.isPresent()) {
318 return routerData.get().isEnableSnat();
323 getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key.
324 container external-networks {
330 leaf vpnid { type yang:uuid; }
331 leaf-list router-ids { type yang:uuid; }
332 leaf-list subnet-ids{ type yang:uuid; }
336 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
337 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
338 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
339 if (networkData.isPresent()) {
340 return networkData.get().getVpnid();
345 public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
346 InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
347 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
348 return networkData.isPresent() ? networkData.get().getRouterIds() : Collections.emptyList();
351 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
352 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
353 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
354 if (routerData.isPresent()) {
355 Uuid networkId = routerData.get().getNetworkId();
356 if(networkId != null) {
357 return networkId.getValue();
363 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
364 InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class).child
365 (Networks.class, new NetworksKey(networkId)).build();
373 getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id in a array using the router-id; as the key.
374 container napt-switches {
375 list router-to-napt-switch {
377 leaf router-id { type uint32; }
378 leaf primary-switch-id { type uint64; }
379 leaf secondary-switch-id { type uint64; }
383 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
384 // convert routerId to Name
385 String routerName = getRouterName(broker, routerId);
386 InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
387 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
388 if (routerToNaptSwitchData.isPresent()) {
389 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
390 return routerToNaptSwitchInstance.getPrimarySwitchId();
395 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
396 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class).child
397 (RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
401 public static String getRouterName(DataBroker broker, Long routerId) {
402 InstanceIdentifier id = buildRouterIdentifier(routerId);
403 Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
404 if (routerIdsData.isPresent()) {
405 RouterIds routerIdsInstance = routerIdsData.get();
406 return routerIdsInstance.getRouterName();
411 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
412 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class).child
413 (RouterIds.class, new RouterIdsKey(routerId)).build();
417 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
418 InstanceIdentifier<T> path) {
420 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
422 Optional<T> result = Optional.absent();
424 result = tx.read(datastoreType, path).get();
425 } catch (Exception e) {
426 throw new RuntimeException(e);
432 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
433 return InstanceIdentifier.builder(VpnInstanceOpData.class)
434 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
437 public static long readVpnId(DataBroker broker, String vpnName) {
439 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
440 = getVpnInstanceToVpnIdIdentifier(vpnName);
441 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
442 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
444 long vpnId = NatConstants.INVALID_ID;
445 if(vpnInstance.isPresent()) {
446 vpnId = vpnInstance.get().getVpnId();
451 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
452 FlowEntity flowEntity = new FlowEntity(dpnId);
453 flowEntity.setTableId(tableId);
454 flowEntity.setCookie(cookie);
458 public static long getIpAddress(byte[] rawIpAddress) {
459 return (((rawIpAddress[0] & 0xFF) << (3 * 8)) + ((rawIpAddress[1] & 0xFF) << (2 * 8))
460 + ((rawIpAddress[2] & 0xFF) << (1 * 8)) + (rawIpAddress[3] & 0xFF)) & 0xffffffffL;
463 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix) {
464 return new StringBuilder(64).append(NatConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
465 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
466 .append(destPrefix.getHostAddress()).toString();
469 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
470 String nextHopIp = null;
471 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
472 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
473 Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
474 if (tunnelInfo.isPresent()) {
475 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
476 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
477 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
484 getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName
486 key "vpn-instance-name"
487 leaf vpn-instance-name {
498 public static String getVpnRd(DataBroker broker, String vpnName) {
500 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
501 = getVpnInstanceToVpnIdIdentifier(vpnName);
502 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
503 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
506 if(vpnInstance.isPresent()) {
507 rd = vpnInstance.get().getVrfId();
512 /* getExternalIPPortMap() returns the internal IP and the port for the querried router ID, external IP and the port.
513 container intext-ip-port-map {
515 list ip-port-mapping {
517 leaf router-id { type uint32; }
518 list intext-ip-protocol-type {
520 leaf protocol { type protocol-types; }
522 key ip-port-internal;
523 description "internal to external ip-port mapping";
524 leaf ip-port-internal { type string; }
525 container ip-port-external {
533 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) {
534 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
535 InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
536 Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
537 if (ipPortMapData.isPresent()) {
538 IpPortMap ipPortMapInstance = ipPortMapData.get();
539 return ipPortMapInstance.getIpPortExternal();
544 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, String internalPort , ProtocolTypes protocolType) {
545 InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class).child
546 (IpPortMapping.class, new IpPortMappingKey(routerId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
547 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
551 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
552 BigInteger cookie, List<MatchInfo> listMatchInfo) {
554 FlowEntity flowEntity = new FlowEntity(dpnId);
555 flowEntity.setTableId(tableId);
556 flowEntity.setFlowId(flowId);
557 flowEntity.setPriority(priority);
558 flowEntity.setFlowName(flowName);
559 flowEntity.setCookie(cookie);
560 flowEntity.setMatchInfoList(listMatchInfo);
564 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName)
566 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
567 Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
569 if (configuredVpnInterface.isPresent()) {
575 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
576 return InstanceIdentifier.builder(VpnInterfaces.class)
577 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
580 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
581 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
582 Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
584 if (configuredVpnInterface.isPresent()) {
585 return configuredVpnInterface.get();
590 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
592 * NodeConnectorId is of form 'openflow:dpnid:portnum'
594 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
598 public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
599 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
600 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
601 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
611 description "vpn-id";
615 description "vpn name";
619 description "The UUID of the tenant that will own the subnet.";
624 description "UUID of router ";
626 leaf-list network_ids {
628 description "UUID representing the network ";
632 Method returns router Id associated to a VPN
635 public static String getRouterIdfromVpnInstance(DataBroker broker,String vpnName){
636 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
637 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
638 Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
640 if (optionalVpnMap.isPresent()) {
641 return optionalVpnMap.get().getRouterId().getValue();
646 public static String getRouterIdfromVpnId(DataBroker broker, long vpnId){
647 String vpnName = getVpnInstanceFromVpnIdentifier(broker, vpnId);
648 if (vpnName == null) {
649 LOG.trace("No VPN instance found for vpn id {}", vpnId);
653 return getRouterIdfromVpnInstance(broker, vpnName);
656 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
657 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
658 Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
660 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
661 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
662 if (routerId != null) {
663 for (VpnMap vpnMap : allMaps) {
664 if (vpnMap.getRouterId() != null &&
665 routerId.equals(vpnMap.getRouterId().getValue()) &&
666 !routerId.equals(vpnMap.getVpnId().getValue())) {
667 return vpnMap.getVpnId();
675 static long getAssociatedVpn(DataBroker broker, String routerName) {
676 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
677 Optional<Routermapping> optRouterMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
678 if(optRouterMapping.isPresent()) {
679 Routermapping routerMapping = optRouterMapping.get();
680 return routerMapping.getVpnId();
682 return NatConstants.INVALID_ID;
686 public static List<VpnToDpnList> getVpnToDpnList(DataBroker dataBroker, String vrfId )
688 List<VpnToDpnList> vpnDpnList = null;
690 InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier
691 .builder(VpnInstanceOpData.class)
692 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId))
695 Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
697 if(vpnInstanceOpData.isPresent())
699 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnInstanceOpData.get();
700 vpnDpnList = vpnInstanceOpDataEntry.getVpnToDpnList();
706 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
707 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
708 if(vpnUuid == null ){
709 log.error("No VPN instance associated with ext network {}", networkId);
712 return vpnUuid.getValue();
715 public static void addPrefixToBGP(DataBroker broker,
716 IBgpManager bgpManager,
717 IFibManager fibManager,
723 RouteOrigin origin) {
725 LOG.info("ADD: Adding Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label);
726 fibManager.addOrUpdateFibEntry(broker, rd, prefix, Arrays.asList(nextHopIp), (int)label, origin, null);
727 bgpManager.advertisePrefix(rd, prefix, Arrays.asList(nextHopIp), (int)label);
728 LOG.info("ADD: Added Fib entry rd {} prefix {} nextHop {} label {}", rd, prefix, nextHopIp, label);
729 } catch(Exception e) {
730 log.error("Add prefix failed", e);
734 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
735 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class).child
736 (RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
740 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
741 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class).child
742 (RouterPorts.class, new RouterPortsKey(routerId)).build();
743 return routerInstanceIndentifier;
746 /* container snatint-ip-port-map {
747 list intip-port-map {
749 leaf router-id { type uint32; }
752 leaf internal-ip { type string; }
753 list int-ip-proto-type {
755 leaf protocol { type protocol-types; }
756 leaf-list ports { type uint16; }
761 Method returns InternalIp port List
764 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker,Long routerId, String internalIpAddress, ProtocolTypes protocolType){
765 Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
766 if (optionalIpProtoType.isPresent()) {
767 return optionalIpProtoType.get().getPorts();
772 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId, String internalIpAddress, ProtocolTypes protocolType) {
773 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId = InstanceIdentifier.builder(SnatintIpPortMap.class).child
774 (IntipPortMap.class, new IntipPortMapKey(routerId)).child(IpPort.class, new IpPortKey(internalIpAddress)).child
775 (IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
776 return intIpProtocolTypeId;
779 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
780 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString()) ? ProtocolTypes.TCP : ProtocolTypes.UDP;
784 public static NaptSwitches getNaptSwitch(DataBroker broker) {
785 Optional<NaptSwitches> switchesOptional = read(broker, LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
786 if(switchesOptional.isPresent()) {
787 return switchesOptional.get();
792 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
793 return InstanceIdentifier.create(NaptSwitches.class);
796 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
797 return InstanceIdentifier.create(NaptSwitches.class).child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
800 public static String toStringIpAddress(byte[] ipAddress, Logger log)
803 if (ipAddress == null) {
808 ip = InetAddress.getByAddress(ipAddress).getHostAddress();
809 } catch(UnknownHostException e) {
810 log.error("NAT Service : Caught exception during toStringIpAddress()");
816 public static String getGroupIdKey(String routerName){
817 String groupIdKey = new String("snatmiss." + routerName);
821 public static long createGroupId(String groupIdKey,IdManagerService idManager) {
822 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
823 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
826 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
827 RpcResult<AllocateIdOutput> rpcResult = result.get();
828 return rpcResult.getResult().getIdValue();
829 } catch (NullPointerException | InterruptedException | ExecutionException e) {
835 public static void removePrefixFromBGP(DataBroker broker , IBgpManager bgpManager, IFibManager fibManager, String rd, String prefix, Logger log) {
837 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
838 fibManager.removeFibEntry(broker, rd, prefix, null);
839 bgpManager.withdrawPrefix(rd, prefix);
840 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
841 } catch(Exception e) {
842 log.error("Delete prefix failed", e);
846 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
847 FlowEntity flowEntity = new FlowEntity(dpnId);
848 flowEntity.setTableId(tableId);
849 flowEntity.setCookie(cookie);
850 flowEntity.setFlowId(flowId);
854 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
855 FlowEntity flowEntity = new FlowEntity(dpnId);
856 flowEntity.setTableId(tableId);
857 flowEntity.setFlowId(flowId);
861 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
862 Optional<IpPortMapping> getIportMappingData = read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId));
863 if(getIportMappingData.isPresent()) {
864 return getIportMappingData.get();
869 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
870 return InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
873 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
874 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
875 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMappingKey(routerId)).build();
879 public static List<String> getExternalIpsForRouter(DataBroker dataBroker,Long routerId) {
880 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
881 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
882 List<String> externalIps = new ArrayList<>();
883 if (ipMappingOptional.isPresent()) {
884 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
885 for (IpMap ipMap : ipMaps) {
886 externalIps.add(ipMap.getExternalIp());
889 Set<String> uniqueExternalIps = Sets.newHashSet(externalIps);
890 externalIps = Lists.newArrayList(uniqueExternalIps);
896 public static HashMap<String,Long> getExternalIpsLabelForRouter(DataBroker dataBroker,Long routerId) {
897 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
898 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
899 HashMap<String,Long> externalIpsLabel = new HashMap<>();
900 if (ipMappingOptional.isPresent()) {
901 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
902 for (IpMap ipMap : ipMaps) {
903 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
905 return externalIpsLabel;
910 container external-ips-counter {
912 list external-counters{
914 leaf segment-id { type uint32; }
915 list external-ip-counter {
917 leaf external-ip { type string; }
918 leaf counter { type uint8; }
924 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId){
925 String leastLoadedExternalIp = null;
926 InstanceIdentifier<ExternalCounters> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
927 Optional <ExternalCounters> externalCountersData = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
928 if (externalCountersData.isPresent()) {
929 ExternalCounters externalCounter = externalCountersData.get();
930 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
931 short countOfLstLoadExtIp = 32767;
932 for(ExternalIpCounter externalIpCounter : externalIpCounterList){
933 String curExternalIp = externalIpCounter.getExternalIp();
934 short countOfCurExtIp = externalIpCounter.getCounter();
935 if( countOfCurExtIp < countOfLstLoadExtIp ){
936 countOfLstLoadExtIp = countOfCurExtIp;
937 leastLoadedExternalIp = curExternalIp;
941 return leastLoadedExternalIp;
944 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId){
945 String subnetIP = getSubnetIp(dataBroker, subnetId);
946 if(subnetId != null){
947 return getSubnetIpAndPrefix(subnetIP);
952 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId){
953 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
954 .builder(Subnetmaps.class)
955 .child(Subnetmap.class, new SubnetmapKey(subnetId))
957 Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
958 if(removedSubnet.isPresent()) {
959 Subnetmap subnetMapEntry = removedSubnet.get();
960 return subnetMapEntry.getSubnetIp();
965 public static String[] getSubnetIpAndPrefix(String subnetString){
966 String[] subnetSplit = subnetString.split("/");
967 String subnetIp = subnetSplit[0];
968 String subnetPrefix = "0";
969 if (subnetSplit.length == 2) {
970 subnetPrefix = subnetSplit[1];
972 return new String[] {subnetIp, subnetPrefix};
975 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr){
976 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
977 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
978 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
979 if (leastLoadedExtIpAddrSplit.length == 2) {
980 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
982 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
985 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid){
986 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class).child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
987 Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
988 List<BigInteger> dpns = new ArrayList<>();
989 if (routerDpnListData.isPresent()) {
990 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
991 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
992 dpns.add(dpnVpnInterface.getDpnId());
999 public static long getBgpVpnId(DataBroker dataBroker, String routerName){
1000 long bgpVpnId = NatConstants.INVALID_ID;
1001 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
1002 if(bgpVpnUuid != null){
1003 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
1008 public static BigInteger getDpnForInterface(OdlInterfaceRpcService interfaceManagerRpcService, String ifName) {
1009 BigInteger nodeId = BigInteger.ZERO;
1011 GetDpidFromInterfaceInput
1013 new GetDpidFromInterfaceInputBuilder().setIntfName(ifName).build();
1014 Future<RpcResult<GetDpidFromInterfaceOutput>>
1016 interfaceManagerRpcService.getDpidFromInterface(dpIdInput);
1017 RpcResult<GetDpidFromInterfaceOutput> dpIdResult = dpIdOutput.get();
1018 if (dpIdResult.isSuccessful()) {
1019 nodeId = dpIdResult.getResult().getDpid();
1021 LOG.error("Could not retrieve DPN Id for interface {}", ifName);
1023 } catch (InterruptedException | ExecutionException e) {
1024 LOG.error("Exception when getting dpn for interface {}", ifName, e);
1029 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1031 return getEgressActionsForInterface(interfaceManager, ifName, tunnelKey, 0);
1034 public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName,
1035 Long tunnelKey, int pos) {
1036 LOG.debug("NAT Service : getEgressActionsForInterface called for interface {}", ifName);
1037 GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder()
1038 .setIntfName(ifName);
1039 if (tunnelKey != null) {
1040 egressActionsBuilder.setTunnelKey(tunnelKey);
1043 List<ActionInfo> listActionInfo = new ArrayList<>();
1045 Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager
1046 .getEgressActionsForInterface(egressActionsBuilder.build());
1047 RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
1048 if (!rpcResult.isSuccessful()) {
1049 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
1050 rpcResult.getErrors());
1052 List<Action> actions = rpcResult.getResult().getAction();
1053 for (Action action : actions) {
1054 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action
1056 if (actionClass instanceof OutputActionCase) {
1058 .add(new ActionInfo(ActionType.output, new String[] { ((OutputActionCase) actionClass)
1059 .getOutputAction().getOutputNodeConnector().getValue() }, pos++));
1060 } else if (actionClass instanceof PushVlanActionCase) {
1061 listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}, pos++));
1062 } else if (actionClass instanceof SetFieldCase) {
1063 if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
1064 int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId()
1065 .getVlanId().getValue();
1066 listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
1067 new String[] { Long.toString(vlanVid) }, pos++));
1069 } else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
1070 Short tableId = ((NxActionResubmitRpcAddGroupCase)actionClass).getNxResubmit().getTable();
1071 listActionInfo.add(new ActionInfo(ActionType.nx_resubmit,
1072 new String[] { tableId.toString() }, pos++));
1073 } else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
1074 NxRegLoad nxRegLoad =
1075 ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase)actionClass).getNxRegLoad();
1076 listActionInfo.add(new ActionInfo(ActionType.nx_load_reg_6,
1077 new String[] { nxRegLoad.getDst().getStart().toString(),
1078 nxRegLoad.getDst().getEnd().toString(),
1079 nxRegLoad.getValue().toString(10)}, pos++));
1083 } catch (InterruptedException | ExecutionException e) {
1084 LOG.warn("Exception when egress actions for interface {}", ifName, e);
1086 return listActionInfo;
1089 public static Port getNeutronPortForFloatingIp(DataBroker broker, IpAddress targetIP) {
1090 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_FLOATING_IP);
1093 public static Port getNeutronPortForRouterGetewayIp(DataBroker broker, IpAddress targetIP) {
1094 return getNeutronPortForIp(broker, targetIP, NeutronConstants.DEVICE_OWNER_GATEWAY_INF);
1097 public static List<Port> getNeutronPorts(DataBroker broker) {
1098 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports>
1099 portsIdentifier = InstanceIdentifier
1100 .create(Neutron.class)
1101 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports.class);
1102 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports> portsOptional = read(
1103 broker, LogicalDatastoreType.CONFIGURATION, portsIdentifier);
1105 if (!portsOptional.isPresent() || portsOptional.get().getPort() == null) {
1106 LOG.trace("No neutron ports found");
1107 return Collections.EMPTY_LIST;
1110 return portsOptional.get().getPort();
1114 public static Port getNeutronPortForIp(DataBroker broker,
1115 IpAddress targetIP, String deviceType) {
1116 List<Port> ports = getNeutronPorts(
1119 for (Port port : ports) {
1120 if (deviceType.equals(port.getDeviceOwner()) && port.getFixedIps() != null) {
1121 for (FixedIps ip : port.getFixedIps()) {
1122 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1132 public static Uuid getSubnetIdForFloatingIp(Port port,
1133 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress targetIP) {
1138 for (FixedIps ip : port.getFixedIps()) {
1139 if (Objects.equals(ip.getIpAddress(), targetIP)) {
1140 return ip.getSubnetId();
1147 public static Subnetmap getSubnetMap(DataBroker broker, Uuid subnetId) {
1148 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier.builder(Subnetmaps.class)
1149 .child(Subnetmap.class, new SubnetmapKey(subnetId)).build();
1150 Optional<Subnetmap> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
1151 return subnetOpt.isPresent() ? subnetOpt.get() : null;
1154 public static String getSubnetGwMac(DataBroker broker, Uuid subnetId, String vpnName) {
1155 if (subnetId == null) {
1159 InstanceIdentifier<Subnet> subnetInst = InstanceIdentifier.create(Neutron.class).child(Subnets.class)
1160 .child(Subnet.class, new SubnetKey(subnetId));
1161 Optional<Subnet> subnetOpt = read(broker, LogicalDatastoreType.CONFIGURATION, subnetInst);
1162 if (!subnetOpt.isPresent()) {
1166 IpAddress gatewayIp = subnetOpt.get().getGatewayIp();
1167 if (gatewayIp == null) {
1168 LOG.trace("No GW ip found for subnet {}", subnetId.getValue());
1172 InstanceIdentifier<VpnPortipToPort> portIpInst = InstanceIdentifier.builder(NeutronVpnPortipPortData.class)
1173 .child(VpnPortipToPort.class, new VpnPortipToPortKey(gatewayIp.getIpv4Address().getValue(), vpnName))
1175 Optional<VpnPortipToPort> portIpToPortOpt = read(broker, LogicalDatastoreType.OPERATIONAL, portIpInst);
1176 if (!portIpToPortOpt.isPresent()) {
1177 LOG.trace("No resolution was found to GW ip {} in subnet {}", gatewayIp, subnetId.getValue());
1181 return portIpToPortOpt.get().getMacAddress();