vkernel - Allow setting MAC addresses from within the command line.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Sun, 17 Feb 2013 11:41:45 +0000 (12:41 +0100)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Sun, 17 Feb 2013 12:44:53 +0000 (13:44 +0100)
  In order to be able to specify the MAC address we want to
  use for every interface within the vkernel, an extra argument
  has been added to the -I option.

  Example:
   ./kernel -r root.img -m 256m -I auto=aa:bb:cc:dd:ee:ff

share/man/man7/vkernel.7
sys/dev/virtual/vkernel/net/if_vke.c
sys/platform/vkernel/include/md_var.h
sys/platform/vkernel/platform/init.c
sys/platform/vkernel64/include/md_var.h
sys/platform/vkernel64/platform/init.c

index 43714a5..a752a0b 100644 (file)
@@ -29,7 +29,7 @@
 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd May 17, 2012
+.Dd Feb 17, 2013
 .Dt VKERNEL 7
 .Os
 .Sh NAME
@@ -50,7 +50,7 @@
 .Op Fl c Ar file
 .Op Fl e Ar name Ns = Ns Li value : Ns Ar name Ns = Ns Li value : Ns ...
 .Op Fl i Ar file
-.Op Fl I Ar interface Ns Op Ar :address1 Ns Oo Ar :address2 Oc Ns Oo Ar /netmask Oc
+.Op Fl I Ar interface Ns Op Ar :address1 Ns Oo Ar :address2 Oc Ns Oo Ar /netmask Oc Ns Oo Ar =MAC Oc
 .Op Fl l Ar cpulock
 .Op Fl m Ar size
 .Op Fl n Ar numcpus Ns Op Ar :lbits Ns Oo Ar :cbits Oc
@@ -98,7 +98,7 @@ with the trailing
 .Ql X Ns s
 being replaced by a sequential number, e.g.\&
 .Pa memimg.000001 .
-.It Fl I Ar interface Ns Op Ar :address1 Ns Oo Ar :address2 Oc Ns Oo Ar /netmask Oc
+.It Fl I Ar interface Ns Op Ar :address1 Ns Oo Ar :address2 Oc Ns Oo Ar /netmask Oc Ns Oo Ar =MAC Oc
 Create a virtual network device, with the first
 .Fl I
 option defining
@@ -150,6 +150,13 @@ The
 .Ar netmask
 argument applies to all interfaces for which an address is specified.
 .Pp
+The
+.Ar MAC
+argument is the MAC address of the
+.Xr vke 4
+interface.
+If not specified, a pseudo-random one will be generated.
+.Pp
 When running multiple vkernels it is often more convenient to simply
 connect to a
 .Xr vknetd 8
index ef65b80..d7e957d 100644 (file)
@@ -683,6 +683,11 @@ vke_attach(const struct vknetif_info *info, int unit)
        KKASSERT(info->tap_fd >= 0);
        fd = info->tap_fd;
 
+       if (info->enaddr) {
+               bcopy(info->enaddr, enaddr, ETHER_ADDR_LEN);
+               goto havemac;
+       }
+
        /*
         * This is only a TAP device if tap_unit is non-zero.  If
         * connecting to a virtual socket we generate a unique MAC.
@@ -711,6 +716,7 @@ vke_attach(const struct vknetif_info *info, int unit)
        }
        enaddr[1] += 1;
 
+havemac:
        sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
 
        sc->sc_txbuf = kmalloc(MCLBYTES, M_DEVBUF, M_WAITOK);
index 2597bf4..3511be7 100644 (file)
@@ -41,6 +41,9 @@
 #ifndef _SYS_VKERNEL_H_
 #include <sys/vkernel.h>
 #endif
+#ifndef _NET_ETHERNET_H_
+#include <net/ethernet.h>
+#endif
 
 #define VKNETIF_MAX    16
 #define VKDISK_MAX     16
@@ -50,6 +53,7 @@ struct vknetif_info {
        int             tap_unit;
        in_addr_t       netif_addr;
        in_addr_t       netif_mask;
+       u_char          *enaddr;
 };
 
 struct vkdisk_info {
index 9b2dd01..afd578c 100644 (file)
@@ -65,6 +65,7 @@
 #include <net/bridge/if_bridgevar.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <net/if_var.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -1213,6 +1214,7 @@ void
 init_netif(char *netifExp[], int netifExpNum)
 {
        int i, s;
+       char *tmp;
 
        if (netifExpNum == 0)
                return;
@@ -1227,6 +1229,10 @@ init_netif(char *netifExp[], int netifExpNum)
                int tap_fd, tap_unit;
                char *netif;
 
+               /* Extract MAC address if there is one */
+               tmp = netifExp[i];
+               strsep(&tmp, "=");
+
                netif = strtok(netifExp[i], ":");
                if (netif == NULL) {
                        warnx("Invalid argument to '-I'");
@@ -1258,10 +1264,27 @@ init_netif(char *netifExp[], int netifExpNum)
                }
 
                info = &NetifInfo[NetifNum];
+               bzero(info, sizeof(*info));
                info->tap_fd = tap_fd;
                info->tap_unit = tap_unit;
                info->netif_addr = netif_addr;
                info->netif_mask = netif_mask;
+               /*
+                * If tmp isn't NULL it means a MAC could have been
+                * specified so attempt to convert it.
+                * Setting enaddr to NULL will tell vke_attach() we
+                * need a pseudo-random MAC address.
+                */
+               if (tmp != NULL) {
+                       if ((info->enaddr = malloc(ETHER_ADDR_LEN)) == NULL)
+                               warnx("Couldn't allocate memory for the operation");
+                       else {
+                               if ((kether_aton(tmp, info->enaddr)) == NULL) {
+                                       free(info->enaddr);
+                                       info->enaddr = NULL;
+                               }
+                       }
+               }
 
                NetifNum++;
                if (NetifNum >= VKNETIF_MAX)    /* XXX will this happen? */
index 286b2fb..3044ed7 100644 (file)
@@ -43,6 +43,9 @@
 #ifndef _SYS_VKERNEL_H_
 #include <sys/vkernel.h>
 #endif
+#ifndef _NET_ETHERNET_H_
+#include <net/ethernet.h>
+#endif
 
 #define VKNETIF_MAX    16
 #define VKDISK_MAX     16
@@ -52,6 +55,7 @@ struct vknetif_info {
        int             tap_unit;
        in_addr_t       netif_addr;
        in_addr_t       netif_mask;
+       u_char          *enaddr;
 };
 
 struct vkdisk_info {
index 2b0ca2d..cdbdb3d 100644 (file)
@@ -66,6 +66,7 @@
 #include <net/bridge/if_bridgevar.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <net/if_var.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -1178,6 +1179,7 @@ void
 init_netif(char *netifExp[], int netifExpNum)
 {
        int i, s;
+       char *tmp;
 
        if (netifExpNum == 0)
                return;
@@ -1192,6 +1194,10 @@ init_netif(char *netifExp[], int netifExpNum)
                int tap_fd, tap_unit;
                char *netif;
 
+               /* Extract MAC address if there is one */
+               tmp = netifExp[i];
+               strsep(&tmp, "=");
+
                netif = strtok(netifExp[i], ":");
                if (netif == NULL) {
                        warnx("Invalid argument to '-I'");
@@ -1223,10 +1229,27 @@ init_netif(char *netifExp[], int netifExpNum)
                }
 
                info = &NetifInfo[NetifNum];
+               bzero(info, sizeof(*info));
                info->tap_fd = tap_fd;
                info->tap_unit = tap_unit;
                info->netif_addr = netif_addr;
                info->netif_mask = netif_mask;
+               /*
+                * If tmp isn't NULL it means a MAC could have been
+                * specified so attempt to convert it.
+                * Setting enaddr to NULL will tell vke_attach() we
+                * need a pseudo-random MAC address.
+                */
+               if (tmp != NULL) {
+                       if ((info->enaddr = malloc(ETHER_ADDR_LEN)) == NULL)
+                               warnx("Couldn't allocate memory for the operation");
+                       else {
+                               if ((kether_aton(tmp, info->enaddr)) == NULL) {
+                                       free(info->enaddr);
+                                       info->enaddr = NULL;
+                               }
+                       }
+               }
 
                NetifNum++;
                if (NetifNum >= VKNETIF_MAX)    /* XXX will this happen? */