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.vpnservice.natservice.internal;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
17 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
18 import org.opendaylight.vpnservice.mdsalutil.FlowEntity;
19 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
20 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
21 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
22 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceToVpnId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdInputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.AllocateIdOutput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.*;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ext.routers.Routers;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ext.routers.RoutersKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.ips.counter.ExternalCounters;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.ips.counter.ExternalCountersKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.ip.port.map.IpPortExternal;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.router.id.name.RouterIds;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.router.id.name.RouterIdsKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.RouterToVpnMapping;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.router.to.vpn.mapping.Routermapping;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.FloatingIpInfo;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.NeutronRouterDpns;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.Subnetmaps;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMaps;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.Subnetmap;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapKey;
64 import org.opendaylight.yangtools.yang.binding.DataObject;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
67 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
69 import com.google.common.base.Optional;
71 import org.opendaylight.bgpmanager.api.IBgpManager;
72 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.networks.Networks;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.external.networks.NetworksKey;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.RouterPorts;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.RouterPortsKey;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.Ports;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.ExternalNetworks;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.napt.switches.RouterToNaptSwitch;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.DpnEndpoints;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfoKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.IntextIpPortMap;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.IpPortMapping;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
94 import org.opendaylight.yangtools.yang.common.RpcResult;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
98 import java.net.InetAddress;
99 import java.net.UnknownHostException;
100 import java.util.concurrent.ExecutionException;
101 import java.util.concurrent.Future;
105 public class NatUtil {
107 private static String OF_URI_SEPARATOR = ":";
108 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
111 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the reference value.
113 public static BigInteger getCookieSnatFlow(long routerId) {
114 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
115 BigInteger.valueOf(routerId));
119 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the reference value.
121 public static BigInteger getCookieNaptFlow(long routerId) {
122 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
123 BigInteger.valueOf(routerId));
127 getVpnId() returns the VPN ID from the VPN name
129 public static long getVpnId(DataBroker broker, String vpnName) {
130 if(vpnName == null) {
131 return NatConstants.INVALID_ID;
134 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
135 = getVpnInstanceToVpnIdIdentifier(vpnName);
136 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
137 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
139 long vpnId = NatConstants.INVALID_ID;
140 if(vpnInstance.isPresent()) {
141 vpnId = vpnInstance.get().getVpnId();
146 public static Long getVpnId(DataBroker broker, long routerId){
147 //Get the external network ID from the ExternalRouter model
148 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
149 if(networkId == null ){
150 LOG.error("NAT Service : networkId is null");
154 //Get the VPN ID from the ExternalNetworks model
155 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
156 if(vpnUuid == null ){
157 LOG.error("NAT Service : vpnUuid is null");
160 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
164 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
165 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)).build();
168 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
169 return InstanceIdentifier.builder(RouterToVpnMapping.class).child(Routermapping.class, new RoutermappingKey(routerId)).build();
172 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
173 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
174 .child(Ports.class, new PortsKey(portName)).build();
177 static InstanceIdentifier<IpMapping> getIpMappingIdentifier(String routerId, String portName, String internalIp) {
178 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
179 .child(Ports.class, new PortsKey(portName))
180 .child(IpMapping.class, new IpMappingKey(internalIp)).build();
184 getVpnInstanceToVpnIdIdentifier() returns the VPN instance from the below model using the VPN name as the key.
186 key "vpn-instance-name"
187 leaf vpn-instance-name {
199 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
200 getVpnInstanceToVpnIdIdentifier(String vpnName) {
201 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
202 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
203 new org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
207 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
209 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
210 return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
211 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID)
212 .append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
215 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
216 return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
217 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).
218 append(NatConstants.FLOWID_SEPARATOR).append(port).toString();
222 getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key
223 container ext-routers {
226 leaf router-name { type string; }
227 leaf network-id { type yang:uuid; }
228 leaf enable-snat { type boolean; }
229 leaf-list external-ips {
230 type string; //format - ipaddress\prefixlength
232 leaf-list subnet-ids { type yang:uuid; }
237 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
238 String routerName = getRouterName(broker, routerId);
239 InstanceIdentifier id = buildRouterIdentifier(routerName);
240 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
241 if (routerData.isPresent()) {
242 return routerData.get().getNetworkId();
247 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
248 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class).child
249 (Routers.class, new RoutersKey(routerId)).build();
250 return routerInstanceIndentifier;
254 * getEnableSnatFromRouterId() returns IsSnatEnabled true is routerID is present in external n/w otherwise returns false
256 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId){
257 InstanceIdentifier id = buildRouterIdentifier(routerId);
258 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
259 if (routerData.isPresent()) {
260 return routerData.get().isEnableSnat();
265 getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key.
266 container external-networks {
272 leaf vpnid { type yang:uuid; }
273 leaf-list router-ids { type yang:uuid; }
274 leaf-list subnet-ids{ type yang:uuid; }
278 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
279 InstanceIdentifier id = buildNetworkIdentifier(networkId);
280 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
281 if (networkData.isPresent()) {
282 return networkData.get().getVpnid();
287 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
288 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
289 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
290 if (routerData.isPresent()) {
291 Uuid networkId = routerData.get().getNetworkId();
292 if(networkId != null) {
293 return networkId.getValue();
299 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
300 InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class).child
301 (Networks.class, new NetworksKey(networkId)).build();
309 getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id in a array using the router-id; as the key.
310 container napt-switches {
311 list router-to-napt-switch {
313 leaf router-id { type uint32; }
314 leaf primary-switch-id { type uint64; }
315 leaf secondary-switch-id { type uint64; }
319 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
320 // convert routerId to Name
321 String routerName = getRouterName(broker, routerId);
322 InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
323 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.OPERATIONAL, id);
324 if (routerToNaptSwitchData.isPresent()) {
325 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
326 return routerToNaptSwitchInstance.getPrimarySwitchId();
331 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
332 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class).child
333 (RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
337 public static String getRouterName(DataBroker broker, Long routerId) {
338 InstanceIdentifier id = buildRouterIdentifier(routerId);
339 Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
340 if (routerIdsData.isPresent()) {
341 RouterIds routerIdsInstance = routerIdsData.get();
342 return routerIdsInstance.getRouterName();
347 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
348 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class).child
349 (RouterIds.class, new RouterIdsKey(routerId)).build();
353 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
354 InstanceIdentifier<T> path) {
356 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
358 Optional<T> result = Optional.absent();
360 result = tx.read(datastoreType, path).get();
361 } catch (Exception e) {
362 throw new RuntimeException(e);
368 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
369 return InstanceIdentifier.builder(VpnInstanceOpData.class)
370 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
373 public static long readVpnId(DataBroker broker, String vpnName) {
375 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
376 = getVpnInstanceToVpnIdIdentifier(vpnName);
377 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
378 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
380 long vpnId = NatConstants.INVALID_ID;
381 if(vpnInstance.isPresent()) {
382 vpnId = vpnInstance.get().getVpnId();
387 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
388 FlowEntity flowEntity = new FlowEntity(dpnId);
389 flowEntity.setTableId(tableId);
390 flowEntity.setCookie(cookie);
394 public static long getIpAddress(byte[] rawIpAddress) {
395 return (((rawIpAddress[0] & 0xFF) << (3 * 8)) + ((rawIpAddress[1] & 0xFF) << (2 * 8))
396 + ((rawIpAddress[2] & 0xFF) << (1 * 8)) + (rawIpAddress[3] & 0xFF)) & 0xffffffffL;
399 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix) {
400 return new StringBuilder(64).append(NatConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
401 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
402 .append(destPrefix.getHostAddress()).toString();
405 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
406 String nextHopIp = null;
407 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
408 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
409 Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
410 if (tunnelInfo.isPresent()) {
411 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
412 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
413 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
420 getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName
422 key "vpn-instance-name"
423 leaf vpn-instance-name {
434 public static String getVpnRd(DataBroker broker, String vpnName) {
436 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
437 = getVpnInstanceToVpnIdIdentifier(vpnName);
438 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
439 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
442 if(vpnInstance.isPresent()) {
443 rd = vpnInstance.get().getVrfId();
448 /* getExternalIPPortMap() returns the internal IP and the port for the querried router ID, external IP and the port.
449 container intext-ip-port-map {
451 list ip-port-mapping {
453 leaf router-id { type uint32; }
454 list intext-ip-protocol-type {
456 leaf protocol { type protocol-types; }
458 key ip-port-internal;
459 description "internal to external ip-port mapping";
460 leaf ip-port-internal { type string; }
461 container ip-port-external {
469 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) {
470 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
471 InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
472 Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
473 if (ipPortMapData.isPresent()) {
474 IpPortMap ipPortMapInstance = ipPortMapData.get();
475 return ipPortMapInstance.getIpPortExternal();
480 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, String internalPort , ProtocolTypes protocolType) {
481 InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class).child
482 (IpPortMapping.class, new IpPortMappingKey(routerId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
483 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
487 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
488 BigInteger cookie, List<MatchInfo> listMatchInfo) {
490 FlowEntity flowEntity = new FlowEntity(dpnId);
491 flowEntity.setTableId(tableId);
492 flowEntity.setFlowId(flowId);
493 flowEntity.setPriority(priority);
494 flowEntity.setFlowName(flowName);
495 flowEntity.setCookie(cookie);
496 flowEntity.setMatchInfoList(listMatchInfo);
500 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName)
502 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
503 Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
505 if (configuredVpnInterface.isPresent()) {
511 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
512 return InstanceIdentifier.builder(VpnInterfaces.class)
513 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
516 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
517 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
518 Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
520 if (configuredVpnInterface.isPresent()) {
521 return configuredVpnInterface.get();
526 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
528 * NodeConnectorId is of form 'openflow:dpnid:portnum'
530 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
534 public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
535 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
536 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
537 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
547 description "vpn-id";
551 description "vpn name";
555 description "The UUID of the tenant that will own the subnet.";
560 description "UUID of router ";
562 leaf-list network_ids {
564 description "UUID representing the network ";
568 Method returns router Id associated to a VPN
571 public static String getRouterIdfromVpnId(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 = read(broker, LogicalDatastoreType.CONFIGURATION,
576 if (optionalVpnMap.isPresent()) {
577 return optionalVpnMap.get().getRouterId().getValue();
582 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
583 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
584 Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
586 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
587 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
588 if (routerId != null) {
589 for (VpnMap vpnMap : allMaps) {
590 if (vpnMap.getRouterId() != null &&
591 routerId.equals(vpnMap.getRouterId().getValue()) &&
592 !routerId.equals(vpnMap.getVpnId().getValue())) {
593 return vpnMap.getVpnId();
601 static long getAssociatedVpn(DataBroker broker, String routerName) {
602 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
603 Optional<Routermapping> optRouterMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
604 if(optRouterMapping.isPresent()) {
605 Routermapping routerMapping = optRouterMapping.get();
606 return routerMapping.getVpnId();
608 return NatConstants.INVALID_ID;
612 public static List<VpnToDpnList> getVpnToDpnList(DataBroker dataBroker, String vrfId )
614 List<VpnToDpnList> vpnDpnList = null;
616 InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier
617 .builder(VpnInstanceOpData.class)
618 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId))
621 Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
623 if(vpnInstanceOpData.isPresent())
625 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnInstanceOpData.get();
626 vpnDpnList = vpnInstanceOpDataEntry.getVpnToDpnList();
632 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
633 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
634 if(vpnUuid == null ){
635 log.error("No VPN instance associated with ext network {}", networkId);
638 return vpnUuid.getValue();
641 public static void addPrefixToBGP(IBgpManager bgpManager, String rd, String prefix, String nextHopIp, long label, Logger log) {
643 bgpManager.addPrefix(rd, prefix, nextHopIp, (int)label);
644 } catch(Exception e) {
645 log.error("Add prefix failed", e);
649 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
650 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class).child
651 (RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
655 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
656 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class).child
657 (RouterPorts.class, new RouterPortsKey(routerId)).build();
658 return routerInstanceIndentifier;
661 /* container snatint-ip-port-map {
662 list intip-port-map {
664 leaf router-id { type uint32; }
667 leaf internal-ip { type string; }
668 list int-ip-proto-type {
670 leaf protocol { type protocol-types; }
671 leaf-list ports { type uint16; }
676 Method returns InternalIp port List
679 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker,Long routerId, String internalIpAddress, ProtocolTypes protocolType){
680 Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
681 if (optionalIpProtoType.isPresent()) {
682 return optionalIpProtoType.get().getPorts();
687 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId, String internalIpAddress, ProtocolTypes protocolType) {
688 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId = InstanceIdentifier.builder(SnatintIpPortMap.class).child
689 (IntipPortMap.class, new IntipPortMapKey(routerId)).child(IpPort.class, new IpPortKey(internalIpAddress)).child
690 (IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
691 return intIpProtocolTypeId;
694 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
695 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString()) ? ProtocolTypes.TCP : ProtocolTypes.UDP;
699 public static NaptSwitches getNaptSwitch(DataBroker broker) {
700 Optional<NaptSwitches> switchesOptional = read(broker, LogicalDatastoreType.OPERATIONAL, getNaptSwitchesIdentifier());
701 if(switchesOptional.isPresent()) {
702 return switchesOptional.get();
707 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
708 return InstanceIdentifier.create(NaptSwitches.class);
711 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
712 return InstanceIdentifier.create(NaptSwitches.class).child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
715 public static String toStringIpAddress(byte[] ipAddress, Logger log)
718 if (ipAddress == null) {
723 ip = InetAddress.getByAddress(ipAddress).getHostAddress();
724 } catch(UnknownHostException e) {
725 log.error("NAT Service : Caught exception during toStringIpAddress()");
731 public static String getGroupIdKey(String routerName){
732 String groupIdKey = new String("snatmiss." + routerName);
736 public static long createGroupId(String groupIdKey,IdManagerService idManager) {
737 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
738 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
741 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
742 RpcResult<AllocateIdOutput> rpcResult = result.get();
743 return rpcResult.getResult().getIdValue();
744 } catch (NullPointerException | InterruptedException | ExecutionException e) {
750 public static void removePrefixFromBGP(IBgpManager bgpManager, String rd, String prefix, Logger log) {
752 bgpManager.deletePrefix(rd, prefix);
753 } catch(Exception e) {
754 log.error("Delete prefix failed", e);
758 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
759 FlowEntity flowEntity = new FlowEntity(dpnId);
760 flowEntity.setTableId(tableId);
761 flowEntity.setCookie(cookie);
762 flowEntity.setFlowId(flowId);
766 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
767 FlowEntity flowEntity = new FlowEntity(dpnId);
768 flowEntity.setTableId(tableId);
769 flowEntity.setFlowId(flowId);
773 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
774 Optional<IpPortMapping> getIportMappingData = read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId));
775 if(getIportMappingData.isPresent()) {
776 return getIportMappingData.get();
781 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
782 return InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
785 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
786 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
787 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMapping.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMappingKey(routerId)).build();
791 public static List<String> getExternalIpsForRouter(DataBroker dataBroker,Long routerId) {
792 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
793 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
794 List<String> externalIps = new ArrayList<>();
795 if (ipMappingOptional.isPresent()) {
796 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
797 for (IpMap ipMap : ipMaps) {
798 externalIps.add(ipMap.getExternalIp());
806 container external-ips-counter {
808 list external-counters{
810 leaf segment-id { type uint32; }
811 list external-ip-counter {
813 leaf external-ip { type string; }
814 leaf counter { type uint8; }
820 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId){
821 String leastLoadedExternalIp = null;
822 InstanceIdentifier<ExternalCounters> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
823 Optional <ExternalCounters> externalCountersData = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
824 if (externalCountersData.isPresent()) {
825 ExternalCounters externalCounter = externalCountersData.get();
826 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
827 short countOfLstLoadExtIp = 32767;
828 for(ExternalIpCounter externalIpCounter : externalIpCounterList){
829 String curExternalIp = externalIpCounter.getExternalIp();
830 short countOfCurExtIp = externalIpCounter.getCounter();
831 if( countOfCurExtIp < countOfLstLoadExtIp ){
832 countOfLstLoadExtIp = countOfCurExtIp;
833 leastLoadedExternalIp = curExternalIp;
837 return leastLoadedExternalIp;
840 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId){
841 String subnetIP = getSubnetIp(dataBroker, subnetId);
842 if(subnetId != null){
843 return getSubnetIpAndPrefix(subnetIP);
848 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId){
849 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
850 .builder(Subnetmaps.class)
851 .child(Subnetmap.class, new SubnetmapKey(subnetId))
853 Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
854 if(removedSubnet.isPresent()) {
855 Subnetmap subnetMapEntry = removedSubnet.get();
856 return subnetMapEntry.getSubnetIp();
861 public static String[] getSubnetIpAndPrefix(String subnetString){
862 String[] subnetSplit = subnetString.split("/");
863 String subnetIp = subnetSplit[0];
864 String subnetPrefix = "0";
865 if (subnetSplit.length == 2) {
866 subnetPrefix = subnetSplit[1];
868 return new String[] {subnetIp, subnetPrefix};
871 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr){
872 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
873 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
874 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
875 if (leastLoadedExtIpAddrSplit.length == 2) {
876 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
878 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
881 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid){
882 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class).child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
883 Optional<RouterDpnList> routerDpnListData = read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
884 List<BigInteger> dpns = new ArrayList<>();
885 if (routerDpnListData.isPresent()) {
886 List<DpnVpninterfacesList> dpnVpninterfacesList = routerDpnListData.get().getDpnVpninterfacesList();
887 for (DpnVpninterfacesList dpnVpnInterface : dpnVpninterfacesList) {
888 dpns.add(dpnVpnInterface.getDpnId());
895 public static long getBgpVpnId(DataBroker dataBroker, String routerName){
896 long bgpVpnId = NatConstants.INVALID_ID;
897 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
898 if(bgpVpnUuid != null){
899 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());