From: Sapan Bhatia Date: Wed, 28 Oct 2009 02:55:33 +0000 (+0000) Subject: Checking in some recent tun/tap changes. X-Git-Tag: vsys-scripts-0.95-10~2 X-Git-Url: http://git.onelab.eu/?p=vsys-scripts.git;a=commitdiff_plain;h=734018b3473b516452c1302607b198bb0ab5aa1d Checking in some recent tun/tap changes. --- diff --git a/Makefile b/Makefile index 936781c..bd67c29 100644 --- 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 index 0000000..0f538eb --- /dev/null +++ b/fd_tuntap.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 --- 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)