Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4512513
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
38 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/libknet/Makefile.am b/libknet/Makefile.am
index 25d95a62..4843d749 100644
--- a/libknet/Makefile.am
+++ b/libknet/Makefile.am
@@ -1,20 +1,20 @@
MAINTAINERCLEANFILES = Makefile.in
LIBS = -lpthread \
-version-info $(libversion)
libversion = 0:0:0
sources = \
- ring.c \
+ handle.c \
host.c \
listener.c
include_HEADERS = libknet.h
noinst_HEADERS = libknet-private.h
noinst_LIBRARIES = libknet.a
#lib_LTLIBRARIES = libknet.la
libknet_a_SOURCES = $(sources)
#libknet_la_SOURCES = $(sources)
diff --git a/libknet/ring.c b/libknet/handle.c
similarity index 100%
rename from libknet/ring.c
rename to libknet/handle.c
diff --git a/libtap/Makefile.am b/libtap/Makefile.am
index ded1ee42..79c99d49 100644
--- a/libtap/Makefile.am
+++ b/libtap/Makefile.am
@@ -1,26 +1,26 @@
MAINTAINERCLEANFILES = Makefile.in
LIBS = -lpthread \
-version-info $(libversion)
sources = libtap.c
libversion = 0:0:0
include_HEADERS = libtap.h
-noinst_HEADERS = libtap_private.h
+noinst_HEADERS = libtap-private.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libtap.pc
lib_LTLIBRARIES = libtap.la
noinst_LTLIBRARIES = libtap_test.la
libtap_test_la_SOURCES = $(sources)
libtap_test_la_CPPFLAGS = -DTEST
libtap_la_SOURCES = $(sources)
diff --git a/libtap/libtap_private.h b/libtap/libtap-private.h
similarity index 100%
rename from libtap/libtap_private.h
rename to libtap/libtap-private.h
diff --git a/libtap/libtap.c b/libtap/libtap.c
index 46c6dd27..3dc366f8 100644
--- a/libtap/libtap.c
+++ b/libtap/libtap.c
@@ -1,862 +1,862 @@
#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 <linux/if_tun.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <limits.h>
#include <stdio.h>
#include "libtap.h"
-#include "libtap_private.h"
+#include "libtap-private.h"
STATIC int tap_init = 0;
STATIC struct tap_config tap_cfg;
STATIC pthread_mutex_t tap_mutex = PTHREAD_MUTEX_INITIALIZER;
/* forward declarations */
STATIC int tap_execute_shell(const char *command, char **error_string);
static int tap_exec_updown(const knet_tap_t knet_tap, const char *action, char **error_string);
static int tap_set_down(knet_tap_t knet_tap);
static int tap_read_pipe(int fd, char **file, size_t *length);
static int tap_check(const knet_tap_t knet_tap);
static void tap_close(knet_tap_t knet_tap);
static void tap_close_cfg(void);
static int tap_get_mtu(const knet_tap_t knet_tap);
static int tap_get_mac(const knet_tap_t knet_tap, char **ether_addr);
static int tap_set_down(knet_tap_t knet_tap);
static char *tap_get_v4_broadcast(const char *ip_addr, const char *prefix);
static int tap_set_ip(knet_tap_t knet_tap, const char *command,
const char *ip_addr, const char *prefix,
char **error_string);
static int tap_find_ip(knet_tap_t knet_tap,
const char *ip_addr, const char *prefix,
struct tap_ip **tap_ip, struct tap_ip **tap_ip_prev);
static int tap_read_pipe(int fd, char **file, size_t *length)
{
char buf[4096];
int n;
int done = 0;
*file = NULL;
*length = 0;
memset(buf, 0, sizeof(buf));
while (!done) {
n = read(fd, buf, sizeof(buf));
if (n < 0) {
if (errno == EINTR)
continue;
if (*file)
free(*file);
return n;
}
if (n == 0 && (!*length))
return 0;
if (n == 0)
done = 1;
if (*file)
*file = realloc(*file, (*length) + n + done);
else
*file = malloc(n + done);
if (!*file)
return -1;
memcpy((*file) + (*length), buf, n);
*length += (done + n);
}
/* Null terminator */
(*file)[(*length) - 1] = 0;
return 0;
}
STATIC int tap_execute_shell(const char *command, char **error_string)
{
pid_t pid;
int status, err = 0;
int fd[2];
size_t size = 0;
if ((command == NULL) || (!error_string)) {
errno = EINVAL;
return -1;
}
*error_string = NULL;
err = pipe(fd);
if (err)
goto out_clean;
pid = fork();
if (pid < 0) {
err = pid;
goto out_clean;
}
if (pid) { /* parent */
close(fd[1]);
err = tap_read_pipe(fd[0], error_string, &size);
if (err)
goto out_clean;
waitpid(pid, &status, 0);
if (!WIFEXITED(status)) {
err = -1;
goto out_clean;
}
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
err = WEXITSTATUS(status);
goto out_clean;
}
} else { /* child */
close(0);
close(1);
close(2);
close(fd[0]);
dup2(fd[1], 1);
dup2(fd[1], 2);
close(fd[1]);
execlp("/bin/sh", "/bin/sh", "-c", command, NULL);
exit(EXIT_FAILURE);
}
out_clean:
close(fd[0]);
close(fd[1]);
return err;
}
static int tap_exec_updown(const knet_tap_t knet_tap, const char *action, char **error_string)
{
char command[PATH_MAX];
if (!knet_tap->hasupdown)
return 0;
memset(command, 0, PATH_MAX);
snprintf(command, PATH_MAX, "%s%s/%s", knet_tap->updownpath, action, knet_tap->ifname);
return tap_execute_shell(command, error_string);
}
static int tap_check(const knet_tap_t knet_tap)
{
knet_tap_t temp = tap_cfg.tap_head;
if (!knet_tap)
return 0;
while (temp != NULL) {
if (knet_tap == temp)
return 1;
temp = temp->next;
}
return 0;
}
static void tap_close(knet_tap_t knet_tap)
{
if (!knet_tap)
return;
if (knet_tap->knet_tap_fd)
close(knet_tap->knet_tap_fd);
free(knet_tap);
return;
}
static void tap_close_cfg(void)
{
if (tap_cfg.tap_head == NULL) {
close(tap_cfg.tap_sockfd);
tap_init = 0;
}
}
static int tap_get_mtu(const knet_tap_t knet_tap)
{
int err;
err = ioctl(tap_cfg.tap_sockfd, SIOCGIFMTU, &knet_tap->ifr);
if (err)
goto out_clean;
err = knet_tap->ifr.ifr_mtu;
out_clean:
return err;
}
static int tap_get_mac(const knet_tap_t knet_tap, char **ether_addr)
{
int err;
char mac[MAX_MAC_CHAR];
err = ioctl(tap_cfg.tap_sockfd, SIOCGIFHWADDR, &knet_tap->ifr);
if (err)
goto out_clean;
ether_ntoa_r((struct ether_addr *)knet_tap->ifr.ifr_hwaddr.sa_data, mac);
*ether_addr = strdup(mac);
if (!*ether_addr)
err = -1;
out_clean:
return err;
}
knet_tap_t knet_tap_find(char *dev, size_t dev_size)
{
knet_tap_t knet_tap;
if (dev == NULL) {
errno = EINVAL;
return NULL;
}
if (dev_size < IFNAMSIZ) {
errno = EINVAL;
return NULL;
}
if (strlen(dev) > IFNAMSIZ) {
errno = E2BIG;
return NULL;
}
pthread_mutex_lock(&tap_mutex);
knet_tap = tap_cfg.tap_head;
while (knet_tap != NULL) {
if (!strcmp(dev, knet_tap->ifname))
break;
knet_tap = knet_tap->next;
}
pthread_mutex_unlock(&tap_mutex);
return knet_tap;
}
knet_tap_t knet_tap_open(char *dev, size_t dev_size, const char *updownpath)
{
knet_tap_t knet_tap;
char *temp_mac = NULL;
if (dev == NULL) {
errno = EINVAL;
return NULL;
}
if (dev_size < IFNAMSIZ) {
errno = EINVAL;
return NULL;
}
if (strlen(dev) > IFNAMSIZ) {
errno = E2BIG;
return NULL;
}
if (updownpath) {
/* only absolute paths */
if (updownpath[0] != '/') {
errno = EINVAL;
return NULL;
}
/* 14: 2 for /, 1 for \0 + 11 (post-down.d) */
if (strlen(updownpath) >= (PATH_MAX - (strlen(dev) + 14))) {
errno = E2BIG;
return NULL;
}
}
pthread_mutex_lock(&tap_mutex);
knet_tap = malloc(sizeof(struct tap_iface));
if (!knet_tap)
return NULL;
memset(knet_tap, 0, sizeof(struct tap_iface));
if ((knet_tap->knet_tap_fd = open("/dev/net/tun", O_RDWR)) < 0)
goto out_error;
strncpy(knet_tap->ifname, dev, IFNAMSIZ);
knet_tap->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
if (ioctl(knet_tap->knet_tap_fd, TUNSETIFF, &knet_tap->ifr) < 0)
goto out_error;
if ((strlen(dev) > 0) && (strcmp(dev, knet_tap->ifname) != 0)) {
errno = EBUSY;
goto out_error;
}
strcpy(dev, knet_tap->ifname);
if (!tap_init) {
tap_cfg.tap_head = NULL;
tap_cfg.tap_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (tap_cfg.tap_sockfd < 0)
goto out_error;
tap_init = 1;
}
if (ioctl(tap_cfg.tap_sockfd, SIOGIFINDEX, &knet_tap->ifr) < 0)
goto out_error;
knet_tap->default_mtu = tap_get_mtu(knet_tap);
if (knet_tap->default_mtu < 0)
goto out_error;
if (tap_get_mac(knet_tap, &temp_mac) < 0)
goto out_error;
strncpy(knet_tap->default_mac, temp_mac, 18);
free(temp_mac);
if (updownpath) {
int len = strlen(updownpath);
strcpy(knet_tap->updownpath, updownpath);
if (knet_tap->updownpath[len-1] != '/') {
knet_tap->updownpath[len] = '/';
}
knet_tap->hasupdown = 1;
}
knet_tap->next = tap_cfg.tap_head;
tap_cfg.tap_head = knet_tap;
pthread_mutex_unlock(&tap_mutex);
return knet_tap;
out_error:
tap_close(knet_tap);
tap_close_cfg();
pthread_mutex_unlock(&tap_mutex);
return NULL;
}
int knet_tap_close(knet_tap_t knet_tap)
{
int err = 0;
knet_tap_t temp = tap_cfg.tap_head;
knet_tap_t prev = tap_cfg.tap_head;
struct tap_ip *tap_ip, *tap_ip_next;
char *error_string = NULL;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
while ((temp) && (temp != knet_tap)) {
prev = temp;
temp = temp->next;
}
if (knet_tap == prev) {
tap_cfg.tap_head = knet_tap->next;
} else {
prev->next = knet_tap->next;
}
tap_set_down(knet_tap);
tap_ip = knet_tap->tap_ip;
while (tap_ip) {
tap_ip_next = tap_ip->next;
tap_set_ip(knet_tap, "del", tap_ip->ip_addr, tap_ip->prefix, &error_string);
if (error_string)
free(error_string);
free(tap_ip);
tap_ip = tap_ip_next;
}
tap_close(knet_tap);
tap_close_cfg();
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_get_mtu(const knet_tap_t knet_tap)
{
int err;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
err = tap_get_mtu(knet_tap);
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_set_mtu(knet_tap_t knet_tap, const int mtu)
{
int err, oldmtu;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
oldmtu = knet_tap->ifr.ifr_mtu;
knet_tap->ifr.ifr_mtu = mtu;
err = ioctl(tap_cfg.tap_sockfd, SIOCSIFMTU, &knet_tap->ifr);
if (err)
knet_tap->ifr.ifr_mtu = oldmtu;
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_reset_mtu(knet_tap_t knet_tap)
{
return knet_tap_set_mtu(knet_tap, knet_tap->default_mtu);
}
int knet_tap_get_mac(const knet_tap_t knet_tap, char **ether_addr)
{
int err;
pthread_mutex_lock(&tap_mutex);
if ((!tap_check(knet_tap)) || (!ether_addr)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
err = tap_get_mac(knet_tap, ether_addr);
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_set_mac(knet_tap_t knet_tap, const char *ether_addr)
{
struct ether_addr oldmac;
int err;
pthread_mutex_lock(&tap_mutex);
if ((!tap_check(knet_tap)) || (!ether_addr)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
memcpy(&oldmac, knet_tap->ifr.ifr_hwaddr.sa_data, ETH_ALEN);
memcpy(knet_tap->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
err = ioctl(tap_cfg.tap_sockfd, SIOCSIFHWADDR, &knet_tap->ifr);
if (err)
memcpy(knet_tap->ifr.ifr_hwaddr.sa_data, &oldmac, ETH_ALEN);
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_reset_mac(knet_tap_t knet_tap)
{
return knet_tap_set_mac(knet_tap, knet_tap->default_mac);
}
int knet_tap_set_up(knet_tap_t knet_tap)
{
int err = 0;
short int oldflags;
char *error_string = NULL;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
if (knet_tap->up)
goto out_clean;
tap_exec_updown(knet_tap, "pre-up.d", &error_string);
if (error_string)
free(error_string);
oldflags = knet_tap->ifr.ifr_flags;
knet_tap->ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
err=ioctl(tap_cfg.tap_sockfd, SIOCSIFFLAGS, &knet_tap->ifr);
if (err)
knet_tap->ifr.ifr_flags = oldflags;
tap_exec_updown(knet_tap, "up.d", &error_string);
if (error_string)
free(error_string);
knet_tap->up = 1;
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
static int tap_set_down(knet_tap_t knet_tap)
{
int err = 0;
short int oldflags;
char *error_string = NULL;
if (!knet_tap->up)
goto out_clean;
tap_exec_updown(knet_tap, "down.d", &error_string);
if (error_string)
free(error_string);
oldflags = knet_tap->ifr.ifr_flags;
knet_tap->ifr.ifr_flags &= ~IFF_UP;
err=ioctl(tap_cfg.tap_sockfd, SIOCSIFFLAGS, &knet_tap->ifr);
if (err) {
knet_tap->ifr.ifr_flags = oldflags;
goto out_clean;
}
tap_exec_updown(knet_tap, "post-down.d", &error_string);
if (error_string)
free(error_string);
knet_tap->up = 0;
out_clean:
return err;
}
int knet_tap_set_down(knet_tap_t knet_tap)
{
int err = 0;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
err=tap_set_down(knet_tap);
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
static char *tap_get_v4_broadcast(const char *ip_addr, const char *prefix)
{
int prefix_len;
struct in_addr mask;
struct in_addr broadcast;
struct in_addr address;
prefix_len = atoi(prefix);
if ((prefix_len > 32) || (prefix_len < 0))
return NULL;
if (inet_pton(AF_INET, ip_addr, &address) <= 0)
return NULL;
mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
memset(&broadcast, 0, sizeof(broadcast));
broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
return strdup(inet_ntoa(broadcast));
}
static int tap_set_ip(knet_tap_t knet_tap, const char *command,
const char *ip_addr, const char *prefix,
char **error_string)
{
char *broadcast = NULL;
char cmdline[4096];
if (!strchr(ip_addr, ':')) {
broadcast = tap_get_v4_broadcast(ip_addr, prefix);
if (!broadcast) {
errno = EINVAL;
return -1;
}
}
memset(cmdline, 0, sizeof(cmdline));
if (broadcast) {
snprintf(cmdline, sizeof(cmdline)-1,
"ip addr %s %s/%s dev %s broadcast %s",
command, ip_addr, prefix,
knet_tap->ifname, broadcast);
free(broadcast);
} else {
snprintf(cmdline, sizeof(cmdline)-1,
"ip addr %s %s/%s dev %s",
command, ip_addr, prefix,
knet_tap->ifname);
}
return tap_execute_shell(cmdline, error_string);
}
static int tap_find_ip(knet_tap_t knet_tap,
const char *ip_addr, const char *prefix,
struct tap_ip **tap_ip, struct tap_ip **tap_ip_prev)
{
struct tap_ip *local_tap_ip, *local_tap_ip_prev;
int found = 0;
local_tap_ip = local_tap_ip_prev = knet_tap->tap_ip;
while(local_tap_ip) {
if ((!strcmp(local_tap_ip->ip_addr, ip_addr)) && (!strcmp(local_tap_ip->prefix, prefix))) {
found = 1;
break;
}
local_tap_ip_prev = local_tap_ip;
local_tap_ip = local_tap_ip->next;
}
if (found) {
*tap_ip = local_tap_ip;
*tap_ip_prev = local_tap_ip_prev;
}
return found;
}
int knet_tap_add_ip(knet_tap_t knet_tap, const char *ip_addr, const char *prefix)
{
int err = 0, found;
struct tap_ip *tap_ip = NULL, *tap_ip_prev = NULL;
char *error_string = NULL;
pthread_mutex_lock(&tap_mutex);
if ((!tap_check(knet_tap)) || (!ip_addr) || (!prefix)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
found = tap_find_ip(knet_tap, ip_addr, prefix, &tap_ip, &tap_ip_prev);
if (found)
goto out_clean;
tap_ip = malloc(sizeof(struct tap_ip));
if (!tap_ip) {
err = -1 ;
goto out_clean;
}
memset(tap_ip, 0, sizeof(struct tap_ip));
strncpy(tap_ip->ip_addr, ip_addr, MAX_IP_CHAR);
strncpy(tap_ip->prefix, prefix, MAX_PREFIX_CHAR);
err = tap_set_ip(knet_tap, "add", ip_addr, prefix, &error_string);
if (error_string)
free(error_string);
if (err) {
free(tap_ip);
goto out_clean;
}
tap_ip->next = knet_tap->tap_ip;
knet_tap->tap_ip = tap_ip;
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_del_ip(knet_tap_t knet_tap, const char *ip_addr, const char *prefix)
{
int err = 0, found;
struct tap_ip *tap_ip = NULL, *tap_ip_prev = NULL;
char *error_string = NULL;
pthread_mutex_lock(&tap_mutex);
if ((!tap_check(knet_tap)) || (!ip_addr) || (!prefix)) {
errno = EINVAL;
err = -1;
goto out_clean;
}
found = tap_find_ip(knet_tap, ip_addr, prefix, &tap_ip, &tap_ip_prev);
if (!found)
goto out_clean;
err = tap_set_ip(knet_tap, "del", ip_addr, prefix, &error_string);
if (error_string)
free(error_string);
if (!err) {
if (tap_ip == tap_ip_prev) {
knet_tap->tap_ip = tap_ip->next;
} else {
tap_ip_prev->next = tap_ip->next;
}
free(tap_ip);
}
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
int knet_tap_get_fd(const knet_tap_t knet_tap)
{
int fd;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
fd = -1;
goto out_clean;
}
fd = knet_tap->knet_tap_fd;
out_clean:
pthread_mutex_unlock(&tap_mutex);
return fd;
}
const char *knet_tap_get_name(const knet_tap_t knet_tap)
{
char *name = NULL;
pthread_mutex_lock(&tap_mutex);
if (!tap_check(knet_tap)) {
errno = EINVAL;
goto out_clean;
}
name = knet_tap->ifname;
out_clean:
pthread_mutex_unlock(&tap_mutex);
return name;
}
int knet_tap_get_ips(const knet_tap_t knet_tap, char **ip_addr_list, int *entries)
{
int err = 0;
int found = 0;
char *ip_list = NULL;
int size = 0, offset = 0, len;
struct tap_ip *tap_ip = knet_tap->tap_ip;
pthread_mutex_lock(&tap_mutex);
while (tap_ip) {
found++;
tap_ip = tap_ip->next;
}
size = found * (MAX_IP_CHAR + MAX_PREFIX_CHAR + 2);
ip_list = malloc(size);
if (!ip_list) {
err = -1;
goto out_clean;
}
memset(ip_list, 0, size);
tap_ip = knet_tap->tap_ip;
while (tap_ip) {
len = strlen(tap_ip->ip_addr);
memcpy(ip_list + offset, tap_ip->ip_addr, len);
offset = offset + len + 1;
len = strlen(tap_ip->prefix);
memcpy(ip_list + offset, tap_ip->prefix, len);
offset = offset + len + 1;
tap_ip = tap_ip->next;
}
*ip_addr_list = ip_list;
*entries = found;
out_clean:
pthread_mutex_unlock(&tap_mutex);
return err;
}
diff --git a/tests/tap_test.c b/tests/tap_test.c
index 3de67ebc..890e97ee 100644
--- a/tests/tap_test.c
+++ b/tests/tap_test.c
@@ -1,869 +1,869 @@
#include "config.h"
#include <string.h>
#include <errno.h>
#include <net/if.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/ether.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include "libtap.h"
-#include "libtap_private.h"
+#include "libtap-private.h"
#include "utils.h"
extern struct tap_config tap_cfg;
extern int tap_execute_shell(const char *command, char **error_string);
static int is_if_in_system(char *name)
{
struct ifaddrs *ifap = NULL;
struct ifaddrs *ifa;
int found = 0;
if (getifaddrs(&ifap) < 0) {
log_error("Unable to get interface list.");
return -1;
}
ifa = ifap;
while (ifa) {
if (!strncmp(name, ifa->ifa_name, IFNAMSIZ)) {
found = 1;
break;
}
ifa=ifa->ifa_next;
}
freeifaddrs(ifap);
return found;
}
static int test_iface(char *name, size_t size, const char *updownpath)
{
knet_tap_t knet_tap;
knet_tap=knet_tap_open(name, size, updownpath);
if (!knet_tap) {
if (tap_cfg.tap_sockfd < 0)
log_error("Unable to open knet_socket");
log_error("Unable to open knet.");
return -1;
}
log_info("Created interface: %s", name);
if (is_if_in_system(name) > 0) {
log_info("Found interface %s on the system", name);
} else {
log_info("Unable to find interface %s on the system", name);
}
if (!knet_tap_find(name, size)) {
log_info("Unable to find interface %s in tap db", name);
} else {
log_info("Found interface %s in tap db", name);
}
knet_tap_close(knet_tap);
if (is_if_in_system(name) == 0)
log_info("Successfully removed interface %s from the system", name);
return 0;
}
static int check_knet_tap_open_close(void)
{
char device_name[2*IFNAMSIZ];
char fakepath[PATH_MAX];
size_t size = IFNAMSIZ;
memset(device_name, 0, sizeof(device_name));
log_info("Creating random tap interface:");
if (test_iface(device_name, size, NULL) < 0) {
log_error("Unable to create random interface");
return -1;
}
log_info("Creating kronostest tap interface:");
strncpy(device_name, "kronostest", IFNAMSIZ);
if (test_iface(device_name, size, NULL) < 0) {
log_error("Unable to create kronosnet interface");
return -1;
}
log_info("Testing ERROR conditions");
log_info("Testing dev == NULL");
errno=0;
if ((test_iface(NULL, size, NULL) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_open sanity checks");
return -1;
}
log_info("Testing size < IFNAMSIZ");
errno=0;
if ((test_iface(device_name, 1, NULL) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_open sanity checks");
return -1;
}
log_info("Testing device_name size > IFNAMSIZ");
errno=0;
strcpy(device_name, "abcdefghilmnopqrstuvwz");
if ((test_iface(device_name, IFNAMSIZ, NULL) >= 0) || (errno != E2BIG)) {
log_error("Something is wrong in knet_tap_open sanity checks");
return -1;
}
log_info("Testing updown path != abs");
errno=0;
strcpy(device_name, "kronostest");
if ((test_iface(device_name, IFNAMSIZ, "foo") >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_open sanity checks");
return -1;
}
memset(fakepath, '/', PATH_MAX - 2);
fakepath[PATH_MAX-1] = 0;
log_info("Testing updown path > PATH_MAX");
errno=0;
strcpy(device_name, "kronostest");
if ((test_iface(device_name, IFNAMSIZ, fakepath) >= 0) || (errno != E2BIG)) {
log_error("Something is wrong in knet_tap_open sanity checks");
return -1;
}
return 0;
}
static int check_knet_multi_eth(void)
{
char device_name1[IFNAMSIZ];
char device_name2[IFNAMSIZ];
size_t size = IFNAMSIZ;
int err=0;
knet_tap_t knet_tap1 = NULL;
knet_tap_t knet_tap2 = NULL;
log_info("Testing multiple knet interface instances");
memset(device_name1, 0, size);
memset(device_name2, 0, size);
strncpy(device_name1, "kronostest1", size);
strncpy(device_name2, "kronostest2", size);
knet_tap1 = knet_tap_open(device_name1, size, NULL);
if (!knet_tap1) {
log_error("Unable to init %s.", device_name1);
err = -1;
goto out_clean;
}
if (is_if_in_system(device_name1) > 0) {
log_info("Found interface %s on the system", device_name1);
} else {
log_info("Unable to find interface %s on the system", device_name1);
}
knet_tap2 = knet_tap_open(device_name2, size, NULL);
if (!knet_tap2) {
log_error("Unable to init %s.", device_name2);
err = -1;
goto out_clean;
}
if (is_if_in_system(device_name2) > 0) {
log_info("Found interface %s on the system", device_name2);
} else {
log_info("Unable to find interface %s on the system", device_name2);
}
if (knet_tap1)
knet_tap_close(knet_tap1);
if (knet_tap2)
knet_tap_close(knet_tap2);
log_info("Testing error conditions");
log_info("Open same device twice");
knet_tap1 = knet_tap_open(device_name1, size, NULL);
if (!knet_tap1) {
log_error("Unable to init %s.", device_name1);
err = -1;
goto out_clean;
}
if (is_if_in_system(device_name1) > 0) {
log_info("Found interface %s on the system", device_name1);
} else {
log_info("Unable to find interface %s on the system", device_name1);
}
knet_tap2 = knet_tap_open(device_name1, size, NULL);
if (knet_tap2) {
log_error("We were able to init 2 interfaces with the same name!");
err = -1;
goto out_clean;
}
out_clean:
if (knet_tap1)
knet_tap_close(knet_tap1);
if (knet_tap2)
knet_tap_close(knet_tap2);
return err;
}
static int check_knet_mtu(void)
{
char device_name[IFNAMSIZ];
size_t size = IFNAMSIZ;
int err=0;
knet_tap_t knet_tap;
int current_mtu = 0;
int expected_mtu = 1500;
log_info("Testing get/set MTU");
memset(device_name, 0, size);
strncpy(device_name, "kronostest", size);
knet_tap = knet_tap_open(device_name, size, NULL);
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Comparing default MTU");
current_mtu = knet_tap_get_mtu(knet_tap);
if (current_mtu < 0) {
log_error("Unable to get MTU");
err = -1;
goto out_clean;
}
if (current_mtu != expected_mtu) {
log_error("current mtu [%d] does not match expected default [%d]", current_mtu, expected_mtu);
err = -1;
goto out_clean;
}
log_info("Setting MTU to 9000");
expected_mtu = 9000;
if (knet_tap_set_mtu(knet_tap, expected_mtu) < 0) {
log_error("Unable to set MTU to %d.", expected_mtu);
err = -1;
goto out_clean;
}
current_mtu = knet_tap_get_mtu(knet_tap);
if (current_mtu < 0) {
log_error("Unable to get MTU");
err = -1;
goto out_clean;
}
if (current_mtu != expected_mtu) {
log_error("current mtu [%d] does not match expected value [%d]", current_mtu, expected_mtu);
err = -1;
goto out_clean;
}
log_info("Testing ERROR conditions");
log_info("Passing empty struct to get_mtu");
if (knet_tap_get_mtu(NULL) > 0) {
log_error("Something is wrong in knet_tap_get_mtu sanity checks");
err = -1;
goto out_clean;
}
log_info("Passing empty struct to set_mtu");
if (knet_tap_set_mtu(NULL, 1500) == 0) {
log_error("Something is wrong in knet_tap_set_mtu sanity checks");
err = -1;
goto out_clean;
}
out_clean:
knet_tap_close(knet_tap);
return err;
}
static int check_knet_mac(void)
{
char device_name[IFNAMSIZ];
size_t size = IFNAMSIZ;
int err=0;
knet_tap_t knet_tap;
char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
struct ether_addr *cur_mac, *tmp_mac;
log_info("Testing get/set MAC");
memset(device_name, 0, size);
strncpy(device_name, "kronostest", size);
knet_tap = knet_tap_open(device_name, size, NULL);
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Get current MAC");
if (knet_tap_get_mac(knet_tap, ¤t_mac) < 0) {
log_error("Unable to get current MAC address.");
err = -1;
goto out_clean;
}
log_info("Current MAC: %s", current_mac);
log_info("Setting MAC: 00:01:01:01:01:01");
if (knet_tap_set_mac(knet_tap, "00:01:01:01:01:01") < 0) {
log_error("Unable to set current MAC address.");
err = -1;
goto out_clean;
}
if (knet_tap_get_mac(knet_tap, &temp_mac) < 0) {
log_error("Unable to get current MAC address.");
err = -1;
goto out_clean;
}
log_info("Current MAC: %s", temp_mac);
cur_mac = ether_aton(current_mac);
tmp_mac = ether_aton(temp_mac);
log_info("Comparing MAC addresses");
if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
log_error("Mac addresses are not the same?!");
err = -1;
goto out_clean;
}
log_info("Testing ERROR conditions");
log_info("Pass NULL to get_mac (pass1)");
errno = 0;
if ((knet_tap_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_get_mac sanity checks");
err = -1;
goto out_clean;
}
log_info("Pass NULL to get_mac (pass2)");
errno = 0;
if ((knet_tap_get_mac(knet_tap, NULL) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_get_mac sanity checks");
err = -1;
goto out_clean;
}
log_info("Pass NULL to set_mac (pass1)");
errno = 0;
if ((knet_tap_set_mac(knet_tap, NULL) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_set_mac sanity checks");
err = -1;
goto out_clean;
}
log_info("Pass NULL to set_mac (pass2)");
errno = 0;
if ((knet_tap_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_set_mac sanity checks");
err = -1;
goto out_clean;
}
out_clean:
if (err_mac) {
log_error("Something managed to set err_mac!");
err = -1;
free(err_mac);
}
if (current_mac)
free(current_mac);
if (temp_mac)
free(temp_mac);
knet_tap_close(knet_tap);
return err;
}
static int check_tap_execute_shell(void)
{
int err = 0;
char command[4096];
char *error_string = NULL;
memset(command, 0, sizeof(command));
log_info("Testing tap_execute_shell");
log_info("command /bin/true");
err = tap_execute_shell("/bin/true", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (err < 0) {
log_error("Unable to execute /bin/true ?!?!");
goto out_clean;
}
log_info("Testing ERROR conditions");
log_info("command /bin/false");
err = tap_execute_shell("/bin/false", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Can we really execute /bin/false successfully?!?!");
err = -1;
goto out_clean;
}
log_info("command that outputs to stdout (enforcing redirect)");
err = tap_execute_shell("/bin/grep -h 2>&1", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Can we really execute /bin/grep -h successfully?!?");
err = -1;
goto out_clean;
}
log_info("command that outputs to stderr");
err = tap_execute_shell("/bin/grep -h", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Can we really execute /bin/grep -h successfully?!?");
err = -1;
goto out_clean;
}
log_info("empty command");
err = tap_execute_shell(NULL, &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Can we really execute (nil) successfully?!?!");
err = -1;
goto out_clean;
}
log_info("empty error");
err = tap_execute_shell("/bin/true", NULL);
if (!err) {
log_error("Check EINVAL filter for no error_string!");
err = -1;
goto out_clean;
}
err = 0;
out_clean:
return err;
}
static int check_knet_up_down(void)
{
char device_name[IFNAMSIZ];
size_t size = IFNAMSIZ;
int err=0;
knet_tap_t knet_tap;
char *error_string = NULL;
log_info("Testing interface up/down");
memset(device_name, 0, size);
strncpy(device_name, "kronostest", size);
knet_tap = knet_tap_open(device_name, size, NULL);
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Put the interface up");
if (knet_tap_set_up(knet_tap) < 0) {
log_error("Unable to set interface up");
err = -1;
goto out_clean;
}
err = tap_execute_shell("ip addr show dev kronostest | grep -q UP", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (err < 0) {
log_error("Unable to verify inteface UP");
err = -1;
goto out_clean;
}
log_info("Put the interface down");
if (knet_tap_set_down(knet_tap) < 0) {
log_error("Unable to put the interface down");
err = -1;
goto out_clean;
}
err = tap_execute_shell("ifconfig kronostest | grep -q UP", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Unable to verify inteface DOWN");
err = -1;
goto out_clean;
}
knet_tap_close(knet_tap);
log_info("Testing interface pre-up/up/down/post-down (exec errors)");
knet_tap = knet_tap_open(device_name, size, ABSBUILDDIR "/tap_updown_bad");
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Put the interface up");
if (knet_tap_set_up(knet_tap) < 0) {
log_error("Unable to set interface up");
err = -1;
goto out_clean;
}
log_info("Put the interface down");
if (knet_tap_set_down(knet_tap) < 0) {
log_error("Unable to put the interface down");
err = -1;
goto out_clean;
}
knet_tap_close(knet_tap);
log_info("Testing interface pre-up/up/down/post-down");
knet_tap = knet_tap_open(device_name, size, ABSBUILDDIR "/tap_updown_good");
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Put the interface up");
if (knet_tap_set_up(knet_tap) < 0) {
log_error("Unable to set interface up");
err = -1;
goto out_clean;
}
log_info("Put the interface down");
if (knet_tap_set_down(knet_tap) < 0) {
log_error("Unable to put the interface down");
err = -1;
goto out_clean;
}
knet_tap_close(knet_tap);
log_info("Test ERROR conditions");
log_info("Pass NULL to set_up");
errno = 0;
if ((knet_tap_set_up(NULL) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_set_up sanity checks");
err = -1;
goto out_clean;
}
log_info("Pass NULL to set_down");
errno = 0;
if ((knet_tap_set_down(NULL) >= 0) || (errno != EINVAL)) {
log_error("Something is wrong in knet_tap_set_down sanity checks");
err = -1;
goto out_clean;
}
out_clean:
knet_tap_close(knet_tap);
return err;
}
static int check_knet_close_leak(void)
{
char device_name[IFNAMSIZ];
size_t size = IFNAMSIZ;
int err=0;
knet_tap_t knet_tap;
log_info("Testing close leak (needs valgrind)");
memset(device_name, 0, size);
strncpy(device_name, "kronostest", size);
knet_tap = knet_tap_open(device_name, size, NULL);
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Adding ip: 192.168.168.168/24");
if (knet_tap_add_ip(knet_tap, "192.168.168.168", "24") < 0) {
log_error("Unable to assign IP address");
err=-1;
goto out_clean;
}
log_info("Adding ip: 192.168.169.169/24");
if (knet_tap_add_ip(knet_tap, "192.168.169.169", "24") < 0) {
log_error("Unable to assign IP address");
err=-1;
goto out_clean;
}
out_clean:
knet_tap_close(knet_tap);
return err;
}
static int check_knet_set_del_ip(void)
{
char device_name[IFNAMSIZ];
size_t size = IFNAMSIZ;
int err=0;
knet_tap_t knet_tap;
char *ip_list = NULL;
int ip_list_entries = 0, i, offset = 0;
char *error_string = NULL;
log_info("Testing interface add/remove ip");
memset(device_name, 0, size);
strncpy(device_name, "kronostest", size);
knet_tap = knet_tap_open(device_name, size, NULL);
if (!knet_tap) {
log_error("Unable to init %s.", device_name);
return -1;
}
log_info("Adding ip: 192.168.168.168/24");
if (knet_tap_add_ip(knet_tap, "192.168.168.168", "24") < 0) {
log_error("Unable to assign IP address");
err=-1;
goto out_clean;
}
log_info("Adding ip: 192.168.169.169/24");
if (knet_tap_add_ip(knet_tap, "192.168.169.169", "24") < 0) {
log_error("Unable to assign IP address");
err=-1;
goto out_clean;
}
log_info("Adding duplicate ip: 192.168.168.168/24");
if (knet_tap_add_ip(knet_tap, "192.168.168.168", "24") < 0) {
log_error("Unable to find IP address in libtap db");
err=-1;
goto out_clean;
}
log_info("Checking ip: 192.168.168.168/24");
err = tap_execute_shell("ip addr show dev kronostest | grep -q 192.168.168.168/24", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (err) {
log_error("Unable to verify IP address");
err=-1;
goto out_clean;
}
log_info("Get ip list from libtap:");
if (knet_tap_get_ips(knet_tap, &ip_list, &ip_list_entries) < 0) {
log_error("Not enough mem?");
err=-1;
goto out_clean;
}
if (ip_list_entries != 2) {
log_error("Didn't get enough ip back from libtap?");
err=-1;
goto out_clean;
}
for (i = 1; i <= ip_list_entries; i++) {
log_info("Found IP %s %s in libtap db", ip_list + offset, ip_list + offset + strlen(ip_list + offset) + 1);
offset = offset + strlen(ip_list) + 1;
offset = offset + strlen(ip_list + offset) + 1;
}
free(ip_list);
log_info("Deleting ip: 192.168.168.168/24");
if (knet_tap_del_ip(knet_tap, "192.168.168.168", "24") < 0) {
log_error("Unable to delete IP address");
err=-1;
goto out_clean;
}
log_info("Deleting ip: 192.168.169.169/24");
if (knet_tap_del_ip(knet_tap, "192.168.169.169", "24") < 0) {
log_error("Unable to delete IP address");
err=-1;
goto out_clean;
}
log_info("Deleting again ip: 192.168.168.168/24");
if (knet_tap_del_ip(knet_tap, "192.168.168.168", "24") < 0) {
log_error("Unable to delete IP address");
err=-1;
goto out_clean;
}
err = tap_execute_shell("ip addr show dev kronostest | grep -q 192.168.168.168/24", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Unable to verify IP address");
err=-1;
goto out_clean;
}
log_info("Adding ip: 3ffe::1/64");
if (knet_tap_add_ip(knet_tap, "3ffe::1", "64") < 0) {
log_error("Unable to assign IP address");
err=-1;
goto out_clean;
}
err = tap_execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (err) {
log_error("Unable to verify IP address");
err=-1;
goto out_clean;
}
log_info("Deleting ip: 3ffe::1/64");
if (knet_tap_del_ip(knet_tap, "3ffe::1", "64") < 0) {
log_error("Unable to delete IP address");
err=-1;
goto out_clean;
}
err = tap_execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
if (error_string) {
log_error("Error string: %s", error_string);
free(error_string);
error_string = NULL;
}
if (!err) {
log_error("Unable to verify IP address");
err=-1;
goto out_clean;
}
out_clean:
knet_tap_close(knet_tap);
return err;
}
int main(void)
{
if (check_knet_tap_open_close() < 0)
return -1;
if (check_knet_multi_eth() < 0)
return -1;
if (check_knet_mtu() < 0)
return -1;
if (check_knet_mac() < 0)
return -1;
if (check_tap_execute_shell() < 0)
return -1;
if (check_knet_up_down() < 0)
return -1;
if (check_knet_set_del_ip() < 0)
return -1;
if (check_knet_close_leak() < 0)
return -1;
return 0;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 25, 5:34 AM (21 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1952323
Default Alt Text
(38 KB)
Attached To
Mode
rK kronosnet
Attached
Detach File
Event Timeline
Log In to Comment