[Lguest] rng / netmask / tapdev name patches
Philip Sanderson
philip.k.sanderson at gmail.com
Wed Dec 1 23:26:34 EST 2010
Hello,
Here's some random patches for your consideration :-)
First patch allows you to specify the source of the random numbers instead
of /dev/random. Using /dev/urandom is faster and doesn't exhaust hosts
entropy, or you could specify /dev/hwrng for direct access, etc.
--- lguest.c.orig 2010-12-01 19:48:18.212001069 +1100
+++ lguest.c 2010-12-01 19:52:15.325002565 +1100
@@ -1802,13 +1802,13 @@
/*L:199
* This creates a "hardware" random number device for the Guest.
*/
-static void setup_rng(void)
+static void setup_rng(char *rng_source)
{
struct device *dev;
struct rng_info *rng_info = malloc(sizeof(*rng_info));
- /* Our device's privat info simply contains the /dev/random fd. */
- rng_info->rfd = open_or_die("/dev/random", O_RDONLY);
+ /* Our device's privat info simply contains the rng_source fd. */
+ rng_info->rfd = open_or_die(rng_source, O_RDONLY);
/* Create the new device. */
dev = new_device("rng", VIRTIO_ID_RNG);
@@ -1817,7 +1817,7 @@
/* The device has one virtqueue, where the Guest places inbufs. */
add_virtqueue(dev, VIRTQUEUE_NUM, rng_input);
- verbose("device %u: rng\n", devices.device_num++);
+ verbose("device %u: rng from %s\n", devices.device_num++,
rng_source);
}
/* That's the end of device setup. */
@@ -1885,6 +1885,7 @@
{ "tunnet", 1, NULL, 't' },
{ "block", 1, NULL, 'b' },
{ "rng", 0, NULL, 'r' },
+ { "rng-source", 1, NULL, 's' },
{ "initrd", 1, NULL, 'i' },
{ "username", 1, NULL, 'u' },
{ "chroot", 1, NULL, 'c' },
@@ -1916,6 +1917,9 @@
/* Directory to chroot to */
char *chroot_path = NULL;
+ /* RNG source, defaults to /dev/random */
+ char *rng_source = "/dev/random";
+
/* Save the args: we "reboot" by execing ourselves again. */
main_args = argv;
@@ -1966,8 +1970,11 @@
case 'b':
setup_block_file(optarg);
break;
+ case 's':
+ rng_source = optarg;
+ break;
case 'r':
- setup_rng();
+ setup_rng(rng_source);
break;
case 'i':
initrd_name = optarg;
This patch allows you to specify the tap device name -- useful for iptables
-i interface and long lived rules.
--- lguest.c.rng 2010-12-01 20:24:44.577001373 +1100
+++ lguest.c 2010-12-01 20:22:24.924001823 +1100
@@ -1482,7 +1482,8 @@
*/
netfd = open_or_die("/dev/net/tun", O_RDWR);
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
- strcpy(ifr.ifr_name, "tap%d");
+ strcpy(ifr.ifr_name, tapif);
if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
err(1, "configuring /dev/net/tun");
@@ -1506,7 +1507,7 @@
* packets into the Host as if they came in from a normal network card. We
* just shunt packets between the Guest and the tun device.
*/
-static void setup_tun_net(char *arg)
+static void setup_tun_net(char *arg, char *tapdev_name)
{
struct device *dev;
struct net_info *net_info = malloc(sizeof(*net_info));
@@ -1516,6 +1517,10 @@
char tapif[IFNAMSIZ], *p;
struct virtio_net_config conf;
+ /* Copy over the device name we are going to use */
+ strncpy(tapif, tapdev_name, IFNAMSIZ);
+ tapif[IFNAMSIZ-1] = '\0';
+
net_info->tunfd = get_tun_device(tapif);
/* First we create a new network device. */
@@ -1882,6 +1887,7 @@
static struct option opts[] = {
{ "verbose", 0, NULL, 'v' },
+ { "tap-name", 1, NULL, 'd' },
{ "tunnet", 1, NULL, 't' },
{ "block", 1, NULL, 'b' },
{ "rng", 0, NULL, 'r' },
@@ -1920,6 +1926,9 @@
/* RNG source, defaults to /dev/random */
char *rng_source = "/dev/random";
+ /* The device name to set in setup_tun_net */
+ char *tap_name = "tap%d";
+
/* Save the args: we "reboot" by execing ourselves again. */
main_args = argv;
@@ -1964,8 +1973,11 @@
case 'v':
verbose = true;
break;
+ case 'd':
+ tap_name = optarg;
+ break;
case 't':
- setup_tun_net(optarg);
+ setup_tun_net(optarg, tap_name);
break;
case 'b':
setup_block_file(optarg);
This patch allows you to specify the netmask on the command line. Useful if
you don't want to assign the default netmask class to the instance. (ie, /31
or /30's).
--- lguest.c.tapdev 2010-12-01 20:27:13.462001086 +1100
+++ lguest.c 2010-12-01 20:53:24.990000713 +1100
@@ -1447,7 +1447,7 @@
* it up so packets will flow, the copies the MAC address into the hwaddr
* pointer.
*/
-static void configure_device(int fd, const char *tapif, u32 ipaddr)
+static void configure_device(int fd, const char *tapif, u32 ipaddr, u32
netmask)
{
struct ifreq ifr;
struct sockaddr_in sin;
@@ -1459,8 +1459,26 @@
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(ipaddr);
memcpy(&ifr.ifr_addr, &sin, sizeof(sin));
+
if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
err(1, "Setting %s interface address", tapif);
+
+ if(netmask) {
+ sin.sin_addr.s_addr = htonl(netmask);
+ memcpy(&ifr.ifr_netmask, &sin, sizeof(sin));
+
+ if(ioctl(fd, SIOCSIFNETMASK, &ifr) != 0)
+ err(1, "Setting %s interface netmask", tapif);
+
+ /* Set the broadcast address, otherwise it will be incorrect
:/ */
+ sin.sin_addr.s_addr = htonl(ipaddr | ~(0xffffffff &
netmask));
+ memcpy(&ifr.ifr_broadaddr, &sin, sizeof(sin));
+
+ if(ioctl(fd, SIOCSIFBRDADDR, &ifr) != 0)
+ err(1, "Setting %s interface broadcast", tapif);
+
+ }
+
ifr.ifr_flags = IFF_UP;
if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
err(1, "Bringing interface %s up", tapif);
@@ -1513,6 +1531,7 @@
struct net_info *net_info = malloc(sizeof(*net_info));
int ipfd;
u32 ip = INADDR_ANY;
+ u32 nm = 0;
bool bridging = false;
char tapif[IFNAMSIZ], *p;
struct virtio_net_config conf;
@@ -1553,14 +1572,25 @@
*p = '\0';
}
- /* arg is now either an IP address or a bridge name */
- if (bridging)
+ /* arg is now either an IP address(/netmask) or a bridge name */
+ if (bridging) {
add_to_bridge(ipfd, tapif, arg);
- else
+ } else {
+ p = strchr(arg, '/');
+ if(p) {
+ /* Calculate the netmask */
+ int shift = 0;
+ shift = atoi(p+1);
+ nm = ~(0xffffffff >> shift);
+
+ *p = 0;
+ }
+
ip = str2ip(arg);
+ }
/* Set up the tun device. */
- configure_device(ipfd, tapif, ip);
+ configure_device(ipfd, tapif, ip, nm);
add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
/* Expect Guest to handle everything except UFO */
And here's some additional documentation :-)
--- lguest.txt.orig 2010-12-01 20:58:32.555001127 +1100
+++ lguest.txt 2010-12-01 21:05:16.253000679 +1100
@@ -83,7 +83,13 @@
can also use a standard bzImage.
--tunnet=192.168.19.1: configures a "tap" device for networking with
this
- IP address.
+ IP address. You can specify the netmask in CIDR notation as
+ --tunnet=192.168.19.1/30
+
+ If you require the ability to specify the tap device name, the
option
+ --tap-name example0 can be specified before --tunnet. This can be
+ useful if you are running multiple lguest's, and are using
+ iptables.
--block=rootfile: a file or block device which becomes /dev/vda
inside the guest.
@@ -114,10 +120,15 @@
See http://linux-net.osdl.org/index.php/Bridge for general information
on how to get bridging working.
-- Random number generation. Using the --rng option will provide a
- /dev/hwrng in the guest that will read from the host's /dev/random.
- Use this option in conjunction with rng-tools (see ../hw_random.txt)
- to provide entropy to the guest kernel's /dev/random.
+- Random number generation. Using the --rng option will provide a
/dev/hwrng
+ in the guest that will read from the host's /dev/random. Use this option
in
+ conjunction with rng-tools (see ../hw_random.txt) to provide entropy to
the
+ guest kernel's /dev/random. You may specify --rng-source before --rng to
+ change the source of the random numbers. Specifying /dev/urandom has the
+ advantage of being faster and does not allow malicious guests to exhaust
the
+ hosts entropy pool, however the quality of the randomness may be reduced.
+ Another use of this option is to allow direct access to the hardware
random
+ number generator on the host.
There is a helpful mailing list at
http://ozlabs.org/mailman/listinfo/lguest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/lguest/attachments/20101201/f337b2d2/attachment.html>
More information about the Lguest
mailing list