All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.netvirt.natservice.rpcservice.NatRpcServiceImpl Maven / Gradle / Ivy

There is a newer version: 0.11.4
Show newest version
/*
 * Copyright © 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 com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
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;

@Singleton
public class NatRpcServiceImpl implements OdlNatRpcService {

    private static final Logger LOG = LoggerFactory.getLogger(NatRpcServiceImpl.class);
    private final DataBroker dataBroker;
    private final INeutronVpnManager nvpnManager;

    @Inject
    public NatRpcServiceImpl(final DataBroker dataBroker, final INeutronVpnManager nvpnManager) {
        this.dataBroker = dataBroker;
        this.nvpnManager = nvpnManager;
    }

    @Override
    public ListenableFuture> getNatTranslationsOnVpn(
            GetNatTranslationsOnVpnInput input) {
        RpcResultBuilder rpcResultBuilder = null;

        List routerUuidList = NatUtil.getRouterUuIdsForVpn(dataBroker, input.getVpnUuid());
        if (routerUuidList.isEmpty()) {
            String errMsg = String.format("404 Not Found - Invalid external vpn {%s} provided",
                    input.getVpnUuid().getValue());
            rpcResultBuilder = RpcResultBuilder.failed()
                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
            return rpcResultBuilder.buildFuture();
        }
        List natRouterList = new ArrayList<>();
        for (Uuid routerUuid : routerUuidList) {
            long routerId = NatUtil.getVpnId(dataBroker, routerUuid.getValue());
            if (routerId == NatConstants.INVALID_ID) {
                LOG.warn("getNatTranslationsOnVpn : 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 ListenableFuture> getNatTranslationsOnRouter(
            GetNatTranslationsOnRouterInput input) {
        RpcResultBuilder 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.failed()
                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
            return rpcResultBuilder.buildFuture();
        }

        List routerNatList = constructNatInformation(input.getRouterUuid(), routerId);

        GetNatTranslationsOnRouterOutputBuilder output = new GetNatTranslationsOnRouterOutputBuilder()
                .setRouterNat(routerNatList);
        rpcResultBuilder = RpcResultBuilder.success();
        rpcResultBuilder.withResult(output.build());
        return rpcResultBuilder.buildFuture();
    }

    @Override
    public ListenableFuture>
            getNatTranslationsForNetworkAndIpaddress(GetNatTranslationsForNetworkAndIpaddressInput input) {

        String ipAddress = input.getIpAddress().stringValue();
        RpcResultBuilder rpcResultBuilder = null;
        GetNatTranslationsForNetworkAndIpaddressOutputBuilder output = null;

        List subnetUuidList = NatUtil.getSubnetIdsFromNetworkId(dataBroker, input.getNetworkUuid());
        if (subnetUuidList.isEmpty()) {
            String errMsg = String.format("404 Not Found - Invalid Network UUID {%s} provided as no Subnetworks found",
                    input.getNetworkUuid().getValue());
            rpcResultBuilder = RpcResultBuilder.failed()
                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
            return rpcResultBuilder.buildFuture();
        }
        Subnet subNet = null;
        Boolean isIpInSubnet = Boolean.FALSE;
        outerloop:
        for (Uuid subnetUuid: subnetUuidList) {
            subNet = nvpnManager.getNeutronSubnet(subnetUuid);
            for (AllocationPools allocationPool : subNet.nonnullAllocationPools()) {
                if (NatUtil.isIpInSubnet(ipAddress,
                        allocationPool.getStart().stringValue(),
                        allocationPool.getEnd().stringValue())) {
                    LOG.debug("getNatTranslationsForNetworkAndIpaddress : 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.failed()
                    .withError(RpcError.ErrorType.APPLICATION, errMsg);
            return rpcResultBuilder.buildFuture();
        }

        Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, subNet.getUuid());
        long routerId = NatUtil.getVpnId(dataBroker, subnetMap.getRouterId().getValue());

        List fipPorts = NatUtil.getFloatingIpPortsForRouter(dataBroker, subnetMap.getRouterId());
        if (fipPorts.isEmpty()) {
            LOG.warn("getNatTranslationsForNetworkAndIpaddress : No DNAT IP Mapping found for IP {}", ipAddress);
        } else {
            for (Ports fipPort : fipPorts) {
                for (InternalToExternalPortMap fipMap : fipPort.nonnullInternalToExternalPortMap()) {
                    if (fipMap.getInternalIp().equals(ipAddress)) {
                        output = new GetNatTranslationsForNetworkAndIpaddressOutputBuilder()
                                    .setExternalIp(fipMap.getExternalIp())
                                    .setNatTranslation("DNAT");
                        rpcResultBuilder = RpcResultBuilder.success();
                        rpcResultBuilder.withResult(output.build());
                        return rpcResultBuilder.buildFuture();
                    }
                }
            }
        }

        IpPortMapping ipPortMapping = NatUtil.getIportMapping(dataBroker, routerId);
        if (ipPortMapping == null) {
            LOG.warn("getNatTranslationsForNetworkAndIpaddress : No SNAT IP Mapping found for IP {}", ipAddress);
        } else {
            for (IntextIpProtocolType protocolType : ipPortMapping.nonnullIntextIpProtocolType()) {
                for (IpPortMap ipPortMap : protocolType.nonnullIpPortMap()) {
                    String[] internalIpPort = ipPortMap.getIpPortInternal().split(NwConstants.MACADDR_SEP);
                    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 rpcResultBuilder.buildFuture();
                    }
                }
            }
        }

        String errMsg = String.format("404 Not Found - No NAT Translation found for IP {%s}", ipAddress);
        rpcResultBuilder = RpcResultBuilder.failed()
                .withError(RpcError.ErrorType.APPLICATION, errMsg);
        return rpcResultBuilder.buildFuture();
    }

    private List 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("constructNatInformation : No SNAT IP Mapping found for router-uuid {}", routerUuid.getValue());
        } else {

            // Capturing SNAT information
            List snatIpMapping = new ArrayList<>();

            for (IntextIpProtocolType protocolType : ipPortMapping.nonnullIntextIpProtocolType()) {
                for (IpPortMap ipPortMap : protocolType.nonnullIpPortMap()) {
                    String[] internalPortMap = ipPortMap.getIpPortInternal().split(NwConstants.MACADDR_SEP);
                    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 = new ArrayList<>();
        List fipPorts = NatUtil.getFloatingIpPortsForRouter(dataBroker, routerUuid);
        if (fipPorts.isEmpty()) {
            LOG.warn("constructNatInformation : No DNAT IP Mapping found for router-uuid {}", routerUuid.getValue());
        } else {
            for (Ports fipPort : fipPorts) {
                for (InternalToExternalPortMap fipMap : fipPort.nonnullInternalToExternalPortMap()) {
                    DnatIpMappingBuilder natIpMappingBuilder = new DnatIpMappingBuilder()
                            .setExternalIp(fipMap.getExternalIp()).setInternalIp(fipMap.getInternalIp());
                    dnatIpMapping.add(natIpMappingBuilder.build());
                }
            }
            natRouterBuilder.setDnatIpMapping(dnatIpMapping);
        }

        List natRouterList = new ArrayList<>();
        natRouterList.add(natRouterBuilder.build());
        return natRouterList;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy