Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
index 05bf0c4b..f04f4161 100644
--- a/libnozzle/libnozzle.c
+++ b/libnozzle/libnozzle.c
@@ -1,1190 +1,1197 @@
/*
* Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
*
* Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <net/ethernet.h>
#include <pthread.h>
#include <limits.h>
#include <stdio.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <stdint.h>
#ifdef KNET_LINUX
#include <linux/if_tun.h>
/*
* libnl3 < 3.3 includes kernel headers directly
* causing conflicts with net/if.h included above
*/
#ifdef LIBNL3_WORKAROUND
#define _LINUX_IF_H 1
#endif
#include <netinet/ether.h>
#include <netlink/netlink.h>
#include <netlink/route/addr.h>
#include <netlink/route/link.h>
#endif
#ifdef KNET_BSD
#include <net/if_dl.h>
#endif
#include "libnozzle.h"
#include "internals.h"
/*
* internal functions are all _unlocked_
* locking should be handled at external API functions
*/
static int lib_init = 0;
static struct nozzle_lib_config lib_cfg;
static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* internal helpers
*/
static void lib_fini(void)
{
if (lib_cfg.head == NULL) {
#ifdef KNET_LINUX
nl_close(lib_cfg.nlsock);
nl_socket_free(lib_cfg.nlsock);
#endif
close(lib_cfg.ioctlfd);
lib_init = 0;
}
}
static int is_valid_nozzle(const nozzle_t nozzle)
{
nozzle_t temp;
if (!nozzle) {
return 0;
}
if (!lib_init) {
return 0;
}
temp = lib_cfg.head;
while (temp != NULL) {
if (nozzle == temp)
return 1;
temp = temp->next;
}
return 0;
}
static void destroy_iface(nozzle_t nozzle)
{
#ifdef KNET_BSD
struct ifreq ifr;
#endif
if (!nozzle)
return;
if (nozzle->fd)
close(nozzle->fd);
#ifdef KNET_BSD
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
#endif
free(nozzle);
lib_fini();
return;
}
static int get_iface_mtu(const nozzle_t nozzle)
{
int err = 0, savederrno = 0;
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
err = ifr.ifr_mtu;
out_clean:
errno = savederrno;
return err;
}
static int get_iface_mac(const nozzle_t nozzle, char **ether_addr)
{
int err = 0, savederrno = 0;
struct ifreq ifr;
char mac[MACADDR_CHAR_MAX];
#ifdef KNET_BSD
struct ifaddrs *ifap = NULL;
struct ifaddrs *ifa;
int found = 0;
#endif
memset(&mac, 0, MACADDR_CHAR_MAX);
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
#ifdef KNET_LINUX
err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
ether_ntoa_r((struct ether_addr *)ifr.ifr_hwaddr.sa_data, mac);
#endif
#ifdef KNET_BSD
/*
* there is no ioctl to get the ether address of an interface on FreeBSD
* (not to be confused with hwaddr). Use workaround described here:
* https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
*/
err = getifaddrs(&ifap);
if (err < 0) {
savederrno = errno;
goto out_clean;
}
ifa = ifap;
while (ifa) {
if (!strncmp(nozzle->name, ifa->ifa_name, IFNAMSIZ)) {
found = 1;
break;
}
ifa=ifa->ifa_next;
}
if (found) {
ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
} else {
errno = EINVAL;
err = -1;
}
freeifaddrs(ifap);
if (err) {
goto out_clean;
}
#endif
*ether_addr = strdup(mac);
if (!*ether_addr) {
savederrno = errno;
err = -1;
}
out_clean:
errno = savederrno;
return err;
}
#define IP_ADD 1
#define IP_DEL 2
static int _set_ip(nozzle_t nozzle,
int command,
const char *ipaddr, const char *prefix,
int secondary)
{
int fam;
char *broadcast = NULL;
int err = 0;
#ifdef KNET_LINUX
struct rtnl_addr *addr = NULL;
struct nl_addr *local_addr = NULL;
struct nl_addr *bcast_addr = NULL;
struct nl_cache *cache = NULL;
int ifindex;
#endif
#ifdef KNET_BSD
char cmdline[4096];
char proto[6];
char *error_string = NULL;
#endif
if (!strchr(ipaddr, ':')) {
fam = AF_INET;
broadcast = generate_v4_broadcast(ipaddr, prefix);
if (!broadcast) {
errno = EINVAL;
return -1;
}
} else {
fam = AF_INET6;
}
#ifdef KNET_LINUX
addr = rtnl_addr_alloc();
if (!addr) {
errno = ENOMEM;
return -1;
}
if (rtnl_link_alloc_cache(lib_cfg.nlsock, AF_UNSPEC, &cache) < 0) {
errno = ENOMEM;
err = -1;
goto out;
}
ifindex = rtnl_link_name2i(cache, nozzle->name);
if (ifindex == 0) {
errno = ENOENT;
err = -1;
goto out;
}
rtnl_addr_set_ifindex(addr, ifindex);
if (nl_addr_parse(ipaddr, fam, &local_addr) < 0) {
errno = EINVAL;
err = -1;
goto out;
}
if (rtnl_addr_set_local(addr, local_addr) < 0) {
errno = EINVAL;
err = -1;
goto out;
}
if (broadcast) {
if (nl_addr_parse(broadcast, fam, &bcast_addr) < 0) {
errno = EINVAL;
err = -1;
goto out;
}
if (rtnl_addr_set_broadcast(addr, bcast_addr) < 0) {
errno = EINVAL;
err = -1;
goto out;
}
}
rtnl_addr_set_prefixlen(addr, atoi(prefix));
if (command == IP_ADD) {
if (rtnl_addr_add(lib_cfg.nlsock, addr, 0) < 0) {
errno = EINVAL;
err = -1;
goto out;
}
} else {
if (rtnl_addr_delete(lib_cfg.nlsock, addr, 0) < 0) {
errno = EINVAL;
err = -1;
goto out;
}
}
out:
if (addr) {
rtnl_addr_put(addr);
}
if (local_addr) {
nl_addr_put(local_addr);
}
if (bcast_addr) {
nl_addr_put(bcast_addr);
}
if (cache) {
nl_cache_put(cache);
}
if (broadcast) {
free(broadcast);
}
return err;
#endif
#ifdef KNET_BSD
/*
* TODO: port to use ioctl and such, drop shell forking here
*/
memset(cmdline, 0, sizeof(cmdline));
if (fam == AF_INET) {
snprintf(proto, sizeof(proto), "inet");
} else {
snprintf(proto, sizeof(proto), "inet6");
}
if (command == IP_ADD) {
snprintf(cmdline, sizeof(cmdline)-1,
"ifconfig %s %s %s/%s",
nozzle->name, proto, ipaddr, prefix);
if (broadcast) {
snprintf(cmdline + strlen(cmdline),
sizeof(cmdline) - strlen(cmdline) -1,
" broadcast %s", broadcast);
}
if ((secondary) && (fam == AF_INET)) {
snprintf(cmdline + strlen(cmdline),
sizeof(cmdline) - strlen(cmdline) -1,
" alias");
}
} else {
snprintf(cmdline, sizeof(cmdline)-1,
"ifconfig %s %s %s/%s delete",
nozzle->name, proto, ipaddr, prefix);
}
if (broadcast) {
free(broadcast);
}
/*
* temporary workaround as we port libnozzle to BSD ioctl
* for IP address management
*/
err = execute_bin_sh_command(cmdline, &error_string);
if (error_string) {
free(error_string);
error_string = NULL;
}
return err;
#endif
}
/*
* Exported public API
*/
nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
{
int savederrno = 0;
nozzle_t nozzle = NULL;
char *temp_mac = NULL;
#ifdef KNET_LINUX
struct ifreq ifr;
#endif
#ifdef KNET_BSD
uint16_t i;
long int nozzlenum = 0;
char curnozzle[IFNAMSIZ];
#endif
if (devname == NULL) {
errno = EINVAL;
return NULL;
}
if (devname_size < IFNAMSIZ) {
errno = EINVAL;
return NULL;
}
if (strlen(devname) > IFNAMSIZ) {
errno = E2BIG;
return NULL;
}
#ifdef KNET_BSD
/*
* BSD does not support named devices like Linux
* but it is possible to force a nozzleX device number
* where X is 0 to 255.
*/
if (strlen(devname)) {
if (strncmp(devname, "tap", 3)) {
errno = EINVAL;
return NULL;
}
errno = 0;
nozzlenum = strtol(devname+3, NULL, 10);
if (errno) {
errno = EINVAL;
return NULL;
}
if ((nozzlenum < 0) || (nozzlenum > 255)) {
errno = EINVAL;
return NULL;
}
}
#endif
if (updownpath) {
/* only absolute paths */
if (updownpath[0] != '/') {
errno = EINVAL;
return NULL;
}
if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
errno = E2BIG;
return NULL;
}
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return NULL;
}
if (!lib_init) {
lib_cfg.head = NULL;
#ifdef KNET_LINUX
lib_cfg.nlsock = nl_socket_alloc();
if (!lib_cfg.nlsock) {
savederrno = errno;
goto out_error;
}
if (nl_connect(lib_cfg.nlsock, NETLINK_ROUTE) < 0) {
savederrno = EBUSY;
goto out_error;
}
lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
#endif
#ifdef KNET_BSD
lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
#endif
if (lib_cfg.ioctlfd < 0) {
savederrno = errno;
goto out_error;
}
lib_init = 1;
}
nozzle = malloc(sizeof(struct nozzle_iface));
if (!nozzle) {
savederrno = ENOMEM;
goto out_error;
}
memset(nozzle, 0, sizeof(struct nozzle_iface));
#ifdef KNET_BSD
if (!strlen(devname)) {
for (i = 0; i < 256; i++) {
snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
nozzle->fd = open(curnozzle, O_RDWR);
savederrno = errno;
if (nozzle->fd > 0) {
break;
}
}
snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
} else {
snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
nozzle->fd = open(curnozzle, O_RDWR);
savederrno = errno;
snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
}
if (nozzle->fd < 0) {
savederrno = EBUSY;
goto out_error;
}
strncpy(devname, curnozzle, IFNAMSIZ);
strncpy(nozzle->name, curnozzle, IFNAMSIZ);
#endif
#ifdef KNET_LINUX
if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
savederrno = errno;
goto out_error;
}
memset(&ifr, 0, sizeof(struct ifreq));
memmove(ifname, devname, IFNAMSIZ);
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
savederrno = errno;
goto out_error;
}
if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
savederrno = EBUSY;
goto out_error;
}
strncpy(devname, ifname, IFNAMSIZ);
strncpy(nozzle->name, ifname, IFNAMSIZ);
#endif
nozzle->default_mtu = get_iface_mtu(nozzle);
if (nozzle->default_mtu < 0) {
savederrno = errno;
goto out_error;
}
if (get_iface_mac(nozzle, &temp_mac) < 0) {
savederrno = errno;
goto out_error;
}
strncpy(nozzle->default_mac, temp_mac, 18);
free(temp_mac);
if (updownpath) {
int len = strlen(updownpath);
strcpy(nozzle->updownpath, updownpath);
if (nozzle->updownpath[len-1] != '/') {
nozzle->updownpath[len] = '/';
}
nozzle->hasupdown = 1;
}
nozzle->next = lib_cfg.head;
lib_cfg.head = nozzle;
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return nozzle;
out_error:
destroy_iface(nozzle);
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return NULL;
}
int nozzle_close(nozzle_t nozzle)
{
int err = 0, savederrno = 0;
nozzle_t temp = lib_cfg.head;
nozzle_t prev = lib_cfg.head;
struct nozzle_ip *ip, *ip_next;
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
while ((temp) && (temp != nozzle)) {
prev = temp;
temp = temp->next;
}
if (nozzle == prev) {
lib_cfg.head = nozzle->next;
} else {
prev->next = nozzle->next;
}
ip = nozzle->ip;
while (ip) {
ip_next = ip->next;
free(ip);
ip = ip_next;
}
destroy_iface(nozzle);
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
{
int err = 0, savederrno = 0;
char command[PATH_MAX];
const char *action_str = NULL;
struct stat sb;
if (action > NOZZLE_POSTDOWN) {
errno = EINVAL;
return -1;
}
if (!exec_string) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
if (!nozzle->hasupdown) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
switch(action) {
case NOZZLE_PREUP:
action_str = "pre-up.d";
break;
case NOZZLE_UP:
action_str = "up.d";
break;
case NOZZLE_DOWN:
action_str = "down.d";
break;
case NOZZLE_POSTDOWN:
action_str = "post-down.d";
break;
}
memset(command, 0, PATH_MAX);
- snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action_str, nozzle->name);
+ snprintf(command, PATH_MAX, "%s/%s/%s", nozzle->updownpath, action_str, nozzle->name);
err = stat(command, &sb);
if (err) {
savederrno = errno;
goto out_clean;
}
+ /*
+ * clear errno from previous calls as there is no errno
+ * returned from execute_bin_sh_command
+ */
+ savederrno = 0;
err = execute_bin_sh_command(command, exec_string);
- savederrno = errno;
+ if (err) {
+ err = -2;
+ }
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_set_up(nozzle_t nozzle)
{
int err = 0, savederrno = 0;
struct ifreq ifr;
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
if (nozzle->up) {
goto out_clean;
}
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
nozzle->up = 1;
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_set_down(nozzle_t nozzle)
{
int err = 0, savederrno = 0;
struct ifreq ifr;
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
if (!nozzle->up) {
goto out_clean;
}
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
ifr.ifr_flags &= ~IFF_UP;
err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
nozzle->up = 0;
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_get_mtu(const nozzle_t nozzle)
{
int err = 0, savederrno = 0;
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
err = get_iface_mtu(nozzle);
savederrno = errno;
out_clean:
pthread_mutex_unlock(&config_mutex);
savederrno = errno;
return err;
}
int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
{
int err = 0, savederrno = 0;
if (!ether_addr) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
err = get_iface_mac(nozzle, ether_addr);
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
{
int err = 0, savederrno = 0;
struct ifreq ifr;
if (!ether_addr) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
#ifdef KNET_LINUX
err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
memmove(ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &ifr);
savederrno = errno;
#endif
#ifdef KNET_BSD
err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
memmove(ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &ifr);
savederrno = errno;
#endif
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_reset_mac(nozzle_t nozzle)
{
return nozzle_set_mac(nozzle, nozzle->default_mac);
}
nozzle_t nozzle_get_handle_by_name(const char *devname)
{
int savederrno = 0;
nozzle_t nozzle;
if ((devname == NULL) || (strlen(devname) > IFNAMSIZ)) {
errno = EINVAL;
return NULL;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return NULL;
}
nozzle = lib_cfg.head;
while (nozzle != NULL) {
if (!strcmp(devname, nozzle->name))
break;
nozzle = nozzle->next;
}
if (!nozzle) {
savederrno = ENOENT;
}
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return nozzle;
}
const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
{
int savederrno = 0;
char *name = NULL;
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return NULL;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = ENOENT;
goto out_clean;
}
name = nozzle->name;
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return name;
}
int nozzle_get_fd(const nozzle_t nozzle)
{
int fd = -1, savederrno = 0;
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = ENOENT;
fd = -1;
goto out_clean;
}
fd = nozzle->fd;
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return fd;
}
int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
{
int err = 0, savederrno = 0;
struct nozzle_ip *tmp_ip;
struct ifreq ifr;
if (!mtu) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
err = nozzle->current_mtu = get_iface_mtu(nozzle);
if (err < 0) {
savederrno = errno;
goto out_clean;
}
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifname, nozzle->name, IFNAMSIZ);
ifr.ifr_mtu = mtu;
err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
if (err) {
savederrno = errno;
goto out_clean;
}
if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
tmp_ip = nozzle->ip;
while(tmp_ip) {
if (tmp_ip->domain == AF_INET6) {
err = _set_ip(nozzle, IP_ADD, tmp_ip->ipaddr, tmp_ip->prefix, 0);
if (err) {
savederrno = errno;
err = -1;
goto out_clean;
}
}
tmp_ip = tmp_ip->next;
}
}
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_reset_mtu(nozzle_t nozzle)
{
return nozzle_set_mtu(nozzle, nozzle->default_mtu);
}
int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
{
int err = 0, savederrno = 0;
int found = 0;
struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
int secondary = 0;
if ((!ipaddr) || (!prefix)) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
if (found) {
goto out_clean;
}
ip = malloc(sizeof(struct nozzle_ip));
if (!ip) {
savederrno = errno;
err = -1 ;
goto out_clean;
}
memset(ip, 0, sizeof(struct nozzle_ip));
strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
if (!strchr(ip->ipaddr, ':')) {
ip->domain = AF_INET;
} else {
ip->domain = AF_INET6;
}
/*
* if user asks for an IPv6 address, but MTU < 1280
* store the IP and bring it up later if and when MTU > 1280
*/
if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
err = 0;
} else {
if (nozzle->ip) {
secondary = 1;
}
err = _set_ip(nozzle, IP_ADD, ipaddr, prefix, secondary);
savederrno = errno;
}
if (err) {
free(ip);
goto out_clean;
}
if (nozzle->ip) {
ip_last = nozzle->ip;
while (ip_last->next != NULL) {
ip_last = ip_last->next;
}
ip_last->next = ip;
} else {
nozzle->ip = ip;
}
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
{
int err = 0, savederrno = 0;
int found = 0;
struct nozzle_ip *ip = NULL, *ip_prev = NULL;
if ((!ipaddr) || (!prefix)) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
savederrno = EINVAL;
err = -1;
goto out_clean;
}
found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
if (!found) {
goto out_clean;
}
err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, 0);
savederrno = errno;
if (!err) {
if (ip == ip_prev) {
nozzle->ip = ip->next;
} else {
ip_prev->next = ip->next;
}
free(ip);
}
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip)
{
int err = 0, savederrno = 0;
if (!nozzle_ip) {
errno = EINVAL;
return -1;
}
savederrno = pthread_mutex_lock(&config_mutex);
if (savederrno) {
errno = savederrno;
return -1;
}
if (!is_valid_nozzle(nozzle)) {
err = -1;
savederrno = EINVAL;
goto out_clean;
}
*nozzle_ip = nozzle->ip;
out_clean:
pthread_mutex_unlock(&config_mutex);
errno = savederrno;
return err;
}
diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
index df3d9fb5..6baf09ee 100644
--- a/libnozzle/libnozzle.h
+++ b/libnozzle/libnozzle.h
@@ -1,314 +1,315 @@
/*
* Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
*
* Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#ifndef __LIBNOZZLE_H__
#define __LIBNOZZLE_H__
#include <sys/types.h>
#include <net/if.h>
/**
*
* @file libnozzle.h
* @brief tap interfaces management API include file
* @copyright Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
*
* nozzle is a commodity library to manage tap (ethernet) interfaces
*/
typedef struct nozzle_iface *nozzle_t;
/**
* nozzle_open
* @brief create a new tap device on the system.
*
* devname - pointer to device name of at least size IFNAMSIZ.
* if the dev strlen is 0, then the system will assign a name automatically.
* if a string is specified, the system will try to create a device with
* the specified name.
* NOTE: on FreeBSD the tap device names can only be tapX where X is a
* number from 0 to 255. On Linux such limitation does not apply.
* The name must be unique to the system. If an interface with the same
* name is already configured on the system, an error will be returned.
*
* devname_size - length of the buffer provided in dev (has to be at least IFNAMSIZ).
*
* updownpath - nozzle supports the typical filesystem structure to execute
* actions for: down.d post-down.d pre-up.d up.d
* in the form of:
* updownpath/<action>/<interface_name>
* updownpath specifies where to find those directories on the
* filesystem and it must be an absolute path.
*
* @return
* nozzle_open returns
* a pointer to a nozzle struct on success
* NULL on error and errno is set.
*/
nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath);
/**
* nozzle_close
* @brief deconfigure and destroy a nozzle device
*
* nozzle - pointer to the nozzle struct to destroy
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_close(nozzle_t nozzle);
#define NOZZLE_PREUP 0
#define NOZZLE_UP 1
#define NOZZLE_DOWN 2
#define NOZZLE_POSTDOWN 3
/**
* nozzle_run_updown
* @brief execute updown commands associated with a nozzle device. It is
* the application responsibility to call helper scripts
* before or after creating/destroying interfaces or IP addresses.
*
* nozzle - pointer to the nozzle struct
*
* action - pre-up.d / up.d / down.d / post-down.d (see defines above)
*
* exec_string - pointers to string to record executing action stdout/stderr.
* The string is malloc'ed, the caller needs to free the buffer.
* If the script generates no output this string might be NULL.
*
* @return
* 0 on success
- * -1 on error and errno is set.
+ * -1 on error and errno is set (sanity checks and internal calls.
+ * -2 on error from executing the shell scripts, and no errno is set.
*/
int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string);
/**
* nozzle_set_up
* @brief equivalent of ifconfig up
*
* nozzle - pointer to the nozzle struct
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_set_up(nozzle_t nozzle);
/**
* nozzle_set_down
* @brief equivalent of ifconfig down
*
* nozzle - pointer to the nozzle struct
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_set_down(nozzle_t nozzle);
/**
* nozzle_add_ip
* @brief equivalent of ip addr or ifconfig <ipaddress/prefix>
*
* nozzle - pointer to the nozzle struct
*
* ipaddr - string containing either an IPv4 or an IPv6 address.
* Please note that Linux will automatically remove any IPv6 addresses from an interface
* with MTU < 1280. libnozzle will cache those IPs and re-instate them when MTU is > 1280.
* MTU must be set via nozzle_set_mtu for IPv6 to be re-instated.
*
* prefix - 24, 64 or any valid network prefix for the requested address.
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
/**
* nozzle_del_ip
* @brief equivalent of ip addr del or ifconfig del <ipaddress/prefix>
*
* nozzle - pointer to the nozzle struct
*
* ipaddr - string containing either an IPv4 or an IPv6 address.
*
* prefix - 24, 64 or any valid network prefix for the requested address.
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
#define IPADDR_CHAR_MAX 128
#define PREFIX_CHAR_MAX 4
struct nozzle_ip {
char ipaddr[IPADDR_CHAR_MAX + 1];
char prefix[PREFIX_CHAR_MAX + 1];
int domain; /* AF_INET or AF_INET6 */
struct nozzle_ip *next;
};
/**
* nozzle_get_ips
* @brief retrive the list of all configured ips for a given interface
*
* nozzle - pointer to the nozzle struct
*
* nozzle_ip - pointer to the head of a list of nozzle_ip structs.
* The last IP will have next = NULL.
* nozzle_ip can be NULL if there are no IP addresses
* associated with this nozzle device.
* *DO NOT* free those structs as they are used internally
* for IP address tracking.
*
* @return
* 0 on success
* -1 on error and errno is set.
*
*/
int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip);
/**
* nozzle_get_mtu
* @brief retrive mtu on a given nozzle interface
*
* nozzle - pointer to the nozzle struct
*
* @return
* MTU on success
* -1 on error and errno is set.
*/
int nozzle_get_mtu(const nozzle_t nozzle);
/**
* nozzle_set_mtu
* @brief set mtu on a given nozzle interface
*
* nozzle - pointer to the nozzle struct
*
* mtu - new MTU value
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
/**
* nozzle_reset_mtu
* @brief reset mtu on a given nozzle interface to the system default
*
* nozzle - pointer to the nozzle struct
*
* @return
* 0 on success
* -1 on error and errno is set.
*/
int nozzle_reset_mtu(nozzle_t nozzle);
/**
* nozzle_get_mac
* @brief retrive mac address on a given nozzle interface
*
* nozzle - pointer to the nozzle struct
*
* ether_addr - pointers to string containing the current mac address.
* The string is malloc'ed, the caller needs to free this buffer.
* @return
* 0 on success.
* -1 on error and errno is set.
*/
int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
/**
* nozzle_set_mac
* @brief set mac address on a given nozzle interface
*
* nozzle - pointer to the nozzle struct
*
* ether_addr - pointers to string containing the new mac address.
*
* @return
* 0 on success.
* -1 on error and errno is set.
*/
int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
/**
* nozzle_reset_mac
* @brief reset mac address on a given nozzle interface to system default
*
* nozzle - pointer to the nozzle struct
*
* @return
* 0 on success.
* -1 on error and errno is set.
*/
int nozzle_reset_mac(nozzle_t nozzle);
/**
* nozzle_get_handle_by_name
* @brief find a nozzle handle by device name
*
* devname - string containing the name of the interface
*
* @return
* handle on success.
* NULL on error and errno is set.
*/
nozzle_t nozzle_get_handle_by_name(const char *devname);
/**
* nozzle_get_name_by_handle
* @brief retrive nozzle interface name by handle
*
* nozzle - pointer to the nozzle struct
*
* @return
* pointer to the interface name
* NULL on error and errno is set.
*/
const char *nozzle_get_name_by_handle(const nozzle_t nozzle);
/**
* nozzle_get_fd
* @brief
*
* nozzle - pointer to the nozzle struct
*
* @return
* fd associated to a given nozzle on success.
* -1 on error and errno is set.
*/
int nozzle_get_fd(const nozzle_t nozzle);
#endif
diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
index 4a53ea44..64af8388 100644
--- a/libnozzle/tests/Makefile.am
+++ b/libnozzle/tests/Makefile.am
@@ -1,112 +1,117 @@
#
# Copyright (C) 2017-2018 Red Hat, Inc. All rights reserved.
#
# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
#
# This software licensed under GPL-2.0+, LGPL-2.0+
#
MAINTAINERCLEANFILES = Makefile.in
include $(top_srcdir)/build-aux/check.mk
EXTRA_DIST = \
- tap_updown_bad \
- tap_updown_good \
+ nozzle_run_updown_exit_true \
+ nozzle_run_updown_exit_false \
api-test-coverage
noinst_HEADERS = \
test-common.h
if BUILD_LIBNOZZLE
api_checks = \
api_nozzle_open_test \
api_nozzle_close_test \
api_nozzle_set_up_test \
api_nozzle_set_down_test \
api_nozzle_get_mtu_test \
api_nozzle_set_mtu_test \
api_nozzle_get_mac_test \
api_nozzle_set_mac_test \
api_nozzle_get_handle_by_name_test \
api_nozzle_get_name_by_handle_test \
- api_nozzle_get_fd_test
+ api_nozzle_get_fd_test \
+ api_nozzle_run_updown_test
int_checks = \
int_execute_bin_sh_command_test \
nozzle_test
fun_checks =
benchmarks =
check_PROGRAMS = \
$(api_checks) \
$(int_checks) \
$(fun_checks)
noinst_PROGRAMS = \
$(benchmarks) \
$(check_PROGRAMS)
noinst_SCRIPTS = \
api-test-coverage
TESTS = $(check_PROGRAMS)
check-local: check-api-test-coverage
check-api-test-coverage:
chmod u+x $(top_srcdir)/libnozzle/tests/api-test-coverage
$(top_srcdir)/libnozzle/tests/api-test-coverage $(top_srcdir) $(top_builddir)
-AM_CPPFLAGS = -I$(top_srcdir)/libnozzle -DABSBUILDDIR=\"$(abs_builddir)\"
+AM_CPPFLAGS = -I$(top_srcdir)/libnozzle -DABSBUILDDIR=\"$(abs_builddir)\" -DABSSRCDIR=\"$(abs_srcdir)\"
AM_CFLAGS += $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
LIBS += $(top_builddir)/libnozzle/libnozzle.la $(PTHREAD_LIBS) $(libnl_LIBS)
api_nozzle_open_test_SOURCES = api_nozzle_open.c \
test-common.c
api_nozzle_close_test_SOURCES = api_nozzle_close.c \
test-common.c
api_nozzle_set_up_test_SOURCES = api_nozzle_set_up.c \
test-common.c \
../internals.c
api_nozzle_set_down_test_SOURCES = api_nozzle_set_down.c \
test-common.c \
../internals.c
api_nozzle_get_mtu_test_SOURCES = api_nozzle_get_mtu.c \
test-common.c
api_nozzle_set_mtu_test_SOURCES = api_nozzle_set_mtu.c \
test-common.c \
../internals.c
api_nozzle_get_mac_test_SOURCES = api_nozzle_get_mac.c \
test-common.c
api_nozzle_set_mac_test_SOURCES = api_nozzle_set_mac.c \
test-common.c
api_nozzle_get_handle_by_name_test_SOURCES = api_nozzle_get_handle_by_name.c \
test-common.c
api_nozzle_get_name_by_handle_test_SOURCES = api_nozzle_get_name_by_handle.c \
test-common.c
api_nozzle_get_fd_test_SOURCES = api_nozzle_get_fd.c \
test-common.c
+api_nozzle_run_updown_test_SOURCES = api_nozzle_run_updown.c \
+ test-common.c \
+ ../internals.c
+
int_execute_bin_sh_command_test_SOURCES = int_execute_bin_sh_command.c \
test-common.c \
../internals.c
nozzle_test_SOURCES = nozzle_test.c \
test-common.c \
../internals.c
endif
diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
new file mode 100644
index 00000000..89bf9095
--- /dev/null
+++ b/libnozzle/tests/api_nozzle_run_updown.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
+ *
+ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ *
+ * This software licensed under GPL-2.0+, LGPL-2.0+
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdint.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "test-common.h"
+
+static int test(void)
+{
+ char device_name[IFNAMSIZ];
+ size_t size = IFNAMSIZ;
+ int err=0;
+ nozzle_t nozzle = NULL;
+ char *error_string = NULL;
+ char *tmpdir = NULL;
+ char tmpdirsrc[PATH_MAX];
+ char tmpstr[PATH_MAX*2];
+ char srcfile[PATH_MAX];
+ char dstfile[PATH_MAX];
+
+ /*
+ * create a tmp dir for storing up/down scripts.
+ * we cannot create symlinks src dir
+ */
+ strcpy(tmpdirsrc, ABSBUILDDIR "/nozzle_test_XXXXXX");
+
+ tmpdir = mkdtemp(tmpdirsrc);
+ if (!tmpdir) {
+ printf("Unable to create temporary directory %s for testing: %s\n", tmpdirsrc, strerror(errno));
+ return -1;
+ }
+
+ printf("Created temporary test dir: %s\n", tmpdir);
+
+ printf("Populating test dir...\n");
+
+ snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/pre-up.d", tmpdir);
+ if (mkdir(tmpstr, 0700) < 0) {
+ printf("Unable to create %s/pre-up.d: %s", tmpdir, strerror(errno));
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/up.d", tmpdir);
+ if (mkdir(tmpstr, 0700) < 0) {
+ printf("Unable to create %s/up.d: %s", tmpdir, strerror(errno));
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/down.d", tmpdir);
+ if (mkdir(tmpstr, 0700) < 0) {
+ printf("Unable to create %s/down.d: %s", tmpdir, strerror(errno));
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/post-down.d", tmpdir);
+ if (mkdir(tmpstr, 0700) < 0) {
+ printf("Unable to create %s/post-down.d: %s", tmpdir, strerror(errno));
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing error conditions\n");
+
+ printf("Init nozzle device with no path\n");
+
+ memset(device_name, 0, size);
+ nozzle = nozzle_open(device_name, size, NULL);
+ if (!nozzle) {
+ printf("Unable to init %s\n", device_name);
+ err = -1;
+ goto out_clean;
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+ if ((!err) || (errno != EINVAL)) {
+ printf("nozzle_run_updown sanity check failed\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ nozzle_close(nozzle);
+
+ printf("Init nozzle device with path\n");
+
+ memset(device_name, 0, size);
+ nozzle = nozzle_open(device_name, size, tmpdir);
+ if (!nozzle) {
+ printf("Unable to init %s\n", device_name);
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing invalid nozzle handle\n");
+
+ err = nozzle_run_updown(NULL, NOZZLE_POSTDOWN, &error_string);
+ if ((!err) || (errno != EINVAL)) {
+ printf("nozzle_run_updown sanity check failed\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing invalid action\n");
+
+ err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN + 1, &error_string);
+ if ((!err) || (errno != EINVAL)) {
+ printf("nozzle_run_updown sanity check failed\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing invalid error string\n");
+
+ err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN + 1, NULL);
+ if ((!err) || (errno != EINVAL)) {
+ printf("nozzle_run_updown sanity check failed\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing interface pre-up/up/down/post-down (no scripts installed)\n");
+
+ err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
+ if (!err) {
+ printf("nozzle_run_updown failed to detect lack of script in pre-up.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
+ if (!err) {
+ printf("nozzle_run_updown failed to detect lack of script in up.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+ if (!err) {
+ printf("nozzle_run_updown failed to detect lack of script in down.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+ if (!err) {
+ printf("nozzle_run_updown failed to detect lack of script in post-down.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ printf("Populating test dir with fail scripts\n");
+
+ snprintf(srcfile, sizeof(srcfile) - 1, "%s/nozzle_run_updown_exit_false", ABSSRCDIR);
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/pre-up.d/%s", tmpdir, device_name);
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/up.d/%s", tmpdir, device_name);
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/down.d/%s", tmpdir, device_name);
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/post-down.d/%s", tmpdir, device_name);
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing interface pre-up/up/down/post-down (FAIL scripts installed)\n");
+
+ err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
+ if (err != -2) {
+ printf("nozzle_run_updown failed to detect script failure in pre-up.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
+ if (err != -2) {
+ printf("nozzle_run_updown failed to detect script failure in up.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+ if (err != -2) {
+ printf("nozzle_run_updown failed to detect script failure in down.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+ if (err != -2) {
+ printf("nozzle_run_updown failed to detect script failure in post-down.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ printf("Populating test dir with true scripts\n");
+
+ snprintf(srcfile, sizeof(srcfile) - 1, "%s/nozzle_run_updown_exit_true", ABSSRCDIR);
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/pre-up.d/%s", tmpdir, device_name);
+ if (unlink(dstfile) < 0) {
+ printf("unable to remove old symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/up.d/%s", tmpdir, device_name);
+ if (unlink(dstfile) < 0) {
+ printf("unable to remove old symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/down.d/%s", tmpdir, device_name);
+ if (unlink(dstfile) < 0) {
+ printf("unable to remove old symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ snprintf(dstfile, sizeof(dstfile) - 1, "%s/post-down.d/%s", tmpdir, device_name);
+ if (unlink(dstfile) < 0) {
+ printf("unable to remove old symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+ if (link(srcfile, dstfile) < 0) {
+ printf("unable to create symlink\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ printf("Testing interface pre-up/up/down/post-down (TRUE scripts installed)\n");
+
+ err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
+ if (err) {
+ printf("nozzle_run_updown failed to execute true script in pre-up.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
+ if (err) {
+ printf("nozzle_run_updown failed to execute true script in up.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+ if (err) {
+ printf("nozzle_run_updown failed to execite true script in down.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+ err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+ if (err) {
+ printf("nozzle_run_updown failed to execute true script in post-down.d\n");
+ err = -1;
+ goto out_clean;
+ } else {
+ if (error_string) {
+ free(error_string);
+ error_string = NULL;
+ }
+ }
+
+
+out_clean:
+ if (tmpdir) {
+ snprintf(tmpstr, sizeof(tmpstr) - 1, "rm -rf %s", tmpdir);
+ printf("Removing temporary dir: %s\n", tmpstr);
+ err = execute_bin_sh_command(tmpstr, &error_string);
+ if (err) {
+ printf("Error removing directory: %s\n", error_string);
+ }
+ if (error_string) {
+ free(error_string);
+ }
+ }
+ if (nozzle) {
+ nozzle_close(nozzle);
+ }
+
+ return err;
+}
+
+int main(void)
+{
+ need_root();
+
+ if (test() < 0)
+ return FAIL;
+
+ return PASS;
+}
diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
index b1b0a42f..c5a7e5d4 100644
--- a/libnozzle/tests/int_execute_bin_sh_command.c
+++ b/libnozzle/tests/int_execute_bin_sh_command.c
@@ -1,124 +1,121 @@
/*
* Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
*
* Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#include "config.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <limits.h>
#include <sys/socket.h>
#include "test-common.h"
static int test(void)
{
int err = 0;
- char command[4096];
char *error_string = NULL;
- memset(command, 0, sizeof(command));
-
printf("Testing execute_bin_sh_command\n");
printf("command true\n");
err = execute_bin_sh_command("true", &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (err) {
printf("Unable to execute true ?!?!\n");
goto out_clean;
}
printf("command false\n");
err = execute_bin_sh_command("false", &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
printf("Can we really execute false successfully?!?!\n");
err = -1;
goto out_clean;
}
printf("command that outputs to stdout (enforcing redirect)\n");
err = execute_bin_sh_command("grep -h 2>&1", &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
printf("Can we really execute grep -h successfully?!?\n");
err = -1;
goto out_clean;
}
printf("command that outputs to stderr\n");
err = execute_bin_sh_command("grep -h", &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
printf("Can we really execute grep -h successfully?!?\n");
err = -1;
goto out_clean;
}
printf("Testing ERROR conditions\n");
printf("empty command\n");
err = execute_bin_sh_command(NULL, &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if ((!err) || (errno != EINVAL)) {
printf("execute_bin_sh_command returned incorrect error or incorrect errno!\n");
err = -1;
goto out_clean;
}
printf("empty error\n");
err = execute_bin_sh_command("true", NULL);
if ((!err) || (errno != EINVAL)) {
printf("execute_bin_sh_command returned incorrect error or incorrect errno!\n");
err = -1;
goto out_clean;
}
err = 0;
out_clean:
return err;
}
int main(void)
{
need_root();
if (test() < 0)
return FAIL;
return PASS;
}
diff --git a/libnozzle/tests/tap_updown_bad/down.d/kronostest b/libnozzle/tests/nozzle_run_updown_exit_false
similarity index 100%
rename from libnozzle/tests/tap_updown_bad/down.d/kronostest
rename to libnozzle/tests/nozzle_run_updown_exit_false
diff --git a/libnozzle/tests/tap_updown_good/down.d/kronostest b/libnozzle/tests/nozzle_run_updown_exit_true
similarity index 100%
rename from libnozzle/tests/tap_updown_good/down.d/kronostest
rename to libnozzle/tests/nozzle_run_updown_exit_true
diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
index ad1ab79d..475035d0 100644
--- a/libnozzle/tests/nozzle_test.c
+++ b/libnozzle/tests/nozzle_test.c
@@ -1,478 +1,241 @@
/*
* Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
*
* Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
*
* This software licensed under GPL-2.0+, LGPL-2.0+
*/
#include "config.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <limits.h>
#include <sys/socket.h>
#include "test-common.h"
char testipv4_1[IPBUFSIZE];
char testipv4_2[IPBUFSIZE];
char testipv6_1[IPBUFSIZE];
char testipv6_2[IPBUFSIZE];
-static int check_knet_up_down(void)
-{
- char verifycmd[1024];
- char device_name[IFNAMSIZ];
- size_t size = IFNAMSIZ;
- int err=0;
- nozzle_t nozzle;
- char *error_string = NULL;
-
- printf("Testing interface up/down\n");
-
- memset(device_name, 0, size);
- nozzle = nozzle_open(device_name, size, NULL);
- if (!nozzle) {
- printf("Unable to init %s\n", device_name);
- return -1;
- }
-
- printf("Put the interface up\n");
-
- err = nozzle_set_up(nozzle);
- if (err < 0) {
- printf("Unable to set interface up\n");
- err = -1;
- goto out_clean;
- }
-
- memset(verifycmd, 0, sizeof(verifycmd));
- snprintf(verifycmd, sizeof(verifycmd)-1,
-#ifdef KNET_LINUX
- "ip addr show dev %s | grep -q UP", nozzle->name);
-#endif
-#ifdef KNET_BSD
- "ifconfig %s | grep -q UP", nozzle->name);
-#endif
- err = execute_bin_sh_command(verifycmd, &error_string);
- if (error_string) {
- printf("Error string: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
- if (err < 0) {
- printf("Unable to verify inteface UP\n");
- err = -1;
- goto out_clean;
- }
-
- printf("Put the interface down\n");
-
- err = nozzle_set_down(nozzle);
- if (err < 0) {
- printf("Unable to put the interface down\n");
- err = -1;
- goto out_clean;
- }
-
- memset(verifycmd, 0, sizeof(verifycmd));
- snprintf(verifycmd, sizeof(verifycmd)-1,
-#ifdef KNET_LINUX
- "ip addr show dev %s | grep -q UP", nozzle->name);
-#endif
-#ifdef KNET_BSD
- "ifconfig %s | grep -q UP", nozzle->name);
-#endif
- err = execute_bin_sh_command(verifycmd, &error_string);
- if (error_string) {
- printf("Error string: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
- if (!err) {
- printf("Unable to verify inteface DOWN\n");
- err = -1;
- goto out_clean;
- }
-
- nozzle_close(nozzle);
-
- printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
-
- memset(device_name, 0, size);
- nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
- if (!nozzle) {
- printf("Unable to init %s\n", device_name);
- return -1;
- }
-
- printf("Put the interface up\n");
-
- err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_PREUP error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("preup output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
- err = nozzle_set_up(nozzle);
- if (err < 0) {
- printf("Unable to put the interface up\n");
- err = -1;
- goto out_clean;
- }
- err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_UP error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("up output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
-
- printf("Put the interface down\n");
-
- err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("down output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
- err = nozzle_set_down(nozzle);
- if (err < 0) {
- printf("Unable to put the interface down\n");
- err = -1;
- goto out_clean;
- }
- err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("postdown output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
-
- nozzle_close(nozzle);
-
- printf("Testing interface pre-up/up/down/post-down\n");
-
- memset(device_name, 0, size);
-
- nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
- if (!nozzle) {
- printf("Unable to init %s\n", device_name);
- return -1;
- }
-
- printf("Put the interface up\n");
-
- err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_PREUP error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("preup output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
- err = nozzle_set_up(nozzle);
- if (err < 0) {
- printf("Unable to put the interface up\n");
- err = -1;
- goto out_clean;
- }
- err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_UP error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("up output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
-
- printf("Put the interface down\n");
-
- err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("down output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
- err = nozzle_set_down(nozzle);
- if (err < 0) {
- printf("Unable to put the interface down\n");
- err = -1;
- goto out_clean;
- }
- err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
- if (err) {
- printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
- }
- if (error_string) {
- printf("postdown output: %s\n", error_string);
- free(error_string);
- error_string = NULL;
- }
-
- nozzle_close(nozzle);
-
- printf("Test ERROR conditions\n");
-
- printf("Pass NULL to nozzle set_up\n");
- err = 0;
- errno = 0;
- if ((nozzle_set_up(NULL) >= 0) || (errno != EINVAL)) {
- printf("Something is wrong in nozzle_set_up sanity checks\n");
- err = -1;
- goto out_clean;
- }
-
- printf("Pass NULL to nozzle set_down\n");
- errno = 0;
- if ((nozzle_set_down(NULL) >= 0) || (errno != EINVAL)) {
- printf("Something is wrong in nozzle_set_down sanity checks\n");
- err = -1;
- goto out_clean;
- }
-
-out_clean:
- nozzle_close(nozzle);
-
- return err;
-}
-
static int check_knet_set_del_ip(void)
{
char device_name[IFNAMSIZ];
size_t size = IFNAMSIZ;
char verifycmd[2048];
int err = 0;
nozzle_t nozzle;
struct nozzle_ip *ip_list = NULL, *ip_list_tmp = NULL;
int ip_list_entries = 0;
char *error_string = NULL;
printf("Testing interface add/remove ip\n");
memset(device_name, 0, size);
nozzle = nozzle_open(device_name, size, NULL);
if (!nozzle) {
printf("Unable to init %s\n", device_name);
return -1;
}
printf("Adding ip: %s/24\n", testipv4_1);
err = nozzle_add_ip(nozzle, testipv4_1, "24");
if (err < 0) {
printf("Unable to assign IP address\n");
err=-1;
goto out_clean;
}
printf("Adding ip: %s/24\n", testipv4_2);
err = nozzle_add_ip(nozzle, testipv4_2, "24");
if (err < 0) {
printf("Unable to assign IP address\n");
err=-1;
goto out_clean;
}
printf("Adding duplicate ip: %s/24\n", testipv4_1);
err = nozzle_add_ip(nozzle, testipv4_1, "24");
if (err < 0) {
printf("Unable to find IP address in libnozzle db\n");
err=-1;
goto out_clean;
}
printf("Checking ip: %s/24\n", testipv4_1);
memset(verifycmd, 0, sizeof(verifycmd));
snprintf(verifycmd, sizeof(verifycmd)-1,
#ifdef KNET_LINUX
"ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
#endif
#ifdef KNET_BSD
"ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
#endif
err = execute_bin_sh_command(verifycmd, &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (err) {
printf("Unable to verify IP address\n");
err=-1;
goto out_clean;
}
printf("Get ip list from libnozzle:\n");
if (nozzle_get_ips(nozzle, &ip_list) < 0) {
printf("Not enough mem?\n");
err=-1;
goto out_clean;
}
ip_list_tmp = ip_list;
ip_list_entries = 0;
while(ip_list_tmp) {
ip_list_entries++;
printf("Found IP %s %s in libnozzle db\n", ip_list_tmp->ipaddr, ip_list_tmp->prefix);
ip_list_tmp = ip_list_tmp->next;
}
if (ip_list_entries != 2) {
printf("Didn't get enough ip back from libnozzle?\n");
err=-1;
goto out_clean;
}
printf("Deleting ip: %s/24\n", testipv4_1);
err = nozzle_del_ip(nozzle, testipv4_1, "24");
if (err < 0) {
printf("Unable to delete IP address\n");
err=-1;
goto out_clean;
}
printf("Deleting ip: %s/24\n", testipv4_2);
err = nozzle_del_ip(nozzle, testipv4_2, "24");
if (err < 0) {
printf("Unable to delete IP address\n");
err=-1;
goto out_clean;
}
printf("Deleting again ip: %s/24\n", testipv4_1);
err = nozzle_del_ip(nozzle, testipv4_1, "24");
if (err < 0) {
printf("Unable to delete IP address\n");
err=-1;
goto out_clean;
}
memset(verifycmd, 0, sizeof(verifycmd));
snprintf(verifycmd, sizeof(verifycmd)-1,
#ifdef KNET_LINUX
"ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
#endif
#ifdef KNET_BSD
"ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
#endif
err = execute_bin_sh_command(verifycmd, &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
printf("Unable to verify IP address\n");
err=-1;
goto out_clean;
}
printf("Adding ip: %s/64\n", testipv6_1);
err = nozzle_add_ip(nozzle, testipv6_1, "64");
if (err < 0) {
printf("Unable to assign IP address\n");
err=-1;
goto out_clean;
}
memset(verifycmd, 0, sizeof(verifycmd));
snprintf(verifycmd, sizeof(verifycmd)-1,
#ifdef KNET_LINUX
"ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
#endif
#ifdef KNET_BSD
"ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
#endif
err = execute_bin_sh_command(verifycmd, &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (err) {
printf("Unable to verify IP address\n");
err=-1;
goto out_clean;
}
printf("Deleting ip: %s/64\n", testipv6_1);
err = nozzle_del_ip(nozzle, testipv6_1, "64");
if (err) {
printf("Unable to delete IP address\n");
err=-1;
goto out_clean;
}
memset(verifycmd, 0, sizeof(verifycmd));
snprintf(verifycmd, sizeof(verifycmd)-1,
#ifdef KNET_LINUX
"ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
#endif
#ifdef KNET_BSD
"ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
#endif
err = execute_bin_sh_command(verifycmd, &error_string);
if (error_string) {
printf("Error string: %s\n", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
printf("Unable to verify IP address\n");
err=-1;
goto out_clean;
}
out_clean:
nozzle_close(nozzle);
return err;
}
int main(void)
{
need_root();
make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
- if (check_knet_up_down() < 0)
- return -1;
-
if (check_knet_set_del_ip() < 0)
return -1;
return 0;
}
diff --git a/libnozzle/tests/tap_updown_bad/post-down.d/kronostest b/libnozzle/tests/tap_updown_bad/post-down.d/kronostest
deleted file mode 100755
index 721ecb6e..00000000
--- a/libnozzle/tests/tap_updown_bad/post-down.d/kronostest
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-#
-# Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
-#
-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
-#
-# This software licensed under GPL-2.0+, LGPL-2.0+
-#
-
-exit 1
diff --git a/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest b/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
deleted file mode 100755
index 721ecb6e..00000000
--- a/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-#
-# Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
-#
-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
-#
-# This software licensed under GPL-2.0+, LGPL-2.0+
-#
-
-exit 1
diff --git a/libnozzle/tests/tap_updown_bad/up.d/kronostest b/libnozzle/tests/tap_updown_bad/up.d/kronostest
deleted file mode 100755
index 721ecb6e..00000000
--- a/libnozzle/tests/tap_updown_bad/up.d/kronostest
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-#
-# Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
-#
-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
-#
-# This software licensed under GPL-2.0+, LGPL-2.0+
-#
-
-exit 1
diff --git a/libnozzle/tests/tap_updown_good/post-down.d/kronostest b/libnozzle/tests/tap_updown_good/post-down.d/kronostest
deleted file mode 100755
index 6e28da18..00000000
--- a/libnozzle/tests/tap_updown_good/post-down.d/kronostest
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-#
-# Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
-#
-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
-#
-# This software licensed under GPL-2.0+, LGPL-2.0+
-#
-
-exit 0
diff --git a/libnozzle/tests/tap_updown_good/pre-up.d/kronostest b/libnozzle/tests/tap_updown_good/pre-up.d/kronostest
deleted file mode 100755
index 6e28da18..00000000
--- a/libnozzle/tests/tap_updown_good/pre-up.d/kronostest
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-#
-# Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
-#
-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
-#
-# This software licensed under GPL-2.0+, LGPL-2.0+
-#
-
-exit 0
diff --git a/libnozzle/tests/tap_updown_good/up.d/kronostest b/libnozzle/tests/tap_updown_good/up.d/kronostest
deleted file mode 100755
index 6e28da18..00000000
--- a/libnozzle/tests/tap_updown_good/up.d/kronostest
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-#
-# Copyright (C) 2010-2018 Red Hat, Inc. All rights reserved.
-#
-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
-#
-# This software licensed under GPL-2.0+, LGPL-2.0+
-#
-
-exit 0

File Metadata

Mime Type
text/x-diff
Expires
Tue, Feb 25, 1:09 AM (22 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1464580
Default Alt Text
(61 KB)

Event Timeline