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

Reply via email to