include xenserver/automake.mk
include python/automake.mk
include python/compat/automake.mk
+include planetlab/automake.mk
--- /dev/null
+sbin_PROGRAMS += \
+ planetlab/pltap-ovs/pltap-ovs
+
+dist_sbin_SCRIPTS += \
+ planetlab/scripts/create_bridge \
+ planetlab/scripts/create_port \
+ planetlab/scripts/del_bridge
+
+planetlab_pltap_ovs_pltap_ovs_SOURCES = \
+ planetlab/pltap-ovs/pltap-ovs.c \
+ planetlab/pltap-ovs/tunalloc.c \
+ planetlab/pltap-ovs/tunalloc.h
--- /dev/null
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+#include "tunalloc.h"
+
+#define OVS_SOCK "/var/tun/pl-ovs.control"
+
+char *appname;
+
+#define ERROR(msg) \
+ do { \
+ fprintf(stderr, "%s: %s: %s", appname, msg, strerror(errno)); \
+ exit(1); \
+ } while (0)
+
+
+int send_vif_fd(int sock_fd, int vif_fd, char *vif_name)
+{
+ int retval;
+ struct msghdr msg;
+ struct cmsghdr *p_cmsg;
+ struct iovec vec;
+ size_t cmsgbuf[CMSG_SPACE(sizeof(vif_fd)) / sizeof(size_t)];
+ int *p_fds;
+
+
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ p_cmsg = CMSG_FIRSTHDR(&msg);
+ p_cmsg->cmsg_level = SOL_SOCKET;
+ p_cmsg->cmsg_type = SCM_RIGHTS;
+ p_cmsg->cmsg_len = CMSG_LEN(sizeof(vif_fd));
+ p_fds = (int *) CMSG_DATA(p_cmsg);
+ *p_fds = vif_fd;
+ msg.msg_controllen = p_cmsg->cmsg_len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+
+ /* Send the interface name as the iov */
+ vec.iov_base = vif_name;
+ vec.iov_len = strlen(vif_name)+1;
+
+ while ((retval = sendmsg(sock_fd, &msg, 0)) == -1 && errno == EINTR);
+ if (retval == -1) {
+ ERROR("sending file descriptor");
+ }
+ return 0;
+}
+
+void send_fd(int p, int fd, char* vif_name)
+{
+ int control_fd;
+ int accept_fd;
+ struct sockaddr_un addr, accept_addr;
+ socklen_t addr_len = sizeof(accept_addr);
+ int i;
+
+ control_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (control_fd == -1 && errno != ENOENT) {
+ ERROR("Could not create UNIX socket");
+ }
+
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ /* Clear structure */
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, OVS_SOCK,
+ sizeof(addr.sun_path) - 1);
+
+ if (unlink(OVS_SOCK) == -1 && errno != ENOENT) {
+ ERROR("Could not unlink " OVS_SOCK " control socket");
+ }
+
+ if (bind(control_fd, (struct sockaddr *) &addr,
+ sizeof(struct sockaddr_un)) == -1) {
+ ERROR("Could not bind to " OVS_SOCK " control socket");
+ }
+
+ if (listen(control_fd, 5) == -1) {
+ ERROR("listen on " OVS_SOCK " failed");
+ }
+ if (write(p, "1", 1) != 1) {
+ ERROR("writing on the synch pipe");
+ }
+ if ((accept_fd = accept(control_fd, (struct sockaddr*) &accept_addr,
+ &addr_len)) == -1) {
+ ERROR("accept on " OVS_SOCK " failed");
+ }
+ send_vif_fd(accept_fd, fd, vif_name);
+}
+
+int main(int argc, char* argv[])
+{
+ char if_name[IFNAMSIZ];
+ int p[2]; // synchronization pipe
+ char dummy;
+
+ if (pipe(p) < 0) {
+ ERROR("pipe");
+ }
+
+ int tun_fd = tun_alloc(IFF_TAP, if_name);
+
+ appname = argv[0];
+
+ switch(fork()) {
+ case -1:
+ ERROR("fork");
+ exit(1);
+ case 0:
+ close(1);
+ open("/dev/null", O_WRONLY);
+ close(p[0]);
+ send_fd(p[1], tun_fd, if_name);
+ exit(0);
+ default:
+ close(p[1]);
+ if (read(p[0], &dummy, 1) != 1) {
+ ERROR("reading from the synch pipe");
+ }
+ printf("%s\n", if_name);
+ }
+ return 0;
+}
--- /dev/null
+/* Slice-side code to allocate tuntap interface in root slice
+ * Based on bmsocket.c
+ * Thom Haddow - 08/10/09
+ *
+ * Call tun_alloc() with IFFTUN or IFFTAP as an argument to get back fd to
+ * new tuntap interface. Interface name can be acquired via TUNGETIFF ioctl.
+ */
+
+#include <sys/un.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+#define VSYS_TUNTAP "/vsys/fd_tuntap.control"
+
+/* Reads vif FD from "fd", writes interface name to vif_name, and returns vif FD.
+ * vif_name should be IFNAMSIZ chars long. */
+int receive_vif_fd(int fd, char *vif_name)
+{
+ struct msghdr msg;
+ struct iovec iov;
+ int rv;
+ size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
+ struct cmsghdr *cmsg;
+
+ /* Use IOV to read interface name */
+ iov.iov_base = vif_name;
+ iov.iov_len = IFNAMSIZ;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ /* old BSD implementations should use msg_accrights instead of
+ * msg_control; the interface is different. */
+ msg.msg_control = ccmsg;
+ msg.msg_controllen = sizeof(ccmsg);
+
+ while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
+ if (rv == -1) {
+ perror("recvmsg");
+ return -1;
+ }
+ if(!rv) {
+ /* EOF */
+ return -1;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg->cmsg_type == SCM_RIGHTS) {
+ fprintf(stderr, "got control message of unknown type %d\n",
+ cmsg->cmsg_type);
+ return -1;
+ }
+ return *(int*)CMSG_DATA(cmsg);
+}
+
+
+int tun_alloc(int iftype, char *if_name)
+{
+ int control_fd;
+ struct sockaddr_un addr;
+ int remotefd;
+
+ control_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (control_fd == -1) {
+ perror("Could not create UNIX socket\n");
+ exit(-1);
+ }
+
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ /* Clear structure */
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, VSYS_TUNTAP,
+ sizeof(addr.sun_path) - 1);
+
+ if (connect(control_fd, (struct sockaddr *) &addr,
+ sizeof(struct sockaddr_un)) == -1) {
+ perror("Could not connect to Vsys control socket");
+ exit(-1);
+ }
+
+ /* passing type param */
+ if (send(control_fd, &iftype, sizeof(iftype), 0) != sizeof(iftype)) {
+ perror("Could not send paramater to Vsys control socket");
+ exit(-1);
+ }
+
+ remotefd = receive_vif_fd(control_fd, if_name);
+ return remotefd;
+}
--- /dev/null
+#ifndef _TUNALLOC_H
+#define _TUNALLOC_H
+
+int tun_alloc(int iftype, char *if_name);
+
+#endif
--- /dev/null
+#!/bin/bash
+
+function error
+{
+ echo $1 >&2
+ killall pltap-ovs 2>/dev/null || true
+ exit 1
+}
+
+function is_switch_running
+{
+ ovs-appctl version >/dev/null 2>&1
+}
+
+if [ -z "$1" ]; then
+ error "Usage: ${0##*/} <IP/PREFIX>"
+fi
+
+# TODO: check paramether validity
+
+IP=${1%/*}
+PREFIX=${1#*/}
+
+set -e
+
+# ensure ovs-vswitchd is running
+if ! is_switch_running; then
+ ovs-vswitchd --pidfile --detach --log-file >/dev/null 2>&1
+fi
+while ! is_switch_running; do
+ sleep 1
+done
+
+
+# check whether the address is already assigned
+set -e
+TAPNAME=$(ip addr show to "$IP/32" | perl -ne '/^\s*\d+:\s*([\w-]+):/ && print $1')
+if [ ! -z "$TAPNAME" ]; then
+ if ovs-vsctl br-exists "$TAPNAME"; then
+ echo $TAPNAME
+ exit 0
+ fi
+ error "$IP already assigned to $TAPNAME"
+fi
+
+TAPNAME=$(pltap-ovs)
+cat < /vsys/vif_up.out&
+cat >/vsys/vif_up.in << EOF
+ $TAPNAME
+ $IP
+ $PREFIX
+EOF
+while ! ip link show up | egrep -q "^[0-9]+: +$TAPNAME:"; do
+ echo "Waiting for $TAPNAME to come UP..." >&2
+ sleep 1
+done
+ovs-vsctl add-br $TAPNAME -- set bridge $TAPNAME datapath_type=planetlab
+echo $TAPNAME
--- /dev/null
+#!/bin/bash
+
+function error
+{
+ echo $1 >&2
+ exit 1
+}
+
+if [ -z "$2" ]; then
+ error "Usage ${0##*/} <bridge> <port>"
+fi
+
+if ovs-vsctl list-ports "$1" | grep -q "^$2$"; then
+ exit 0
+fi
+ovs-vsctl add-port "$1" "$2" -- set interface "$2" type=tunnel
--- /dev/null
+#!/bin/bash
+
+function error
+{
+ echo $1 >&2
+ exit 1
+}
+
+function is_switch_running
+{
+ ovs-appctl version >/dev/null 2>&1
+}
+
+if [ -z "$1" ]; then
+ error "Usage: ${0##*/} <bridge name>"
+fi
+
+# ensure ovs-vswitchd is running
+if ! is_switch_running; then
+ exit 0;
+fi
+
+ovs-vsctl del-br $1 || true
+ovs-appctl exit