Checking in some recent tun/tap changes.
authorSapan Bhatia <sapanb@cs.princeton.edu>
Wed, 28 Oct 2009 02:55:33 +0000 (02:55 +0000)
committerSapan Bhatia <sapanb@cs.princeton.edu>
Wed, 28 Oct 2009 02:55:33 +0000 (02:55 +0000)
Makefile
fd_tuntap.c [new file with mode: 0644]
vif_up

index 936781c..bd67c29 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,10 @@
 CC=gcc
 CFLAGS=-g -O2
 
-all: dcookie fd_bmsocket fd_udpsocket fd_fusemount
+all: dcookie fd_bmsocket fd_udpsocket fd_fusemount fd_tuntap
+
+fd_tuntap: fd_tuntap.c
+       gcc fd_tuntap.c -o exec/fd_tuntap
 
 dcookie: dcookie.c
        gcc dcookie.c -o exec/dcookie
diff --git a/fd_tuntap.c b/fd_tuntap.c
new file mode 100644 (file)
index 0000000..0f538eb
--- /dev/null
@@ -0,0 +1,132 @@
+/* fd_tuntap.c: VSYS script to allocate slice-local tuntap interfaces.
+ *   Thom Haddow - 06/09/09
+ *
+ * Reads interface type from local control unix socket, replies with fd for new
+ * (unconfigured) tuntap interface. VSYS client can get interface name with
+ * TUNGETIFF ioctl. 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pwd.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+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) {
+               perror("sending file descriptor");
+               return -1;
+       }
+       return 0;
+}
+
+
+
+int main(int argc, char *argv[])
+{
+    int control_channel_fd;
+    int tap_fd;
+    int slice_uid;
+    char if_name[IFNAMSIZ];
+    int if_type;
+    struct ifreq ifr;
+    struct passwd *pwd;
+   
+    if(argc < 3) {
+        printf("This script is called by vsys.\n");
+        exit(-1);
+    }
+
+
+    /* Get slice UID and control channel fd from VSYS args */ 
+    pwd = getpwnam(argv[1]);
+    if(pwd==NULL) {
+        perror("Failed to lookup UID");
+        exit(-1);
+    }
+    slice_uid = pwd->pw_uid;
+    sscanf(argv[2],"%d", &control_channel_fd);
+
+   
+     
+    /* Get type param from control channel. */
+    if(recv(control_channel_fd, &if_type, sizeof(int), 0) != sizeof(int)) {
+        perror("fd_tuntap: Failed to read from control channel");
+        exit(-1);
+    }
+    
+   
+    /* Generate basename for interface */
+    if(if_type==IFF_TUN) {
+        sprintf(if_name, "tun%d-%%d", slice_uid);
+    }
+    else if(if_type==IFF_TAP) {
+        sprintf(if_name, "tap%d-%%d", slice_uid);
+    }
+    else { /* TODO: Might also want to allow the other types? */
+        fprintf(stderr, "fd_tuntap: %d is not a valid interface type",if_type);
+        exit(-1); 
+    }
+
+    /* Open tun device */
+    if( (tap_fd = open("/dev/stdtun", O_RDWR)) < 0 ) {
+        perror("ERROR: tun_alloc():open(/dev/stdtun)");
+        exit(-1);
+    }
+
+
+    /* Set interface type */
+    memset(&ifr, 0, sizeof(ifr));
+    ifr.ifr_flags = if_type; 
+    strncpy(ifr.ifr_name, if_name, IFNAMSIZ);
+    
+    if( ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0 ) {
+        close(tap_fd);
+        perror("fd_tuntap: Failed to set tun type");
+    }
+
+    /* Read initialised interface name */
+    strcpy(if_name, ifr.ifr_name);
+
+
+    /* Send tap_fd to slice */
+    //send_vif_fd(control_channel_fd, tap_fd, if_name);
+
+    return 0;
+}
diff --git a/vif_up b/vif_up
index 5556b6a..b40fef7 100755 (executable)
--- a/vif_up
+++ b/vif_up
@@ -15,7 +15,7 @@ import socket
 import struct
 import os
 
-netblock_config="vnetblocks.conf"
+vsys_config_dir = "/etc/planetlab/vsys-attributes"
 
 if len(sys.argv) != 2: sys.exit(1)
 
@@ -23,15 +23,13 @@ if len(sys.argv) != 2: sys.exit(1)
 slicename=sys.argv[1]
 sliceid = pwd.getpwnam(slicename).pw_uid
 
+netblock_config=os.path.join(vsys_config_dir,slicename,"vsys_vnet")
+
 # Read netblock allocation file
 base = None
 
-for line in open(netblock_config,'r'):
-    if line.startswith('#'): continue # skip comments
-    slice, netblock = line.split()
-    if slice == slicename: # found slice's alloc
-        base, mask = netblock.split('/')
-        break
+for netblock in open(netblock_config,'r'):
+    base, mask = netblock.split('/')
 
 if base is None:
     print >>sys.stderr, "Could not find entry for slice %s in netblock config file %s" % (slicename, netblock_config)