Bug 7780 : NAT RPC's for getting SNAT/DNAT translation information. 93/52093/6
authorcgowdru <chetan.arakere@altencalsoftlabs.com>
Mon, 13 Feb 2017 08:07:38 +0000 (13:37 +0530)
committerVivekanandan Narasimhan <n.vivekanandan@ericsson.com>
Sun, 26 Feb 2017 16:44:41 +0000 (16:44 +0000)
Description : With the Current DS structure, it's is bit difficult to
identify information about what is the current DNAT/SNAT configuration
done fo the given router-uuid/vpn-uuid.

It would be good if we have a RPC's which can provide a information as
below.

input- router-uuid/vpn-uuid

SNAT output - router-name, internal-ip/port, external-ip/port,protocol
DNAT output - router-name,internal-ip,floating-ip

Change-Id: I00b6576d2a752b53e94ad28c611a06794c65456c
Signed-off-by: cgowdru <chetan.arakere@altencalsoftlabs.com>
vpnservice/natservice/natservice-api/src/main/yang/odl-nat-rpc.yang [new file with mode: 0644]
vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/rpcservice/NatRpcServiceImpl.java [new file with mode: 0644]
vpnservice/natservice/natservice-impl/src/main/resources/org/opendaylight/blueprint/natservice.xml

diff --git a/vpnservice/natservice/natservice-api/src/main/yang/odl-nat-rpc.yang b/vpnservice/natservice/natservice-api/src/main/yang/odl-nat-rpc.yang
new file mode 100644 (file)
index 0000000..68628a9
--- /dev/null
@@ -0,0 +1,233 @@
+module odl-nat-rpc {
+    namespace "urn:opendaylight:netvirt:natservice:rpc";
+    prefix odl-nat-rpc;
+
+    import ietf-yang-types { prefix "yang"; }
+    import ietf-inet-types {
+        prefix inet;
+        revision-date "2013-07-15";
+    }
+
+    revision "2017-02-09" {
+        description "NAT RPC module";
+    }
+
+    grouping nat-router-info {
+        leaf router-uuid {
+            description "Router UUID";
+            type yang:uuid;
+        }
+        leaf router-name {
+            description "Router Name";
+            type string;
+        }
+    }
+
+    grouping snat-state {
+        list snat-ip-mapping {
+            leaf internal-ip {
+                description "Internal IP Address of VM";
+                type string;
+            }
+            leaf internal-port {
+                description "Internal Port";
+                type string;
+            }
+            leaf external-ip {
+                description "External Fixed IP Address used for SNAT Translation";
+                type string;
+            }
+            leaf external-port {
+                description "External Port used for SNAT Translation";
+                type string;
+            }
+            leaf protocol {
+                description "Protocol Type";
+                type string;
+            }
+        }
+    }
+
+    grouping dnat-configuration {
+        list dnat-ip-mapping {
+            leaf internal-ip {
+                description "Internal IP Address";
+                type string;
+            }
+            leaf external-ip {
+                description "Floating IP Address used for DNAT Translation";
+                type string;
+            }
+        }
+    }
+
+    grouping nat-output {
+        list router-nat {
+            key router-uuid;
+            uses nat-router-info;
+            uses dnat-configuration;
+            uses snat-state;
+        }
+    }
+
+    rpc get_nat_translations_on_router {
+        description "Provides the NAT translations for given router uuid";
+        input {
+            leaf router-uuid {
+                description "Router UUID";
+                mandatory true;
+                type yang:uuid;
+            }
+        }
+        output {
+            uses nat-output;
+        }
+    }
+    /*
+    Sample output of get_nat_translations_on_router RPC
+    {
+    "output": {
+      "router-nat": [
+        {
+          "router-uuid": "feca5b1a-8ca8-43c1-b85d-80542144435d",
+          "snat-ip-mapping": [
+            {
+              "external-port": "49152",
+              "internal-port": "33811",
+              "internal-ip": "20.0.0.5",
+              "external-ip": "172.170.0.3",
+              "protocol": "TCP"
+            }
+          ],
+          "router-name": "router2",
+          "dnat-ip-mapping": [
+            {
+              "external-ip": "172.170.0.100",
+              "internal-ip": "20.0.0.5"
+            }
+          ]
+        }
+      ]
+    }
+  }
+  */
+
+
+    rpc get_nat_translations_on_vpn {
+        description "Provides the NAT translations for given vpn uuid";
+        input {
+            leaf vpn-uuid {
+                description "External VPN UUID";
+                mandatory true;
+                type yang:uuid;
+            }
+        }
+        output {
+            uses nat-output;
+        }
+    }
+    /*
+    Sample output for get_nat_translations_on_vpn RPC
+    {
+    "output": {
+      "router-nat": [
+        {
+          "router-uuid": "2e4563c4-c051-44f9-a84a-0d6814f2b83e",
+          "router-name": "router1",
+          "snat-ip-mapping": [
+            {
+              "external-port": "49152",
+              "internal-port": "39268",
+              "internal-ip": "10.0.0.5",
+              "external-ip": "172.160.0.3",
+              "protocol": "TCP"
+            }
+          ]
+        },
+        {
+          "router-uuid": "feca5b1a-8ca8-43c1-b85d-80542144435d",
+          "snat-ip-mapping": [
+            {
+              "external-port": "49152",
+              "internal-port": "33811",
+              "internal-ip": "20.0.0.5",
+              "external-ip": "172.170.0.3",
+              "protocol": "TCP"
+            }
+          ],
+          "router-name": "router2",
+          "dnat-ip-mapping": [
+            {
+              "external-ip": "172.170.0.100",
+              "internal-ip": "20.0.0.5"
+            }
+          ]
+        }
+      ]
+    }
+    */
+
+
+    rpc get_nat_translations_for_network_and_ipaddress {
+        description "Provides the NAT translations for given IP Address";
+        input {
+            leaf network-uuid {
+                description "Network UUID of the Internal IP address provided";
+                mandatory true;
+                type yang:uuid;
+            }
+            leaf ip-address {
+                description "Internal IP address of VM";
+                mandatory true;
+                type inet:ip-address;
+            }
+        }
+        output {
+            leaf nat-translation {
+                description "Represents whether its an SNAT or DNAT translation";
+                type string;
+            }
+            leaf external-ip {
+                description "External IP address used for NAT translation";
+                type string;
+            }
+            leaf internal-ip {
+                description "Internal IP address";
+                type string;
+            }
+            leaf external-port {
+                description "External Port";
+                type string;
+            }
+            leaf internal-port {
+                description "Internal Port";
+                type string;
+            }
+            leaf protocol {
+                description "Protocol Type";
+                type string;
+            }
+        }
+    }
+    /*
+    DNAT output
+    {
+    "output": {
+      "nat-translation": "DNAT",
+      "external-ip-address": "172.160.0.100"
+    }
+    }
+
+    SNAT output
+    {
+    "output": {
+      "nat-translation": "SNAT",
+      "external-port": "49152",
+      "internal-port": "6543",
+      "internal-ip": "10.0.0.5",
+      "external-ip": "172.160.0.3",
+      "protocol": "TCP"
+    }
+    }
+    */
+}
index 2ac79d8ce0f641fe1e6d4cc7b914e40911414f91..4a1de4de74046e379522f8f1aa6f9e9eb61a8a49 100644 (file)
@@ -9,7 +9,6 @@
 package org.opendaylight.netvirt.natservice.internal;
 
 import java.math.BigInteger;
-
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
@@ -105,6 +104,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev15060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
@@ -1640,13 +1641,77 @@ public class NatUtil {
   */
     static String getExtGwMacAddFromRouterId(DataBroker broker, long routerId) {
 
-     String routerName = getRouterName(broker, routerId);
-     InstanceIdentifier id = buildRouterIdentifier(routerName);
-     Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
-     if (routerData.isPresent()) {
-         return routerData.get().getExtGwMacAddress();
-     }
-     return null;
-  }
+        String routerName = getRouterName(broker, routerId);
+        InstanceIdentifier id = buildRouterIdentifier(routerName);
+        Optional<Routers> routerData = read(broker, LogicalDatastoreType.CONFIGURATION, id);
+        if (routerData.isPresent()) {
+            return routerData.get().getExtGwMacAddress();
+        }
+        return null;
+    }
 
+    static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
+        InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
+             .child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers.class)
+             .child(Router.class, new RouterKey(routerUuid));
+        return routerInstanceIdentifier;
+    }
+
+    public static String getNeutronRouterNamebyUuid(DataBroker broker, Uuid routerUuid) {
+        InstanceIdentifier<Router> neutronRouterIdentifier = NatUtil.buildNeutronRouterIdentifier(routerUuid);
+        Optional<Router> neutronRouterData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
+                neutronRouterIdentifier);
+        if (neutronRouterData.isPresent()) {
+            return neutronRouterData.get().getName();
+        }
+        return null;
+    }
+
+    public static List<Ports> getFloatingIpPortsForRouter(DataBroker broker, Uuid routerUuid) {
+
+        InstanceIdentifier<RouterPorts> routerPortsIdentifier = getRouterPortsId(routerUuid.getValue());
+        Optional<RouterPorts> routerPortsData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
+                routerPortsIdentifier);
+        if (routerPortsData.isPresent()) {
+            return routerPortsData.get().getPorts();
+        }
+        return null;
+    }
+
+    public static List<Uuid> getRouterUuIdsForVpn(DataBroker broker, Uuid vpnUuid) {
+        InstanceIdentifier<ExternalNetworks> externalNwIdentifier = InstanceIdentifier.create(ExternalNetworks.class);
+        Optional<ExternalNetworks> externalNwData = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
+                externalNwIdentifier);
+        if (externalNwData.isPresent()) {
+            for (Networks externalNw : externalNwData.get().getNetworks()) {
+                if (externalNw.getVpnid() != null && externalNw.getVpnid().equals(vpnUuid)) {
+                    return externalNw.getRouterIds();
+                }
+            }
+        }
+        return null;
+    }
+
+    public static boolean isIpInSubnet(String ipAddress, String start, String end) {
+
+        try {
+            long ipLo = ipToLong(InetAddress.getByName(start));
+            long ipHi = ipToLong(InetAddress.getByName(end));
+            long ipToTest = ipToLong(InetAddress.getByName(ipAddress));
+            return (ipToTest >= ipLo && ipToTest <= ipHi);
+        } catch (UnknownHostException e) {
+            LOG.error("NAT Service : isIpInSubnet failed for IP {}. Exception {}", ipAddress, e.getMessage());
+            return false;
+        }
+    }
+
+    private static long ipToLong(InetAddress ip) {
+        byte[] octets = ip.getAddress();
+        long result = 0;
+        for (byte octet : octets) {
+            result <<= 8;
+            result |= octet & 0xff;
+        }
+        return result;
+    }
 }
diff --git a/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/rpcservice/NatRpcServiceImpl.java b/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/rpcservice/NatRpcServiceImpl.java
new file mode 100644 (file)
index 0000000..fc0e59f
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.natservice.rpcservice;
+
+import com.google.common.util.concurrent.Futures;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.netvirt.natservice.internal.NatConstants;
+import org.opendaylight.netvirt.natservice.internal.NatUtil;
+import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.Ports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.IpPortMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.IntextIpProtocolType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.intext.ip.port.map.ip.port.mapping.intext.ip.protocol.type.IpPortMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsForNetworkAndIpaddressInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsForNetworkAndIpaddressOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsForNetworkAndIpaddressOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsOnRouterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsOnRouterOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsOnRouterOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsOnVpnInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsOnVpnOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.GetNatTranslationsOnVpnOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.OdlNatRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.dnat.configuration.DnatIpMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.dnat.configuration.DnatIpMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.nat.output.RouterNat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.nat.output.RouterNatBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.snat.state.SnatIpMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.snat.state.SnatIpMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnet.attributes.AllocationPools;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NatRpcServiceImpl implements OdlNatRpcService {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NatRpcServiceImpl.class);
+    private final DataBroker dataBroker;
+    private final INeutronVpnManager nvpnManager;
+
+    public NatRpcServiceImpl(final DataBroker dataBroker, INeutronVpnManager nvpnManager) {
+        this.dataBroker = dataBroker;
+        this.nvpnManager = nvpnManager;
+    }
+
+    @Override
+    public Future<RpcResult<GetNatTranslationsOnVpnOutput>> getNatTranslationsOnVpn(
+            GetNatTranslationsOnVpnInput input) {
+        RpcResultBuilder<GetNatTranslationsOnVpnOutput> rpcResultBuilder = null;
+
+        List<Uuid> routerUuidList = NatUtil.getRouterUuIdsForVpn(dataBroker, input.getVpnUuid());
+        if (routerUuidList == null || routerUuidList.isEmpty()) {
+            String errMsg = String.format("404 Not Found - Invalid external vpn {%s} provided",
+                    input.getVpnUuid().getValue());
+            rpcResultBuilder = RpcResultBuilder.<GetNatTranslationsOnVpnOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
+            return Futures.immediateFuture(rpcResultBuilder.build());
+        }
+        List<RouterNat> natRouterList = new ArrayList<RouterNat>();
+        for (Uuid routerUuid : routerUuidList) {
+            long routerId = NatUtil.getVpnId(dataBroker, routerUuid.getValue());
+            if (routerId == NatConstants.INVALID_ID) {
+                LOG.warn("NAT Service: Invalid RouterID found {}", routerId);
+                continue;
+            }
+            natRouterList.addAll(constructNatInformation(routerUuid, routerId));
+        }
+        GetNatTranslationsOnVpnOutputBuilder output = new GetNatTranslationsOnVpnOutputBuilder()
+                .setRouterNat(natRouterList);
+        rpcResultBuilder = RpcResultBuilder.success();
+        rpcResultBuilder.withResult(output.build());
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    @Override
+    public Future<RpcResult<GetNatTranslationsOnRouterOutput>> getNatTranslationsOnRouter(
+            GetNatTranslationsOnRouterInput input) {
+        RpcResultBuilder<GetNatTranslationsOnRouterOutput> rpcResultBuilder = null;
+        long routerId = NatUtil.getVpnId(dataBroker, input.getRouterUuid().getValue());
+        if (routerId == NatConstants.INVALID_ID) {
+            String errMsg = String.format("404 Not Found - No Router found with UUID {%s}",
+                    input.getRouterUuid().getValue());
+            rpcResultBuilder = RpcResultBuilder.<GetNatTranslationsOnRouterOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
+            return Futures.immediateFuture(rpcResultBuilder.build());
+        }
+
+        List<RouterNat> routerNatList = constructNatInformation(input.getRouterUuid(), routerId);
+
+        GetNatTranslationsOnRouterOutputBuilder output = new GetNatTranslationsOnRouterOutputBuilder()
+                .setRouterNat(routerNatList);
+        rpcResultBuilder = RpcResultBuilder.success();
+        rpcResultBuilder.withResult(output.build());
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    public Future<RpcResult<GetNatTranslationsForNetworkAndIpaddressOutput>> getNatTranslationsForNetworkAndIpaddress(
+            GetNatTranslationsForNetworkAndIpaddressInput input) {
+
+        String ipAddress = String.valueOf(input.getIpAddress().getValue());
+        RpcResultBuilder<GetNatTranslationsForNetworkAndIpaddressOutput> rpcResultBuilder = null;
+        GetNatTranslationsForNetworkAndIpaddressOutputBuilder output = null;
+
+        List<Uuid> subnetUuidList = NatUtil.getSubnetIdsFromNetworkId(dataBroker, input.getNetworkUuid());
+        if (subnetUuidList == null) {
+            String errMsg = String.format("404 Not Found - Invalid Network UUID {%s} provided as no Subnetworks found",
+                    input.getNetworkUuid().getValue());
+            rpcResultBuilder = RpcResultBuilder.<GetNatTranslationsForNetworkAndIpaddressOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
+            return Futures.immediateFuture(rpcResultBuilder.build());
+        }
+        Subnet subNet = null;
+        Boolean isIpInSubnet = Boolean.FALSE;
+        outerloop:
+        for (Uuid subnetUuid: subnetUuidList) {
+            subNet = nvpnManager.getNeutronSubnet(subnetUuid);
+            for (AllocationPools allocationPool : subNet.getAllocationPools()) {
+                if (NatUtil.isIpInSubnet(ipAddress,
+                        String.valueOf(allocationPool.getStart().getValue()),
+                        String.valueOf(allocationPool.getEnd().getValue()))) {
+                    LOG.debug("NAT Service: IP Adderess {} falls within the Subnet {}", ipAddress,
+                            subNet.getUuid().getValue());
+                    isIpInSubnet = Boolean.TRUE;
+                    break outerloop;
+                }
+            }
+        }
+
+        if (!isIpInSubnet) {
+            String errMsg = String.format("404 Not Found - IP Adress {%s} does not fall within the Subnet IP range"
+                    + " of Network {%s}", ipAddress, input.getNetworkUuid().getValue());
+            rpcResultBuilder = RpcResultBuilder.<GetNatTranslationsForNetworkAndIpaddressOutput>failed()
+                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
+            return Futures.immediateFuture(rpcResultBuilder.build());
+        }
+
+        Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, subNet.getUuid());
+        long routerId = NatUtil.getVpnId(dataBroker, subnetMap.getRouterId().getValue());
+
+        List<Ports> fipPorts = NatUtil.getFloatingIpPortsForRouter(dataBroker, subnetMap.getRouterId());
+        if (fipPorts == null || fipPorts.isEmpty()) {
+            LOG.warn("NAT Service: No DNAT IP Mapping found for IP {}", ipAddress);
+        } else {
+            for (Ports fipPort : fipPorts) {
+                List<InternalToExternalPortMap> ipMapping = fipPort.getInternalToExternalPortMap();
+                for (InternalToExternalPortMap fipMap : ipMapping) {
+                    if (fipMap.getInternalIp().equals(ipAddress)) {
+                        output = new GetNatTranslationsForNetworkAndIpaddressOutputBuilder()
+                                    .setExternalIp(fipMap.getExternalIp())
+                                    .setNatTranslation("DNAT");
+                        rpcResultBuilder = RpcResultBuilder.success();
+                        rpcResultBuilder.withResult(output.build());
+                        return Futures.immediateFuture(rpcResultBuilder.build());
+                    }
+                }
+            }
+        }
+
+        IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
+        if (ipPortMapping == null) {
+            LOG.warn("NAT Service: No SNAT IP Mapping found for IP {}", ipAddress);
+        } else {
+            for (IntextIpProtocolType protocolType : ipPortMapping.getIntextIpProtocolType()) {
+                for (IpPortMap ipPortMap : protocolType.getIpPortMap()) {
+                    String[] internalIpPort = ipPortMap.getIpPortInternal().split(":");
+                    if (ipAddress.equals(internalIpPort[0])) {
+
+                        output = new GetNatTranslationsForNetworkAndIpaddressOutputBuilder()
+                                .setExternalIp(ipPortMap.getIpPortExternal().getIpAddress())
+                                .setInternalIp(internalIpPort[0])
+                                .setNatTranslation("SNAT")
+                                .setInternalPort(internalIpPort[1])
+                                .setExternalPort(ipPortMap.getIpPortExternal().getPortNum().toString())
+                                .setProtocol(protocolType.getProtocol().getName());
+                        rpcResultBuilder = RpcResultBuilder.success();
+                        rpcResultBuilder.withResult(output.build());
+                        return Futures.immediateFuture(rpcResultBuilder.build());
+                    }
+                }
+            }
+        }
+
+        String errMsg = String.format("404 Not Found - No NAT Translation found for IP {%s}", ipAddress);
+        rpcResultBuilder = RpcResultBuilder.<GetNatTranslationsForNetworkAndIpaddressOutput>failed()
+                .withError(RpcError.ErrorType.APPLICATION, errMsg);
+        return Futures.immediateFuture(rpcResultBuilder.build());
+    }
+
+    private List<RouterNat> constructNatInformation(Uuid routerUuid, long routerId) {
+
+        String neutronRouterName = NatUtil.getNeutronRouterNamebyUuid(dataBroker, routerUuid);
+
+        RouterNatBuilder natRouterBuilder = new RouterNatBuilder();
+        natRouterBuilder.setRouterUuid(routerUuid);
+        natRouterBuilder.setRouterName(neutronRouterName);
+
+        IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
+        if (ipPortMapping == null) {
+            LOG.warn("NAT Service: No SNAT IP Mapping found for router-uuid {}", routerUuid.getValue());
+        } else {
+
+            // Capturing SNAT information
+            List<SnatIpMapping> snatIpMapping = new ArrayList<SnatIpMapping>();
+
+            for (IntextIpProtocolType protocolType : ipPortMapping.getIntextIpProtocolType()) {
+                for (IpPortMap ipPortMap : protocolType.getIpPortMap()) {
+                    String[] internalPortMap = ipPortMap.getIpPortInternal().split(":");
+                    SnatIpMappingBuilder natIpMappingBuilder = new SnatIpMappingBuilder()
+                            .setInternalIp(internalPortMap[0]).setInternalPort(internalPortMap[1])
+                            .setExternalIp(ipPortMap.getIpPortExternal().getIpAddress())
+                            .setExternalPort(ipPortMap.getIpPortExternal().getPortNum().toString())
+                            .setProtocol(protocolType.getProtocol().getName());
+                    snatIpMapping.add(natIpMappingBuilder.build());
+                }
+            }
+            natRouterBuilder.setSnatIpMapping(snatIpMapping);
+        }
+
+        // Capturing DNAT information
+        List<DnatIpMapping> dnatIpMapping = new ArrayList<DnatIpMapping>();
+        List<Ports> fipPorts = NatUtil.getFloatingIpPortsForRouter(dataBroker, routerUuid);
+        if (fipPorts == null || fipPorts.isEmpty()) {
+            LOG.warn("NAT Service: No DNAT IP Mapping found for router-uuid {}", routerUuid.getValue());
+        } else {
+            for (Ports fipPort : fipPorts) {
+                List<InternalToExternalPortMap> ipMapping = fipPort.getInternalToExternalPortMap();
+                for (InternalToExternalPortMap fipMap : ipMapping) {
+                    DnatIpMappingBuilder natIpMappingBuilder = new DnatIpMappingBuilder()
+                            .setExternalIp(fipMap.getExternalIp()).setInternalIp(fipMap.getInternalIp());
+                    dnatIpMapping.add(natIpMappingBuilder.build());
+                }
+            }
+            natRouterBuilder.setDnatIpMapping(dnatIpMapping);
+        }
+
+        List<RouterNat> natRouterList = new ArrayList<RouterNat>();
+        natRouterList.add(natRouterBuilder.build());
+        return natRouterList;
+    }
+}
\ No newline at end of file
index 7da5014fa3452bf87cefdadf0c1ab134cb51fe11..529cbf442bb6c4fa67dd12ae119f07737c58cdc2 100644 (file)
@@ -37,6 +37,7 @@
                    interface="org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.FibRpcService" />
   <odl:rpc-service id="odlArputilService"
                    interface="org.opendaylight.yang.gen.v1.urn.opendaylight.genius.arputil.rev160406.OdlArputilService" />
+  <odl:rpc-implementation ref="natRpcServiceImpl"/>
 
   <bean id="subnetmapListener"
         class="org.opendaylight.netvirt.natservice.internal.SubnetmapListener"
     <argument ref="fibRpcService" />
   </bean>
 
+  <bean id="natRpcServiceImpl" class="org.opendaylight.netvirt.natservice.rpcservice.NatRpcServiceImpl">
+    <argument ref="dataBroker"/>
+    <argument ref="neutronvpnManager" />
+  </bean>
+  <service ref="natRpcServiceImpl"
+           interface="org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rpc.rev170209.OdlNatRpcService"/>
 </blueprint>