This attached patch is intended for allowing automated clever scripting for networking (tuntap only). Please read and apply if possible.
It does the following: a) allow for specifying the guest netdevice interface MAC address (in addition to keeping the old functionality of specifying just the first one and letting qemu decide what subsequent ones should be) So now you can say something along the lines of: "-nics 2 -macaddr0 00:11:a:0:2:19 -macaddr1 00:11:a:0:1:19" We allow upto 6 such MAC addresses to be specified. Maybe theres a more clever way to achieve this. b) allows to specify an opaque integer to be passed to the host script. Such an integer is useful if you are creating many NICs and you want to do different things depending on what this extra parameter is; example you may wanna add/del a route for one but not other syntax is of the form: "-ID1 1 -ID2 2" The IDs are mapped to the NICs. i.e ID1 maps to the first NIC and ID2 to the second etc. If you dont specify an ID, a 0 is used. Just like NICS/MACs we allow upto 6 such IDs to be specified. c) In addition to receiving the tun device name as $1, the net setup script now receives $2 as the ID value and $3 as the guest MAC address. I was thinking instead of passing the guest MAC, to allow the user to specify the IP address of the host side if needed but then figured that maybe introducing too many parameters around. The user can instead write a script which will configure the host side IP based on the ID passed. Also i could get rid of passing the MAC if deemed unneeded. cheers, jamal
--- qemu-0.7.0/vl.h 2005-04-27 16:52:05.000000000 -0400 +++ qemu-0.7.0-mod/vl.h 2005-08-20 06:57:56.000000000 -0400 @@ -238,7 +238,8 @@ typedef struct NetDriverState { int index; /* index number in QEMU */ - uint8_t macaddr[6]; + uint8_t macaddr[6]; /* MAC of this netdevice */ + int ID; /* opaque value we pass host scripts */ char ifname[16]; void (*send_packet)(struct NetDriverState *nd, const uint8_t *buf, int size); --- qemu-0.7.0/vl.c 2005-04-27 16:52:05.000000000 -0400 +++ qemu-0.7.0-mod/vl.c 2005-08-20 07:11:18.000000000 -0400 @@ -1652,7 +1652,7 @@ static int net_tun_init(NetDriverState *nd) { int pid, status; - char *args[3]; + char *args[6]; char **parg; nd->fd = tun_open(nd->ifname, sizeof(nd->ifname)); @@ -1663,9 +1663,16 @@ pid = fork(); if (pid >= 0) { if (pid == 0) { + char I[8],MAC[24]; + memset(I,0,8); + memset(MAC,0,24); + sprintf(I, "%d", nd->ID); + sprintf(MAC, "%x.%x.%x.%x.%x.%x", nd->macaddr[0],nd->macaddr[1], nd->macaddr[2], nd->macaddr[3],nd->macaddr[4],nd->macaddr[5]); parg = args; *parg++ = network_script; *parg++ = nd->ifname; + *parg++ = I; + *parg++ = MAC; *parg++ = NULL; execv(network_script, args); exit(1); @@ -2756,6 +2763,13 @@ "Network options:\n" "-nics n simulate 'n' network cards [default=1]\n" "-macaddr addr set the mac address of the first interface\n" + "-macaddr0 addr set the mac address of the first interface\n" + "-macaddr1 addr set the mac address of the second interface\n" + "-macaddr2 addr set the mac address of the third interface\n" + "-macaddr3 addr set the mac address of the fourth interface\n" + "-macaddr4 addr set the mac address of the fifth interface\n" + "-macaddr5 addr set the mac address of the sixth interface\n" + "-ID1-6 identifier ID passed to host script maps to macaddr\n" "-n script set tap/tun network init script [default=%s]\n" "-tun-fd fd use this fd as already opened tap/tun interface\n" #ifdef CONFIG_SLIRP @@ -2843,7 +2857,19 @@ QEMU_OPTION_enable_audio, QEMU_OPTION_nics, + QEMU_OPTION_ID1, + QEMU_OPTION_ID2, + QEMU_OPTION_ID3, + QEMU_OPTION_ID4, + QEMU_OPTION_ID5, + QEMU_OPTION_ID6, QEMU_OPTION_macaddr, + QEMU_OPTION_macaddr0, + QEMU_OPTION_macaddr1, + QEMU_OPTION_macaddr2, + QEMU_OPTION_macaddr3, + QEMU_OPTION_macaddr4, + QEMU_OPTION_macaddr5, QEMU_OPTION_n, QEMU_OPTION_tun_fd, QEMU_OPTION_user_net, @@ -2904,7 +2930,19 @@ { "enable-audio", 0, QEMU_OPTION_enable_audio }, { "nics", HAS_ARG, QEMU_OPTION_nics}, + { "ID1", HAS_ARG, QEMU_OPTION_ID1}, + { "ID2", HAS_ARG, QEMU_OPTION_ID2}, + { "ID3", HAS_ARG, QEMU_OPTION_ID3}, + { "ID4", HAS_ARG, QEMU_OPTION_ID4}, + { "ID5", HAS_ARG, QEMU_OPTION_ID5}, + { "ID6", HAS_ARG, QEMU_OPTION_ID6}, { "macaddr", HAS_ARG, QEMU_OPTION_macaddr}, + { "macaddr0", HAS_ARG, QEMU_OPTION_macaddr0}, + { "macaddr1", HAS_ARG, QEMU_OPTION_macaddr1}, + { "macaddr2", HAS_ARG, QEMU_OPTION_macaddr2}, + { "macaddr3", HAS_ARG, QEMU_OPTION_macaddr3}, + { "macaddr4", HAS_ARG, QEMU_OPTION_macaddr4}, + { "macaddr5", HAS_ARG, QEMU_OPTION_macaddr4}, { "n", HAS_ARG, QEMU_OPTION_n }, { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd }, #ifdef CONFIG_SLIRP @@ -3009,6 +3047,7 @@ int use_gdbstub, gdbstub_port; #endif int i, has_cdrom; + int IDs[6]; int snapshot, linux_boot; CPUState *env; const char *initrd_filename; @@ -3018,6 +3057,7 @@ int cyls, heads, secs, translation; int start_emulation = 1; uint8_t macaddr[6]; + uint8_t macaddrs[6][6]; int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; int optind; const char *r, *optarg; @@ -3075,6 +3115,15 @@ macaddr[3] = 0x12; macaddr[4] = 0x34; macaddr[5] = 0x56; + /* default IDs are 0 */ + + for (i = 0; i < 6; i++) { + int j; + IDs[i]=0; + for (j = 0; j < 6; j++) { + macaddrs[i][j] = 0xFF; + } + } optind = 1; for(;;) { @@ -3223,6 +3272,36 @@ exit(1); } break; + case QEMU_OPTION_ID1: + { + IDs[0]=atoi(optarg); + } + break; + case QEMU_OPTION_ID2: + { + IDs[1]=atoi(optarg); + } + break; + case QEMU_OPTION_ID3: + { + IDs[2]=atoi(optarg); + } + break; + case QEMU_OPTION_ID4: + { + IDs[3]=atoi(optarg); + } + break; + case QEMU_OPTION_ID5: + { + IDs[4]=atoi(optarg); + } + break; + case QEMU_OPTION_ID6: + { + IDs[5]=atoi(optarg); + } + break; case QEMU_OPTION_macaddr: { const char *p; @@ -3244,6 +3323,126 @@ } } break; + case QEMU_OPTION_macaddr0: + { + const char *p; + int i; + p = optarg; + for(i = 0; i < 6; i++) { + macaddrs[0][i] = strtol(p, (char **)&p, 16); + if (i == 5) { + if (*p != '\0') + goto macaddr_error; + } else { + if (*p != ':') { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + p++; + } + } + } + break; + case QEMU_OPTION_macaddr1: + { + const char *p; + int i; + p = optarg; + for(i = 0; i < 6; i++) { + macaddrs[1][i] = strtol(p, (char **)&p, 16); + if (i == 5) { + if (*p != '\0') + goto macaddr_error; + } else { + if (*p != ':') { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + p++; + } + } + } + break; + case QEMU_OPTION_macaddr2: + { + const char *p; + int i; + p = optarg; + for(i = 0; i < 6; i++) { + macaddrs[2][i] = strtol(p, (char **)&p, 16); + if (i == 5) { + if (*p != '\0') + goto macaddr_error; + } else { + if (*p != ':') { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + p++; + } + } + } + break; + case QEMU_OPTION_macaddr3: + { + const char *p; + int i; + p = optarg; + for(i = 0; i < 6; i++) { + macaddrs[3][i] = strtol(p, (char **)&p, 16); + if (i == 5) { + if (*p != '\0') + goto macaddr_error; + } else { + if (*p != ':') { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + p++; + } + } + } + break; + case QEMU_OPTION_macaddr4: + { + const char *p; + int i; + p = optarg; + for(i = 0; i < 6; i++) { + macaddrs[4][i] = strtol(p, (char **)&p, 16); + if (i == 5) { + if (*p != '\0') + goto macaddr_error; + } else { + if (*p != ':') { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + p++; + } + } + } + break; + case QEMU_OPTION_macaddr5: + { + const char *p; + int i; + p = optarg; + for(i = 0; i < 6; i++) { + macaddrs[5][i] = strtol(p, (char **)&p, 16); + if (i == 5) { + if (*p != '\0') + goto macaddr_error; + } else { + if (*p != ':') { + fprintf(stderr, "qemu: invalid syntax for ethernet address\n"); + exit(1); + } + p++; + } + } + } + break; #ifdef CONFIG_SLIRP case QEMU_OPTION_tftp: tftp_prefix = optarg; @@ -3444,12 +3643,22 @@ NetDriverState *nd = &nd_table[i]; nd->index = i; /* init virtual mac address */ - nd->macaddr[0] = macaddr[0]; - nd->macaddr[1] = macaddr[1]; - nd->macaddr[2] = macaddr[2]; - nd->macaddr[3] = macaddr[3]; - nd->macaddr[4] = macaddr[4]; - nd->macaddr[5] = macaddr[5] + i; + nd->ID = IDs[i]; + if (macaddrs[i][0] == 0xFF) { + nd->macaddr[0] = macaddr[0]; + nd->macaddr[1] = macaddr[1]; + nd->macaddr[2] = macaddr[2]; + nd->macaddr[3] = macaddr[3]; + nd->macaddr[4] = macaddr[4]; + nd->macaddr[5] = macaddr[5] + i; + } else { + nd->macaddr[0] = macaddrs[i][0]; + nd->macaddr[1] = macaddrs[i][1]; + nd->macaddr[2] = macaddrs[i][2]; + nd->macaddr[3] = macaddrs[i][3]; + nd->macaddr[4] = macaddrs[i][4]; + nd->macaddr[5] = macaddrs[i][5]; + } switch(net_if_type) { #if defined(CONFIG_SLIRP) case NET_IF_USER:
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel