This patch is to allow solaris to create a tap device in qemu, using the modified tun/tap driver at http://www.whiteboard.ne.jp/~admin2/tuntap.
I'm also including qemu_tap.c which is a setuid wrapper which sets up the tap, uses /etc/qemu-ifup (included - modify for your environment) and a start script (dsl.sh, minimal, but shows what needs done). To build qemu_tap, it's very simple. gcc -o qemu_tap qemu_tap.c sudo chown root qemu_tap sudo chmod 4755 qemu_tap The bridge code at http://www.whiteboard.ne.jp/~admin2/tuntap should also work, and should only require /etc/qemu-ifup to contain the commands to add the bridge, ie, no ifconfig should be needed.
qemu-solaris-tap-patch
Description: Binary data
qemu-ifup
Description: Binary data
/*
** qemu_tap.c: SUID wrapper program to allow non-root user to use tap network
** on Solaris, derived from qemu_tun.c by Sittichai Palansong
** with guidance from the tap code he wrote in qemu/vl.c
**
** Modified by: Ben Taylor
** Updated: 02/09/2007
**
** Author: Sittichai Palanisong
** Updated: 05/20/2005
**
** You are expected to be able to write a shell script wrapper to invoke
** qemu with the right parameters for a tap device passed in as a file
** descriptor. SUID privileges are only for setting the TAP device up for use.
**
*/
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <signal.h>
#include <stropts.h>
#include <net/if.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#define TUNNEWPPA (('T'<<16) | 0x0001)
int main(int argc, char *argv[])
{
char buf[2048], ifname[10]="";
int fd, len;
int uid, pid, status;
char tap_fd[32];
char *args[4];
char *qemu_script = "./qemu.sh";
char *network_script = "/etc/qemu-ifup";
if(argc > 1){
qemu_script = argv[1];
}
uid = getuid();
if( (fd = tap_alloc(ifname)) < 0 ){
printf("Cannot allocate TAP device\n");
exit(1);
}
/* try to launch network init script */
args[0] = network_script;
args[1] = ifname;
args[2] = NULL;
pid = fork();
if (pid >= 0) {
if (pid == 0) {
/* child */
execv(network_script, args);
exit(1);
}
/* parent */
while (waitpid(pid, &status, 0) != pid);
if (!WIFEXITED(status) ||
WEXITSTATUS(status) != 0) {
fprintf(stderr, "%s: could not launch network script\n",
network_script);
exit(1);
}
}
/* now switch to back to calling user */
if(setuid( uid) < 0){
printf("Cannot switch to UID %d\n", uid);
exit(1);
}
printf("Switch to UID %d\n", uid);
/* try to launch qemu script*/
sprintf( tap_fd, "%d", fd);
args[0] = qemu_script;
args[1] = "-t";
args[2] = tap_fd;
args[3] = NULL;
printf("Invoking %s %s %s\n", args[0], args[1], args[2]);
execv( qemu_script, args);
exit(1);
}
/*
* Allocate TAP device, returns opened fd.
* Stores dev name in the first arg(must be large enough).
*/
int tap_alloc(char *dev)
{
int tap_fd, if_fd, ppa = -1;
static int ip_fd = 0;
char *ptr;
static int arp_fd = 0;
int ip_muxid, arp_muxid;
struct strioctl strioc_if, strioc_ppa;
int link_type = I_PLINK;;
struct lifreq ifr;
char actual_name[32] = "";
memset(&ifr, 0x0, sizeof(ifr));
if ( *dev ) {
ptr = dev;
while ( *ptr && !isdigit((int)*ptr) ) ptr++;
ppa = atoi(ptr);
}
/* Check if IP device was opened */
if ( ip_fd )
close(ip_fd);
if ( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0 ) {
syslog(LOG_ERR, "Can't open /dev/udp");
return -1;
}
if ( (tap_fd = open("/dev/tap", O_RDWR, 0)) < 0 ) {
syslog(LOG_ERR, "Can't open /dev/tap");
return -1;
}
/* Assign a new PPA and get its unit number. */
strioc_ppa.ic_cmd = TUNNEWPPA;
strioc_ppa.ic_timout = 0;
strioc_ppa.ic_len = sizeof(ppa);
strioc_ppa.ic_dp = (char *)&ppa;
if ( (ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0 )
syslog (LOG_ERR, "Can't assign new interface");
if ( (if_fd = open("/dev/tap", O_RDWR, 0)) < 0 ) {
syslog(LOG_ERR, "Can't open /dev/tap (2)");
return -1;
}
if ( ioctl(if_fd, I_PUSH, "ip") < 0 ) {
syslog(LOG_ERR, "Can't push IP module");
return -1;
}
if ( ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0 )
syslog(LOG_ERR, "Can't get flags\n");
snprintf (actual_name, 32, "tap%d", ppa);
strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
ifr.lifr_ppa = ppa;
/* Assign ppa according to the unit number returned by tun device */
if ( ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0 )
syslog (LOG_ERR, "Can't set PPA %d", ppa);
if ( ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0 )
syslog (LOG_ERR, "Can't get flags\n");
/* Push arp module to if_fd */
if ( ioctl (if_fd, I_PUSH, "arp") < 0 )
syslog (LOG_ERR, "Can't push ARP module (2)");
/* Push arp module to ip_fd */
if ( ioctl (ip_fd, I_POP, NULL) < 0 )
syslog (LOG_ERR, "I_POP failed\n");
if ( ioctl (ip_fd, I_PUSH, "arp") < 0 )
syslog (LOG_ERR, "Can't push ARP module (3)\n");
/* Open arp_fd */
if ( (arp_fd = open ("/dev/tap", O_RDWR, 0)) < 0 )
syslog (LOG_ERR, "Can't open /dev/tap (3)");
/* Push arp module to arp_fd */
if ( ioctl (arp_fd, I_PUSH, "arp") < 0 )
syslog (LOG_ERR, "Can't push ARP module (4)\n");
/* Set ifname to arp */
strioc_if.ic_cmd = SIOCSLIFNAME;
strioc_if.ic_timout = 0;
strioc_if.ic_len = sizeof(ifr);
strioc_if.ic_dp = (char *)𝔦
if ( ioctl(arp_fd, I_STR, &strioc_if) < 0 ) {
syslog (LOG_ERR, "Can't set ifname to arp\n");
}
if ( (ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0 ) {
syslog(LOG_ERR, "Can't link TAP device to IP");
return -1;
}
if ( (arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0 )
syslog (LOG_ERR, "Can't link TAP device to ARP");
close (if_fd);
memset(&ifr, 0x0, sizeof(ifr));
strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
ifr.lifr_ip_muxid = ip_muxid;
ifr.lifr_arp_muxid = arp_muxid;
if ( ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0 )
{
ioctl (ip_fd, I_PUNLINK , arp_muxid);
ioctl (ip_fd, I_PUNLINK, ip_muxid);
syslog (LOG_ERR, "Can't set multiplexor id");
}
sprintf(dev, "tap%d", ppa);
return tap_fd;
}
dsl.sh
Description: Bourne shell script
_______________________________________________ Qemu-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/qemu-devel
