#warning "Merge netns.c from osmo-ggsn and osmo-gtpu-daemon"
/*
 * Copyright (C) 2014-2017, Travelping GmbH <info@travelping.com>
 * Copyright (C) 2020, Harald Welte <laforge@gnumonks.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#if defined(__linux__)

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <fcntl.h>
#include <errno.h>

#include <osmocom/core/utils.h>

#include "netns.h"

#define NETNS_PATH "/var/run/netns"

/*! default namespace of the GGSN process */
static int default_nsfd = -1;

/*! switch to a (non-default) namespace, store existing signal mask in oldmask.
 *  \param[in] nsfd file descriptor representing the namespace to whch we shall switch
 *  \param[out] oldmaks caller-provided memory location to which old signal mask is stored
 *  \ returns 0 on success or negative (errno) in case of error */
int switch_ns(int nsfd, sigset_t *oldmask)
{
	sigset_t intmask;
	int rc;

	OSMO_ASSERT(default_nsfd >= 0);

	if (sigfillset(&intmask) < 0)
		return -errno;
	if ((rc = sigprocmask(SIG_BLOCK, &intmask, oldmask)) != 0)
		return -rc;

	if (setns(nsfd, CLONE_NEWNET) < 0) {
		/* restore old mask if we couldn't switch the netns */
		sigprocmask(SIG_SETMASK, oldmask, NULL);
		return -errno;
	}
	return 0;
}

/*! switch back to the default namespace, restoring signal mask.
 *  \param[in] oldmask signal mask to restore after returning to default namespace
 *  \returns 0 on successs; negative errno value in case of error */
int restore_ns(sigset_t *oldmask)
{
	OSMO_ASSERT(default_nsfd >= 0);

	int rc;
	if (setns(default_nsfd, CLONE_NEWNET) < 0)
		return -errno;

	if ((rc = sigprocmask(SIG_SETMASK, oldmask, NULL)) != 0)
		return -rc;
	return 0;
}

/*! open a file from within specified network namespace */
int open_ns(int nsfd, const char *pathname, int flags)
{
	sigset_t intmask, oldmask;
	int ret;
	int fd = -1;
	int rc;

	OSMO_ASSERT(default_nsfd >= 0);

	/* mask off all signals, store old signal mask */
	if (sigfillset(&intmask) < 0)
		return -errno;
	if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)
		return -rc;

	/* associate the calling thread with namespace file descriptor */
	if (setns(nsfd, CLONE_NEWNET) < 0) {
		ret = -errno;
		goto restore_sigmask;
	}
	/* open the requested file/path */
	if ((fd = open(pathname, flags)) < 0) {
		ret = -errno;
		goto restore_defaultns;
	}
	ret = fd;

restore_defaultns:
	/* return back to default namespace */
	if (setns(default_nsfd, CLONE_NEWNET) < 0) {
		if (fd >= 0)
			close(fd);
		return -errno;
	}

restore_sigmask:
	/* restore process mask */
	if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0) {
		if (fd >= 0)
			close(fd);
		return -rc;
	}

	return ret;
}

/*! create a socket in another namespace.
 *  Switches temporarily to namespace indicated by nsfd, creates a socket in
 *  that namespace and then returns to the default namespace.
 *  \param[in] nsfd File descriptor of the namspace in which to create socket
 *  \param[in] domain Domain of the socket (AF_INET, ...)
 *  \param[in] type Type of the socket (SOCK_STREAM, ...)
 *  \param[in] protocol Protocol of the socket (IPPROTO_TCP, ...)
 *  \returns 0 on success; negative errno in case of error */
int socket_ns(int nsfd, int domain, int type, int protocol)
{
	sigset_t intmask, oldmask;
	int ret;
	int sk = -1;
	int rc;

	OSMO_ASSERT(default_nsfd >= 0);

	/* mask off all signals, store old signal mask */
	if (sigfillset(&intmask) < 0)
		return -errno;
	if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)
		return -rc;

	/* associate the calling thread with namespace file descriptor */
	if (setns(nsfd, CLONE_NEWNET) < 0) {
		ret = -errno;
		goto restore_sigmask;
	}

	/* create socket of requested domain/type/proto */
	if ((sk = socket(domain, type, protocol)) < 0) {
		ret = -errno;
		goto restore_defaultns;
	}
	ret = sk;

restore_defaultns:
	/* return back to default namespace */
	if (setns(default_nsfd, CLONE_NEWNET) < 0) {
		if (sk >= 0)
			close(sk);
		return -errno;
	}

restore_sigmask:
	/* restore process mask */
	if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0) {
		if (sk >= 0)
			close(sk);
		return -rc;
	}
	return ret;
}

/*! initialize this network namespace helper module.
 *  Must be called before using any other functions of this file.
 *  \returns 0 on success; negative errno in case of error */
int init_netns()
{
	/* store the default namespace for later reference */
	if ((default_nsfd = open("/proc/self/ns/net", O_RDONLY)) < 0)
		return -errno;
	return 0;
}

/*! create obtain file descriptor for network namespace of give name.
 *  Creates /var/run/netns  if it doesn't exist already.
 *  \param[in] name Name of the network namespace (in /var/run/netns/)
 *  \returns File descriptor of network namespace; negative errno in case of error */
int get_nsfd(const char *name)
{
	int ret = 0;
	int rc;
	int fd;
	sigset_t intmask, oldmask;
	char path[MAXPATHLEN] = NETNS_PATH;

	OSMO_ASSERT(default_nsfd >= 0);

	/* create /var/run/netns, if it doesn't exist already */
	rc = mkdir(path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
	if (rc < 0 && errno != EEXIST)
		return rc;

	/* create /var/run/netns/[name], if it doesn't exist already */
	snprintf(path, sizeof(path), "%s/%s", NETNS_PATH, name);
	fd = open(path, O_RDONLY|O_CREAT|O_EXCL, 0);
	if (fd < 0) {
		if (errno == EEXIST) {
			if ((fd = open(path, O_RDONLY)) < 0)
				return -errno;
			return fd;
		}
		return -errno;
	}
	if (close(fd) < 0)
		return -errno;

	/* mask off all signals, store old signal mask */
	if (sigfillset(&intmask) < 0)
		return -errno;
	if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)
		return -rc;

	/* create a new network namespace */
	if (unshare(CLONE_NEWNET) < 0) {
		ret = -errno;
		goto restore_sigmask;
	}
	if (mount("/proc/self/ns/net", path, "none", MS_BIND, NULL) < 0)
		ret = -errno;

	/* switch back to default namespace */
	if (setns(default_nsfd, CLONE_NEWNET) < 0)
		return -errno;

restore_sigmask:
	/* restore process mask */
	if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0)
		return -rc;

	/* might have been set above in case mount fails */
	if (ret < 0)
		return ret;

	/* finally, open the created namespace file descriptor from default ns */
	if ((fd = open(path, O_RDONLY)) < 0)
		return -errno;

	return fd;
}

#endif
