Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3152376
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/libnozzle/internals.c b/libnozzle/internals.c
index f21784ff..437fe4a2 100644
--- a/libnozzle/internals.c
+++ b/libnozzle/internals.c
@@ -1,783 +1,185 @@
/*
* Copyright (C) 2010-2017 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/wait.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "libnozzle.h"
#include "internals.h"
static int 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;
memmove((*file) + (*length), buf, n);
*length += (done + n);
}
/* Null terminator */
(*file)[(*length) - 1] = 0;
return 0;
}
int execute_bin_sh_command(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 = read_pipe(fd[0], error_string, &size);
if (err)
goto out_clean0;
waitpid(pid, &status, 0);
if (!WIFEXITED(status)) {
err = -1;
goto out_clean0;
}
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
err = WEXITSTATUS(status);
goto out_clean0;
}
goto out_clean0;
} 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[1]);
out_clean0:
close(fd[0]);
return err;
}
char *generate_v4_broadcast(const char *ipaddr, 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, ipaddr, &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));
}
int find_ip(nozzle_t nozzle,
const char *ipaddr, const char *prefix,
struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
{
struct nozzle_ip *local_ip, *local_ip_prev;
int found = 0;
local_ip = local_ip_prev = nozzle->ip;
while(local_ip) {
if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
found = 1;
break;
}
local_ip_prev = local_ip;
local_ip = local_ip->next;
}
if (found) {
*ip = local_ip;
*ip_prev = local_ip_prev;
}
return found;
}
-
-#if 0
-static void _close(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);
-
- return;
-}
-
-static void _close_cfg(void)
-{
- if (lib_cfg.head == NULL) {
- close(lib_cfg.ioctlfd);
- lib_init = 0;
- }
-}
-
-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.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) {
- errno = 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));
- strncpy(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)) {
- errno = EBUSY;
- goto out_error;
- }
-
- strncpy(devname, ifname, IFNAMSIZ);
- strncpy(nozzle->name, ifname, IFNAMSIZ);
-#endif
-
- nozzle->default_mtu = _get_mtu(nozzle);
- if (nozzle->default_mtu < 0) {
- savederrno = errno;
- goto out_error;
- }
-
- if (_get_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:
- _close(nozzle);
- _close_cfg();
- pthread_mutex_unlock(&config_mutex);
- errno = savederrno;
- return NULL;
-}
-
-int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown)
-{
- int err = 0, savederrno = 0;
- nozzle_t temp = lib_cfg.head;
- nozzle_t prev = lib_cfg.head;
- struct nozzle_ip *ip, *ip_next;
- char *error_string = NULL;
-
- savederrno = pthread_mutex_lock(&config_mutex);
- if (savederrno) {
- errno = savederrno;
- return -1;
- }
-
- if (!_check(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;
- }
-
- _set_down(nozzle, error_down, error_postdown);
-
- ip = nozzle->ip;
- while (ip) {
- ip_next = ip->next;
- _set_ip(nozzle, "del", ip->ipaddr, ip->prefix, &error_string, 0);
- if (error_string) {
- free(error_string);
- error_string = NULL;
- }
- free(ip);
- ip = ip_next;
- }
-
- _close(nozzle);
- _close_cfg();
-
-out_clean:
- pthread_mutex_unlock(&config_mutex);
- errno = savederrno;
- return err;
-}
-
-int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
-{
- int err = 0, savederrno = 0;
- struct nozzle_ip *tmp_ip;
- struct ifreq ifr;
-
- if ((!nozzle) || (!mtu) || (!error_string)) {
- errno = EINVAL;
- return -1;
- }
-
- savederrno = pthread_mutex_lock(&config_mutex);
- if (savederrno) {
- errno = savederrno;
- return -1;
- }
-
- if (!_check(nozzle)) {
- errno = EINVAL;
- err = -1;
- goto out_clean;
- }
-
- err = nozzle->current_mtu = _get_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, "add", tmp_ip->ipaddr, tmp_ip->prefix, error_string, 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, char **error_string)
-{
- return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
-}
-
-static int _set_ip(nozzle_t nozzle, const char *command,
- const char *ipaddr, const char *prefix,
- char **error_string, int secondary)
-{
- char *broadcast = NULL;
- char cmdline[4096];
-#ifdef KNET_BSD
- char proto[6];
- int v4 = 1;
-
- snprintf(proto, sizeof(proto), "inet");
-#endif
-
- if (!strchr(ipaddr, ':')) {
- broadcast = _get_v4_broadcast(ipaddr, prefix);
- if (!broadcast) {
- errno = EINVAL;
- return -1;
- }
- }
-#ifdef KNET_BSD
- else {
- v4 = 0;
- snprintf(proto, sizeof(proto), "inet6");
- }
-#endif
-
- memset(cmdline, 0, sizeof(cmdline));
-
-#ifdef KNET_LINUX
- if (broadcast) {
- snprintf(cmdline, sizeof(cmdline)-1,
- "ip addr %s %s/%s dev %s broadcast %s",
- command, ipaddr, prefix,
- nozzle->name, broadcast);
- } else {
- snprintf(cmdline, sizeof(cmdline)-1,
- "ip addr %s %s/%s dev %s",
- command, ipaddr, prefix,
- nozzle->name);
- }
-#endif
-#ifdef KNET_BSD
- if (!strcmp(command, "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) && (v4)) {
- 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);
- }
-#endif
- if (broadcast) {
- free(broadcast);
- }
- return _execute_bin_sh(cmdline, error_string);
-}
-
-int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
-{
- int err = 0, savederrno = 0;
- int found = 0;
- struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
- int secondary = 0;
-
- if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
- errno = EINVAL;
- return -1;
- }
-
- savederrno = pthread_mutex_lock(&config_mutex);
- if (savederrno) {
- errno = savederrno;
- return -1;
- }
-
- if (!_check(nozzle)) {
- errno = 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_mtu(nozzle) < 1280)) {
- err = 0;
- } else {
- if (nozzle->ip) {
- secondary = 1;
- }
- err = _set_ip(nozzle, "add", ipaddr, prefix, error_string, 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, char **error_string)
-{
- int err = 0, savederrno = 0;
- int found = 0;
- struct nozzle_ip *ip = NULL, *ip_prev = NULL;
-
- if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
- errno = EINVAL;
- return -1;
- }
-
- savederrno = pthread_mutex_lock(&config_mutex);
- if (savederrno) {
- errno = savederrno;
- return -1;
- }
-
- if (!_check(nozzle)) {
- errno = EINVAL;
- err = -1;
- goto out_clean;
- }
-
- found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
- if (!found) {
- goto out_clean;
- }
-
- err = _set_ip(nozzle, "del", ipaddr, prefix, error_string, 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, char **ipaddr_list, int *entries)
-{
- int err = 0, savederrno = 0;
- int found = 0;
- char *ip_list = NULL;
- int size = 0, offset = 0, len;
- struct nozzle_ip *ip = NULL;
-
- if ((!nozzle) || (!ipaddr_list) || (!entries)) {
- errno = EINVAL;
- return -1;
- }
-
- savederrno = pthread_mutex_lock(&config_mutex);
- if (savederrno) {
- errno = savederrno;
- return -1;
- }
-
- if (!_check(nozzle)) {
- errno = EINVAL;
- goto out_clean;
- }
-
- ip = nozzle->ip;
-
- while (ip) {
- found++;
- ip = ip->next;
- }
-
- if (!found) {
- *ipaddr_list = NULL;
- *entries = 0;
- goto out_clean;
- }
-
- size = found * (IPADDR_CHAR_MAX + PREFIX_CHAR_MAX + 2);
-
- ip_list = malloc(size);
- if (!ip_list) {
- savederrno = errno;
- err = -1;
- goto out_clean;
- }
-
- memset(ip_list, 0, size);
-
- ip = nozzle->ip;
-
- while (ip) {
- len = strlen(ip->ipaddr);
- memmove(ip_list + offset, ip->ipaddr, len);
- offset = offset + len + 1;
- len = strlen(ip->prefix);
- memmove(ip_list + offset, ip->prefix, len);
- offset = offset + len + 1;
- ip = ip->next;
- }
-
- *ipaddr_list = ip_list;
- *entries = found;
-
-out_clean:
- pthread_mutex_unlock(&config_mutex);
- errno = savederrno;
- return err;
-}
-#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Feb 24, 9:12 PM (9 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1464458
Default Alt Text
(15 KB)
Attached To
Mode
rK kronosnet
Attached
Detach File
Event Timeline
Log In to Comment