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;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.HashMap;
15 import java.util.List;
17 import com.google.common.collect.Lists;
18 import com.google.common.collect.Sets;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.genius.mdsalutil.NwConstants;
23 import org.opendaylight.genius.mdsalutil.FlowEntity;
24 import org.opendaylight.genius.mdsalutil.MatchInfo;
25 import org.opendaylight.netvirt.bgpmanager.api.RouteOrigin;
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.genius.idmanager.rev160406.AllocateIdInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.*;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.RoutersKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCounters;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.ExternalCountersKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.ips.counter.external.counters.ExternalIpCounter;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.ip.mapping.IpMap;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolTypeKey;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMapKey;
47 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;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIds;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.id.name.RouterIdsKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.RouterToVpnMapping;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.Routermapping;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.router.to.vpn.mapping.RoutermappingKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMap;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.IntipPortMapKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPort;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.FloatingIpInfo;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.NeutronRouterDpns;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
70 import org.opendaylight.yangtools.yang.binding.DataObject;
71 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
72 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
73 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
75 import com.google.common.base.Optional;
77 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
78 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.Networks;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPorts;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.RouterPortsKey;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.PortsKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExternalNetworks;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfoKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMapping;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.IpMappingKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.IntextIpPortMap;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMappingKey;
100 import org.opendaylight.yangtools.yang.common.RpcResult;
101 import org.slf4j.Logger;
102 import org.slf4j.LoggerFactory;
104 import java.net.InetAddress;
105 import java.net.UnknownHostException;
106 import java.util.Set;
107 import java.util.concurrent.ExecutionException;
108 import java.util.concurrent.Future;
112 public class NatUtil {
114 private static String OF_URI_SEPARATOR = ":";
115 private static final Logger LOG = LoggerFactory.getLogger(NatUtil.class);
118 getCookieSnatFlow() computes and returns a unique cookie value for the NAT flows using the router ID as the reference value.
120 public static BigInteger getCookieSnatFlow(long routerId) {
121 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0110000", 16)).add(
122 BigInteger.valueOf(routerId));
126 getCookieNaptFlow() computes and returns a unique cookie value for the NAPT flows using the router ID as the reference value.
128 public static BigInteger getCookieNaptFlow(long routerId) {
129 return NatConstants.COOKIE_NAPT_BASE.add(new BigInteger("0111000", 16)).add(
130 BigInteger.valueOf(routerId));
134 getVpnId() returns the VPN ID from the VPN name
136 public static long getVpnId(DataBroker broker, String vpnName) {
137 if(vpnName == null) {
138 return NatConstants.INVALID_ID;
141 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
142 = getVpnInstanceToVpnIdIdentifier(vpnName);
143 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
144 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
147 long vpnId = NatConstants.INVALID_ID;
148 if(vpnInstance.isPresent()) {
149 Long vpnIdAsLong = vpnInstance.get().getVpnId();
150 if(vpnIdAsLong != null){
157 public static Long getVpnId(DataBroker broker, long routerId){
158 //Get the external network ID from the ExternalRouter model
159 Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
160 if(networkId == null ){
161 LOG.error("NAT Service : networkId is null");
165 //Get the VPN ID from the ExternalNetworks model
166 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(broker, networkId);
167 if(vpnUuid == null ){
168 LOG.error("NAT Service : vpnUuid is null");
171 Long vpnId = NatUtil.getVpnId(broker, vpnUuid.getValue());
175 static InstanceIdentifier<RouterPorts> getRouterPortsId(String routerId) {
176 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId)).build();
179 static InstanceIdentifier<Routermapping> getRouterVpnMappingId(String routerId) {
180 return InstanceIdentifier.builder(RouterToVpnMapping.class).child(Routermapping.class, new RoutermappingKey(routerId)).build();
183 static InstanceIdentifier<Ports> getPortsIdentifier(String routerId, String portName) {
184 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
185 .child(Ports.class, new PortsKey(portName)).build();
188 static InstanceIdentifier<IpMapping> getIpMappingIdentifier(String routerId, String portName, String internalIp) {
189 return InstanceIdentifier.builder(FloatingIpInfo.class).child(RouterPorts.class, new RouterPortsKey(routerId))
190 .child(Ports.class, new PortsKey(portName))
191 .child(IpMapping.class, new IpMappingKey(internalIp)).build();
195 getVpnInstanceToVpnIdIdentifier() returns the VPN instance from the below model using the VPN name as the key.
197 key "vpn-instance-name"
198 leaf vpn-instance-name {
210 static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
211 getVpnInstanceToVpnIdIdentifier(String vpnName) {
212 return InstanceIdentifier.builder(VpnInstanceToVpnId.class)
213 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance.class,
214 new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstanceKey(vpnName)).build();
218 getFlowRef() returns a string identfier for the SNAT flows using the router ID as the reference.
220 public static String getFlowRef(BigInteger dpnId, short tableId, long routerID, String ip) {
221 return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
222 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID)
223 .append(NatConstants.FLOWID_SEPARATOR).append(ip).toString();
226 public static String getNaptFlowRef(BigInteger dpnId, short tableId, String routerID, String ip, int port) {
227 return new StringBuffer().append(NatConstants.NAPT_FLOWID_PREFIX).append(dpnId).append(NatConstants.FLOWID_SEPARATOR).
228 append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).append(NatConstants.FLOWID_SEPARATOR).append(ip).
229 append(NatConstants.FLOWID_SEPARATOR).append(port).toString();
233 getNetworkIdFromRouterId() returns the network-id from the below model using the router-id as the key
234 container ext-routers {
237 leaf router-name { type string; }
238 leaf network-id { type yang:uuid; }
239 leaf enable-snat { type boolean; }
240 leaf-list external-ips {
241 type string; //format - ipaddress\prefixlength
243 leaf-list subnet-ids { type yang:uuid; }
248 static Uuid getNetworkIdFromRouterId(DataBroker broker, long routerId) {
249 String routerName = getRouterName(broker, routerId);
250 InstanceIdentifier id = buildRouterIdentifier(routerName);
251 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
252 if (routerData.isPresent()) {
253 return routerData.get().getNetworkId();
258 static InstanceIdentifier<Routers> buildRouterIdentifier(String routerId) {
259 InstanceIdentifier<Routers> routerInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class).child
260 (Routers.class, new RoutersKey(routerId)).build();
261 return routerInstanceIndentifier;
265 * getEnableSnatFromRouterId() returns IsSnatEnabled true is routerID is present in external n/w otherwise returns false
267 static boolean isSnatEnabledForRouterId(DataBroker broker, String routerId){
268 InstanceIdentifier id = buildRouterIdentifier(routerId);
269 Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
270 if (routerData.isPresent()) {
271 return routerData.get().isEnableSnat();
276 getVpnIdfromNetworkId() returns the vpnid from the below model using the network ID as the key.
277 container external-networks {
283 leaf vpnid { type yang:uuid; }
284 leaf-list router-ids { type yang:uuid; }
285 leaf-list subnet-ids{ type yang:uuid; }
289 public static Uuid getVpnIdfromNetworkId(DataBroker broker, Uuid networkId) {
290 InstanceIdentifier id = buildNetworkIdentifier(networkId);
291 Optional<Networks> networkData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
292 if (networkData.isPresent()) {
293 return networkData.get().getVpnid();
298 static String getAssociatedExternalNetwork(DataBroker dataBroker, String routerId) {
299 InstanceIdentifier<Routers> id = NatUtil.buildRouterIdentifier(routerId);
300 Optional<Routers> routerData = NatUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION, id);
301 if (routerData.isPresent()) {
302 Uuid networkId = routerData.get().getNetworkId();
303 if(networkId != null) {
304 return networkId.getValue();
310 private static InstanceIdentifier<Networks> buildNetworkIdentifier(Uuid networkId) {
311 InstanceIdentifier<Networks> network = InstanceIdentifier.builder(ExternalNetworks.class).child
312 (Networks.class, new NetworksKey(networkId)).build();
320 getNaptSwitchesDpnIdsfromRouterId() returns the primary-switch-id and the secondary-switch-id in a array using the router-id; as the key.
321 container napt-switches {
322 list router-to-napt-switch {
324 leaf router-id { type uint32; }
325 leaf primary-switch-id { type uint64; }
326 leaf secondary-switch-id { type uint64; }
330 public static BigInteger getPrimaryNaptfromRouterId(DataBroker broker, Long routerId) {
331 // convert routerId to Name
332 String routerName = getRouterName(broker, routerId);
333 InstanceIdentifier id = buildNaptSwitchIdentifier(routerName);
334 Optional<RouterToNaptSwitch> routerToNaptSwitchData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
335 if (routerToNaptSwitchData.isPresent()) {
336 RouterToNaptSwitch routerToNaptSwitchInstance = routerToNaptSwitchData.get();
337 return routerToNaptSwitchInstance.getPrimarySwitchId();
342 private static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchIdentifier(String routerId) {
343 InstanceIdentifier<RouterToNaptSwitch> rtrNaptSw = InstanceIdentifier.builder(NaptSwitches.class).child
344 (RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId)).build();
348 public static String getRouterName(DataBroker broker, Long routerId) {
349 InstanceIdentifier id = buildRouterIdentifier(routerId);
350 Optional<RouterIds> routerIdsData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
351 if (routerIdsData.isPresent()) {
352 RouterIds routerIdsInstance = routerIdsData.get();
353 return routerIdsInstance.getRouterName();
358 private static InstanceIdentifier<RouterIds> buildRouterIdentifier(Long routerId) {
359 InstanceIdentifier<RouterIds> routerIds = InstanceIdentifier.builder(RouterIdName.class).child
360 (RouterIds.class, new RouterIdsKey(routerId)).build();
364 public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
365 InstanceIdentifier<T> path) {
367 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
369 Optional<T> result = Optional.absent();
371 result = tx.read(datastoreType, path).get();
372 } catch (Exception e) {
373 throw new RuntimeException(e);
379 static InstanceIdentifier<VpnInstanceOpDataEntry> getVpnInstanceOpDataIdentifier(String vrfId) {
380 return InstanceIdentifier.builder(VpnInstanceOpData.class)
381 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId)).build();
384 public static long readVpnId(DataBroker broker, String vpnName) {
386 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
387 = getVpnInstanceToVpnIdIdentifier(vpnName);
388 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
389 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
391 long vpnId = NatConstants.INVALID_ID;
392 if(vpnInstance.isPresent()) {
393 vpnId = vpnInstance.get().getVpnId();
398 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie) {
399 FlowEntity flowEntity = new FlowEntity(dpnId);
400 flowEntity.setTableId(tableId);
401 flowEntity.setCookie(cookie);
405 public static long getIpAddress(byte[] rawIpAddress) {
406 return (((rawIpAddress[0] & 0xFF) << (3 * 8)) + ((rawIpAddress[1] & 0xFF) << (2 * 8))
407 + ((rawIpAddress[2] & 0xFF) << (1 * 8)) + (rawIpAddress[3] & 0xFF)) & 0xffffffffL;
410 public static String getFlowRef(BigInteger dpnId, short tableId, InetAddress destPrefix) {
411 return new StringBuilder(64).append(NatConstants.FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
412 .append(tableId).append(NwConstants.FLOWID_SEPARATOR)
413 .append(destPrefix.getHostAddress()).toString();
416 public static String getEndpointIpAddressForDPN(DataBroker broker, BigInteger dpnId) {
417 String nextHopIp = null;
418 InstanceIdentifier<DPNTEPsInfo> tunnelInfoId =
419 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, new DPNTEPsInfoKey(dpnId)).build();
420 Optional<DPNTEPsInfo> tunnelInfo = read(broker, LogicalDatastoreType.CONFIGURATION, tunnelInfoId);
421 if (tunnelInfo.isPresent()) {
422 List<TunnelEndPoints> nexthopIpList = tunnelInfo.get().getTunnelEndPoints();
423 if (nexthopIpList != null && !nexthopIpList.isEmpty()) {
424 nextHopIp = nexthopIpList.get(0).getIpAddress().getIpv4Address().getValue();
431 getVpnRd returns the rd (route distinguisher) which is the VRF ID from the below model using the vpnName
433 key "vpn-instance-name"
434 leaf vpn-instance-name {
445 public static String getVpnRd(DataBroker broker, String vpnName) {
447 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> id
448 = getVpnInstanceToVpnIdIdentifier(vpnName);
449 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
450 = read(broker, LogicalDatastoreType.CONFIGURATION, id);
453 if(vpnInstance.isPresent()) {
454 rd = vpnInstance.get().getVrfId();
459 /* getExternalIPPortMap() returns the internal IP and the port for the querried router ID, external IP and the port.
460 container intext-ip-port-map {
462 list ip-port-mapping {
464 leaf router-id { type uint32; }
465 list intext-ip-protocol-type {
467 leaf protocol { type protocol-types; }
469 key ip-port-internal;
470 description "internal to external ip-port mapping";
471 leaf ip-port-internal { type string; }
472 container ip-port-external {
480 public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress, String internalPort, NAPTEntryEvent.Protocol protocol) {
481 ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
482 InstanceIdentifier ipPortMapId = buildIpToPortMapIdentifier(routerId, internalIpAddress, internalPort, protocolType);
483 Optional<IpPortMap> ipPortMapData = read(broker, LogicalDatastoreType.CONFIGURATION, ipPortMapId);
484 if (ipPortMapData.isPresent()) {
485 IpPortMap ipPortMapInstance = ipPortMapData.get();
486 return ipPortMapInstance.getIpPortExternal();
491 private static InstanceIdentifier<IpPortMap> buildIpToPortMapIdentifier(Long routerId, String internalIpAddress, String internalPort , ProtocolTypes protocolType) {
492 InstanceIdentifier<IpPortMap> ipPortMapId = InstanceIdentifier.builder(IntextIpPortMap.class).child
493 (IpPortMapping.class, new IpPortMappingKey(routerId)).child(IntextIpProtocolType.class, new IntextIpProtocolTypeKey(protocolType))
494 .child(IpPortMap.class, new IpPortMapKey(internalIpAddress + ":" + internalPort)).build();
498 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId, int priority, String flowName,
499 BigInteger cookie, List<MatchInfo> listMatchInfo) {
501 FlowEntity flowEntity = new FlowEntity(dpnId);
502 flowEntity.setTableId(tableId);
503 flowEntity.setFlowId(flowId);
504 flowEntity.setPriority(priority);
505 flowEntity.setFlowName(flowName);
506 flowEntity.setCookie(cookie);
507 flowEntity.setMatchInfoList(listMatchInfo);
511 static boolean isVpnInterfaceConfigured(DataBroker broker, String interfaceName)
513 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
514 Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
516 if (configuredVpnInterface.isPresent()) {
522 static InstanceIdentifier<VpnInterface> getVpnInterfaceIdentifier(String vpnInterfaceName) {
523 return InstanceIdentifier.builder(VpnInterfaces.class)
524 .child(VpnInterface.class, new VpnInterfaceKey(vpnInterfaceName)).build();
527 static VpnInterface getConfiguredVpnInterface(DataBroker broker, String interfaceName) {
528 InstanceIdentifier<VpnInterface> interfaceId = getVpnInterfaceIdentifier(interfaceName);
529 Optional<VpnInterface> configuredVpnInterface = read(broker, LogicalDatastoreType.CONFIGURATION, interfaceId);
531 if (configuredVpnInterface.isPresent()) {
532 return configuredVpnInterface.get();
537 public static String getDpnFromNodeConnectorId(NodeConnectorId portId) {
539 * NodeConnectorId is of form 'openflow:dpnid:portnum'
541 String[] split = portId.getValue().split(OF_URI_SEPARATOR);
545 public static BigInteger getDpIdFromInterface(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface ifState) {
546 String lowerLayerIf = ifState.getLowerLayerIf().get(0);
547 NodeConnectorId nodeConnectorId = new NodeConnectorId(lowerLayerIf);
548 return new BigInteger(getDpnFromNodeConnectorId(nodeConnectorId));
558 description "vpn-id";
562 description "vpn name";
566 description "The UUID of the tenant that will own the subnet.";
571 description "UUID of router ";
573 leaf-list network_ids {
575 description "UUID representing the network ";
579 Method returns router Id associated to a VPN
582 public static String getRouterIdfromVpnId(DataBroker broker,String vpnName){
583 InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
584 .child(VpnMap.class, new VpnMapKey(new Uuid(vpnName))).build();
585 Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION,
587 if (optionalVpnMap.isPresent()) {
588 return optionalVpnMap.get().getRouterId().getValue();
593 static Uuid getVpnForRouter(DataBroker broker, String routerId) {
594 InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
595 Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
597 if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
598 List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
599 if (routerId != null) {
600 for (VpnMap vpnMap : allMaps) {
601 if (vpnMap.getRouterId() != null &&
602 routerId.equals(vpnMap.getRouterId().getValue()) &&
603 !routerId.equals(vpnMap.getVpnId().getValue())) {
604 return vpnMap.getVpnId();
612 static long getAssociatedVpn(DataBroker broker, String routerName) {
613 InstanceIdentifier<Routermapping> routerMappingId = NatUtil.getRouterVpnMappingId(routerName);
614 Optional<Routermapping> optRouterMapping = NatUtil.read(broker, LogicalDatastoreType.OPERATIONAL, routerMappingId);
615 if(optRouterMapping.isPresent()) {
616 Routermapping routerMapping = optRouterMapping.get();
617 return routerMapping.getVpnId();
619 return NatConstants.INVALID_ID;
623 public static List<VpnToDpnList> getVpnToDpnList(DataBroker dataBroker, String vrfId )
625 List<VpnToDpnList> vpnDpnList = null;
627 InstanceIdentifier<VpnInstanceOpDataEntry> id = InstanceIdentifier
628 .builder(VpnInstanceOpData.class)
629 .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vrfId))
632 Optional<VpnInstanceOpDataEntry> vpnInstanceOpData = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
634 if(vpnInstanceOpData.isPresent())
636 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnInstanceOpData.get();
637 vpnDpnList = vpnInstanceOpDataEntry.getVpnToDpnList();
643 public static String getAssociatedVPN(DataBroker dataBroker, Uuid networkId, Logger log) {
644 Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
645 if(vpnUuid == null ){
646 log.error("No VPN instance associated with ext network {}", networkId);
649 return vpnUuid.getValue();
652 public static void addPrefixToBGP(IBgpManager bgpManager, String rd, String prefix, List<String> nextHopIpList,
653 long label, Logger log, RouteOrigin origin) {
655 LOG.info("ADD: Adding Fib Entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHopIpList, label);
656 bgpManager.addPrefix(rd, prefix, nextHopIpList, (int)label, origin);
657 LOG.info("ADD: Added Fib Entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHopIpList, label);
658 } catch(Exception e) {
659 log.error("Add prefix failed", e);
663 static InstanceIdentifier<Ports> buildPortToIpMapIdentifier(String routerId, String portName) {
664 InstanceIdentifier<Ports> ipPortMapId = InstanceIdentifier.builder(FloatingIpInfo.class).child
665 (RouterPorts.class, new RouterPortsKey(routerId)).child(Ports.class, new PortsKey(portName)).build();
669 static InstanceIdentifier<RouterPorts> buildRouterPortsIdentifier(String routerId) {
670 InstanceIdentifier<RouterPorts> routerInstanceIndentifier = InstanceIdentifier.builder(FloatingIpInfo.class).child
671 (RouterPorts.class, new RouterPortsKey(routerId)).build();
672 return routerInstanceIndentifier;
675 /* container snatint-ip-port-map {
676 list intip-port-map {
678 leaf router-id { type uint32; }
681 leaf internal-ip { type string; }
682 list int-ip-proto-type {
684 leaf protocol { type protocol-types; }
685 leaf-list ports { type uint16; }
690 Method returns InternalIp port List
693 public static List<Integer> getInternalIpPortListInfo(DataBroker dataBroker,Long routerId, String internalIpAddress, ProtocolTypes protocolType){
694 Optional<IntIpProtoType> optionalIpProtoType = read(dataBroker, LogicalDatastoreType.CONFIGURATION, buildSnatIntIpPortIdentifier(routerId, internalIpAddress, protocolType));
695 if (optionalIpProtoType.isPresent()) {
696 return optionalIpProtoType.get().getPorts();
701 public static InstanceIdentifier<IntIpProtoType> buildSnatIntIpPortIdentifier(Long routerId, String internalIpAddress, ProtocolTypes protocolType) {
702 InstanceIdentifier<IntIpProtoType> intIpProtocolTypeId = InstanceIdentifier.builder(SnatintIpPortMap.class).child
703 (IntipPortMap.class, new IntipPortMapKey(routerId)).child(IpPort.class, new IpPortKey(internalIpAddress)).child
704 (IntIpProtoType.class, new IntIpProtoTypeKey(protocolType)).build();
705 return intIpProtocolTypeId;
708 public static ProtocolTypes getProtocolType(NAPTEntryEvent.Protocol protocol) {
709 ProtocolTypes protocolType = ProtocolTypes.TCP.toString().equals(protocol.toString()) ? ProtocolTypes.TCP : ProtocolTypes.UDP;
713 public static NaptSwitches getNaptSwitch(DataBroker broker) {
714 Optional<NaptSwitches> switchesOptional = read(broker, LogicalDatastoreType.CONFIGURATION, getNaptSwitchesIdentifier());
715 if(switchesOptional.isPresent()) {
716 return switchesOptional.get();
721 public static InstanceIdentifier<NaptSwitches> getNaptSwitchesIdentifier() {
722 return InstanceIdentifier.create(NaptSwitches.class);
725 public static InstanceIdentifier<RouterToNaptSwitch> buildNaptSwitchRouterIdentifier(String routerId) {
726 return InstanceIdentifier.create(NaptSwitches.class).child(RouterToNaptSwitch.class, new RouterToNaptSwitchKey(routerId));
729 public static String toStringIpAddress(byte[] ipAddress, Logger log)
732 if (ipAddress == null) {
737 ip = InetAddress.getByAddress(ipAddress).getHostAddress();
738 } catch(UnknownHostException e) {
739 log.error("NAT Service : Caught exception during toStringIpAddress()");
745 public static String getGroupIdKey(String routerName){
746 String groupIdKey = new String("snatmiss." + routerName);
750 public static long createGroupId(String groupIdKey,IdManagerService idManager) {
751 AllocateIdInput getIdInput = new AllocateIdInputBuilder()
752 .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
755 Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
756 RpcResult<AllocateIdOutput> rpcResult = result.get();
757 return rpcResult.getResult().getIdValue();
758 } catch (NullPointerException | InterruptedException | ExecutionException e) {
764 public static void removePrefixFromBGP(IBgpManager bgpManager, String rd, String prefix, Logger log) {
766 LOG.info("REMOVE: Removing Fib Entry rd {} prefix {}", rd, prefix);
767 bgpManager.deletePrefix(rd, prefix);
768 LOG.info("REMOVE: Removed Fib Entry rd {} prefix {}", rd, prefix);
769 } catch(Exception e) {
770 log.error("Delete prefix failed", e);
774 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, BigInteger cookie, String flowId) {
775 FlowEntity flowEntity = new FlowEntity(dpnId);
776 flowEntity.setTableId(tableId);
777 flowEntity.setCookie(cookie);
778 flowEntity.setFlowId(flowId);
782 public static FlowEntity buildFlowEntity(BigInteger dpnId, short tableId, String flowId) {
783 FlowEntity flowEntity = new FlowEntity(dpnId);
784 flowEntity.setTableId(tableId);
785 flowEntity.setFlowId(flowId);
789 public static IpPortMapping getIportMapping(DataBroker broker, long routerId) {
790 Optional<IpPortMapping> getIportMappingData = read(broker, LogicalDatastoreType.CONFIGURATION, getIportMappingIdentifier(routerId));
791 if(getIportMappingData.isPresent()) {
792 return getIportMappingData.get();
797 public static InstanceIdentifier<IpPortMapping> getIportMappingIdentifier(long routerId) {
798 return InstanceIdentifier.builder(IntextIpPortMap.class).child(IpPortMapping.class, new IpPortMappingKey(routerId)).build();
801 public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> getIpMappingBuilder(Long routerId) {
802 InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> idBuilder = InstanceIdentifier.builder(IntextIpMap.class)
803 .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();
807 public static List<String> getExternalIpsForRouter(DataBroker dataBroker,Long routerId) {
808 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
809 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
810 List<String> externalIps = new ArrayList<>();
811 if (ipMappingOptional.isPresent()) {
812 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
813 for (IpMap ipMap : ipMaps) {
814 externalIps.add(ipMap.getExternalIp());
817 Set<String> uniqueExternalIps = Sets.newHashSet(externalIps);
818 externalIps = Lists.newArrayList(uniqueExternalIps);
824 public static HashMap<String,Long> getExternalIpsLabelForRouter(DataBroker dataBroker,Long routerId) {
825 Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.map.IpMapping> ipMappingOptional = read(dataBroker,
826 LogicalDatastoreType.OPERATIONAL, getIpMappingBuilder(routerId));
827 HashMap<String,Long> externalIpsLabel = new HashMap<>();
828 if (ipMappingOptional.isPresent()) {
829 List<IpMap> ipMaps = ipMappingOptional.get().getIpMap();
830 for (IpMap ipMap : ipMaps) {
831 externalIpsLabel.put(ipMap.getExternalIp(), ipMap.getLabel());
833 return externalIpsLabel;
838 container external-ips-counter {
840 list external-counters{
842 leaf segment-id { type uint32; }
843 list external-ip-counter {
845 leaf external-ip { type string; }
846 leaf counter { type uint8; }
852 public static String getLeastLoadedExternalIp(DataBroker dataBroker, long segmentId){
853 String leastLoadedExternalIp = null;
854 InstanceIdentifier<ExternalCounters> id = InstanceIdentifier.builder(ExternalIpsCounter.class).child(ExternalCounters.class, new ExternalCountersKey(segmentId)).build();
855 Optional <ExternalCounters> externalCountersData = MDSALUtil.read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
856 if (externalCountersData.isPresent()) {
857 ExternalCounters externalCounter = externalCountersData.get();
858 List<ExternalIpCounter> externalIpCounterList = externalCounter.getExternalIpCounter();
859 short countOfLstLoadExtIp = 32767;
860 for(ExternalIpCounter externalIpCounter : externalIpCounterList){
861 String curExternalIp = externalIpCounter.getExternalIp();
862 short countOfCurExtIp = externalIpCounter.getCounter();
863 if( countOfCurExtIp < countOfLstLoadExtIp ){
864 countOfLstLoadExtIp = countOfCurExtIp;
865 leastLoadedExternalIp = curExternalIp;
869 return leastLoadedExternalIp;
872 public static String[] getSubnetIpAndPrefix(DataBroker dataBroker, Uuid subnetId){
873 String subnetIP = getSubnetIp(dataBroker, subnetId);
874 if(subnetId != null){
875 return getSubnetIpAndPrefix(subnetIP);
880 public static String getSubnetIp(DataBroker dataBroker, Uuid subnetId){
881 InstanceIdentifier<Subnetmap> subnetmapId = InstanceIdentifier
882 .builder(Subnetmaps.class)
883 .child(Subnetmap.class, new SubnetmapKey(subnetId))
885 Optional<Subnetmap> removedSubnet = read(dataBroker, LogicalDatastoreType.CONFIGURATION, subnetmapId);
886 if(removedSubnet.isPresent()) {
887 Subnetmap subnetMapEntry = removedSubnet.get();
888 return subnetMapEntry.getSubnetIp();
893 public static String[] getSubnetIpAndPrefix(String subnetString){
894 String[] subnetSplit = subnetString.split("/");
895 String subnetIp = subnetSplit[0];
896 String subnetPrefix = "0";
897 if (subnetSplit.length == 2) {
898 subnetPrefix = subnetSplit[1];
900 return new String[] {subnetIp, subnetPrefix};
903 public static String[] getExternalIpAndPrefix(String leastLoadedExtIpAddr){
904 String[] leastLoadedExtIpAddrSplit = leastLoadedExtIpAddr.split("/");
905 String leastLoadedExtIp = leastLoadedExtIpAddrSplit[0];
906 String leastLoadedExtIpPrefix = String.valueOf(NatConstants.DEFAULT_PREFIX);
907 if (leastLoadedExtIpAddrSplit.length == 2) {
908 leastLoadedExtIpPrefix = leastLoadedExtIpAddrSplit[1];
910 return new String[] {leastLoadedExtIp, leastLoadedExtIpPrefix};
913 public static List<BigInteger> getDpnsForRouter(DataBroker dataBroker, String routerUuid){
914 InstanceIdentifier id = InstanceIdentifier.builder(NeutronRouterDpns.class).child(RouterDpnList.class, new RouterDpnListKey(routerUuid)).build();
915 Optional<RouterDpnList> routerDpnListData = read(dataBroker, 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());
927 public static long getBgpVpnId(DataBroker dataBroker, String routerName){
928 long bgpVpnId = NatConstants.INVALID_ID;
929 Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
930 if(bgpVpnUuid != null){
931 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());