qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] patch: allow defining MAC address etc
@ 2005-08-21  0:36 jamal
  2005-08-21  1:04 ` Paul Brook
  0 siblings, 1 reply; 12+ messages in thread
From: jamal @ 2005-08-21  0:36 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1573 bytes --]


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

[-- Attachment #2: qemu_p --]
[-- Type: text/plain, Size: 11235 bytes --]

--- 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:

^ permalink raw reply	[flat|nested] 12+ messages in thread
* [Qemu-devel] PATCH: allow defining MAC address etc
@ 2005-08-22  1:44 jamal
  0 siblings, 0 replies; 12+ messages in thread
From: jamal @ 2005-08-22  1:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jim C. Brown, Paul Brook

[-- Attachment #1: Type: text/plain, Size: 1069 bytes --]


Ok, here goes as per discussion...

Please apply.
This patch is intended for allowing automated clever scripting
for networking (tuntap only).

It does the following:
1) extends syntax for specifying the macaddr

Examples:

a) "-nics 2"
Which will give you the
    0x52:0x54:0x00:0x12:0x34:0x56 for the first nic
and 0x52:0x54:0x00:0x12:0x34:0x57 for the second nic

b) "-nics 3 -macaddr 00:11:a:0:1:39"

Which will give first NIC 00:11:a:0:1:39, the second 00:11:a:0:1:3A
and the third 00:11:a:0:1:3B.

c) "-nics 2 -macaddr 00:11:a:0:2:19,00:11:a:0:1:19"
Which will give first NIC 00:11:a:0:2:19, the second 00:11:a:0:1:19

d) "-nics 3 -macaddr 00:11:a:0:1:39,00:11:a:0:3:19"

which will give the first NIC a MAC of 00:11:a:0:1:39 the second
00:11:a:0:3:19 and the last 00:11:a:0:1:3B

2) In addition to receiving the tun device name as $1, the
net setup script now receives $2 as the guest MAC address.
One could encode a byte or two in this MAC address for example as a
message to the host script so that it can do something like prepare a
route etc

cheers,
jamal

[-- Attachment #2: qemu_t2_p --]
[-- Type: text/x-patch, Size: 6762 bytes --]

diff --git a/vl.c b/vl.c
--- a/vl.c
+++ b/vl.c
@@ -1652,7 +1652,7 @@ static void tun_add_read_packet(NetDrive
 static int net_tun_init(NetDriverState *nd)
 {
     int pid, status;
-    char *args[3];
+    char *args[4];
     char **parg;
 
     nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
@@ -1663,9 +1663,13 @@ static int net_tun_init(NetDriverState *
     pid = fork();
     if (pid >= 0) {
         if (pid == 0) {
+            char MAC[24];
+            memset(MAC,0,24);
+            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++ = MAC;
             *parg++ = NULL;
             execv(network_script, args);
             exit(1);
@@ -2755,7 +2759,9 @@ void help(void)
            "\n"
            "Network options:\n"
            "-nics n         simulate 'n' network cards [default=1]\n"
-           "-macaddr addr   set the mac address of the first interface\n"
+           "-macaddr addr[,addr,addr ..] set the mac address(es) of the guest\n"
+           "                if only one mac is specified it is used as \n"
+	   "                the mac address of the first interface \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
@@ -3018,6 +3024,7 @@ int main(int argc, char **argv)
     int cyls, heads, secs, translation;
     int start_emulation = 1;
     uint8_t macaddr[6];
+    uint8_t macaddrs[MAX_NICS][6];
     int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
     int optind;
     const char *r, *optarg;
@@ -3075,7 +3082,7 @@ int main(int argc, char **argv)
     macaddr[3] = 0x12;
     macaddr[4] = 0x34;
     macaddr[5] = 0x56;
-    
+
     optind = 1;
     for(;;) {
         if (optind >= argc)
@@ -3217,33 +3224,80 @@ int main(int argc, char **argv)
                 code_copy_enabled = 0;
                 break;
             case QEMU_OPTION_nics:
-                nb_nics = atoi(optarg);
-                if (nb_nics < 0 || nb_nics > MAX_NICS) {
-                    fprintf(stderr, "qemu: invalid number of network interfaces\n");
-                    exit(1);
-                }
-                break;
+                {
+                 int i = 0, j = -1;
+                 nb_nics = atoi(optarg);
+                 if (nb_nics < 0 || nb_nics > MAX_NICS) {
+                     fprintf(stderr, "qemu: invalid number of network interfaces\n");
+                     exit(1);
+                 }
+                 /* set the defaults */
+                  while (j++ < nb_nics-1) {
+                     printf("setting default for NIC %d",j);
+                     for(i = 0; i < 6; i++) {
+                         if (i == 5)
+                             macaddrs[j][i] = macaddr[i]+j;
+                         else
+                             macaddrs[j][i] = macaddr[i];
+                     }
+                 }
+              }
+              break;
             case QEMU_OPTION_macaddr:
                 {
-                    const char *p;
-                    int i;
-                    p = optarg;
-                    for(i = 0; i < 6; i++) {
-                        macaddr[i] = strtol(p, (char **)&p, 16);
-                        if (i == 5) {
-                            if (*p != '\0') 
-                                goto macaddr_error;
-                        } else {
-                            if (*p != ':') {
-                            macaddr_error:
-                                fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
-                                exit(1);
-                            }
-                            p++;
-                        }
-                    }
-                }
-                break;
+                   char *macs[MAX_NICS];
+                   char *amac;
+                   const char *p; 
+                   char *p2; 
+                   int i, j = 0, first_mac_seen = 0;
+                   p = optarg;
+
+                  memset(macs,0,sizeof(macs));
+                  j=-1;
+                /* tokenize: unfortunately strtok is too smart for me */
+                  while(p!=NULL) {
+                      j++;
+                      macs[j] = (char *)p;
+                      p2 = strstr(p, ",");
+                      if (p2 == NULL)
+                          break;
+                      *p2 = 0;
+                      p = p2+1;
+                  }
+
+                  j = -1;
+                  while (j++ < nb_nics-1) {
+                      amac = macs[j];
+                      if (amac == NULL || !strlen(amac)) {
+                          for(i = 0; i < 6; i++) {
+                              if (i == 5)
+                                  macaddrs[j][i] = macaddr[i]+j;
+                              else
+                                  macaddrs[j][i] = macaddr[i];
+                          }
+
+                      continue;
+                      }
+
+                      for(i = 0; i < 6; i++) {
+                          macaddrs[j][i] = strtol(amac, (char **)&amac, 16);
+                          if (*amac != ':' && i != 5 ) {
+                              fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
+                              exit(1);
+                          }
+                          amac++;
+                      }
+
+                      if(!first_mac_seen) {
+                          for(i = 0; i < 6; i++) {
+                             macaddr[i] = macaddrs[j][i];
+                             }
+
+                          first_mac_seen = 1;
+                       }
+                   }
+               }
+               break;
 #ifdef CONFIG_SLIRP
             case QEMU_OPTION_tftp:
 		tftp_prefix = optarg;
@@ -3443,13 +3497,12 @@ int main(int argc, char **argv)
     for(i = 0; i < nb_nics; i++) {
         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->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:

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-08-26 12:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-21  0:36 [Qemu-devel] patch: allow defining MAC address etc jamal
2005-08-21  1:04 ` Paul Brook
2005-08-21  1:56   ` jamal
2005-08-21  2:22     ` Paul Brook
2005-08-21  2:46       ` jamal
2005-08-21  3:18         ` jamal
2005-08-21  4:30           ` Jim C. Brown
2005-08-21 15:51             ` jamal
2005-08-21  4:06         ` Jim C. Brown
2005-08-21 17:03   ` Fabrice Bellard
2005-08-26 11:43     ` Henrik Nordstrom
  -- strict thread matches above, loose matches on Subject: below --
2005-08-22  1:44 [Qemu-devel] PATCH: " jamal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).