forked from Openwrt-EcoNet/openwrt
refresh config + patches. This includes the following changes: - The selected x86_64 CPU is switched to generic instead of K8. A backported patch is included from 6.13. 000-v6.13-asm-generic-io.h-rework-split-ioread64-iowrite64-hel.patch |fixed the following build error: | CC lib/iomap.o |lib/iomap.c:156:5: error: no previous prototype for 'ioread64_lo_hi' [-Werror=missing-prototypes] | 156 | u64 ioread64_lo_hi(const void __iomem *addr) | | ^~~~~~~~~~~~~~ | [...] Note: 102-pseudo-random-mac.patch will likely go away with the next stable. UML is switching to a new networking infrastructure. The previous implementation using tuntap, daemon, socket, ethertap, vde are being replaced by "vector" transports tap, hybrid, raw, EoGRE, Eol2tpv3, fd, vde (vector!). Please see, to checkout what will change: <https://docs.kernel.org/virt/uml/user_mode_linux_howto_v2.html#setting-up-uml-networking> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
152 lines
4.1 KiB
Diff
152 lines
4.1 KiB
Diff
===============================================================================
|
|
|
|
This patch makes MAC addresses of network interfaces predictable. In
|
|
particular, it adds a small routine that computes MAC addresses of based on
|
|
a SHA1 hash of the virtual machine name and interface ID.
|
|
|
|
TECHNICAL INFORMATION:
|
|
|
|
Applies to vanilla kernel 3.9.4.
|
|
|
|
===============================================================================
|
|
--- a/arch/um/drivers/Kconfig
|
|
+++ b/arch/um/drivers/Kconfig
|
|
@@ -143,6 +143,20 @@ config UML_NET
|
|
enable at least one of the following transport options to actually
|
|
make use of UML networking.
|
|
|
|
+config UML_NET_DETERMINISTIC_MAC
|
|
+ bool "Use deterministic MAC addresses for network interfaces"
|
|
+ default y
|
|
+ depends on UML_NET
|
|
+ select CRYPTO_SHA1
|
|
+ help
|
|
+ Virtual network devices inside a User-Mode Linux instance must be
|
|
+ assigned a MAC (Ethernet) address. If none is specified on the UML
|
|
+ command line, one must be automatically computed. If this option is
|
|
+ enabled, a randomly generated address is used. Otherwise, if this
|
|
+ option is disabled, the address is generated from a SHA1 hash of
|
|
+ the umid of the UML instance and the interface name. The latter choice
|
|
+ is useful to make MAC addresses predictable.
|
|
+
|
|
config UML_NET_ETHERTAP
|
|
bool "Ethertap transport (obsolete)"
|
|
depends on UML_NET
|
|
--- a/arch/um/drivers/net_kern.c
|
|
+++ b/arch/um/drivers/net_kern.c
|
|
@@ -25,6 +25,14 @@
|
|
#include <net_kern.h>
|
|
#include <net_user.h>
|
|
|
|
+#include <crypto/sha1.h>
|
|
+#include <crypto/hash.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/crypto.h>
|
|
+#include <linux/err.h>
|
|
+#include <linux/scatterlist.h>
|
|
+#include "os.h"
|
|
+
|
|
#define DRIVER_NAME "uml-netdev"
|
|
|
|
static DEFINE_SPINLOCK(opened_lock);
|
|
@@ -274,9 +282,55 @@ static const struct ethtool_ops uml_net_
|
|
.get_ts_info = ethtool_op_get_ts_info,
|
|
};
|
|
|
|
+#ifdef CONFIG_UML_NET_DETERMINISTIC_MAC
|
|
+
|
|
+/* Compute a SHA1 hash of the UML instance's id and
|
|
+ * * an interface name. */
|
|
+static int compute_hash(const char *umid, const char *ifname, char *hash)
|
|
+{
|
|
+ struct ahash_request *desc = NULL;
|
|
+ struct crypto_ahash *tfm = NULL;
|
|
+ struct scatterlist sg;
|
|
+ char *vmif = NULL;
|
|
+ int ret = -ENOMEM;
|
|
+
|
|
+ vmif = kmalloc(1024, GFP_KERNEL);
|
|
+ if (!vmif)
|
|
+ goto out;
|
|
+
|
|
+ strcpy (vmif, umid);
|
|
+ strcat (vmif, ifname);
|
|
+
|
|
+ tfm = crypto_alloc_ahash("sha1", 0, CRYPTO_ALG_ASYNC);
|
|
+ if (IS_ERR(tfm))
|
|
+ goto out;
|
|
+
|
|
+ desc = ahash_request_alloc(tfm, GFP_KERNEL);
|
|
+ if (!desc)
|
|
+ goto out;
|
|
+
|
|
+ crypto_ahash_clear_flags(tfm, ~0);
|
|
+
|
|
+ sg_init_table(&sg, 1);
|
|
+ sg_set_buf(&sg, vmif, strlen(vmif));
|
|
+
|
|
+ ahash_request_set_crypt(desc, &sg, hash, strlen(vmif));
|
|
+
|
|
+ ret = crypto_ahash_digest(desc);
|
|
+out:
|
|
+ crypto_free_ahash(tfm);
|
|
+ ahash_request_free(desc);
|
|
+ kfree(vmif);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
void uml_net_setup_etheraddr(struct net_device *dev, char *str)
|
|
{
|
|
u8 addr[ETH_ALEN];
|
|
+ u8 hash[SHA1_DIGEST_SIZE];
|
|
char *end;
|
|
int i;
|
|
|
|
@@ -320,9 +374,26 @@ void uml_net_setup_etheraddr(struct net_
|
|
return;
|
|
|
|
random:
|
|
+#ifndef CONFIG_UML_NET_DETERMINISTIC_MAC
|
|
printk(KERN_INFO
|
|
"Choosing a random ethernet address for device %s\n", dev->name);
|
|
eth_hw_addr_random(dev);
|
|
+#else
|
|
+ printk(KERN_INFO
|
|
+ "Computing a digest to use as ethernet address for device %s\n", dev->name);
|
|
+ if (compute_hash(get_umid(), dev->name, hash) < 0) {
|
|
+ printk(KERN_WARNING
|
|
+ "Could not compute digest to use as ethernet address for device %s. "
|
|
+ "Using random address instead.\n", dev->name);
|
|
+ eth_random_addr(addr);
|
|
+ }
|
|
+ else {
|
|
+ for (i=0; i < 6; i++)
|
|
+ addr[i] = (hash[i] + hash[i+6]) % 0x100;
|
|
+ }
|
|
+ addr [0] &= 0xfe; /* clear multicast bit */
|
|
+ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
|
|
+#endif
|
|
}
|
|
|
|
static DEFINE_SPINLOCK(devices_lock);
|
|
--- a/kernel/umh.c
|
|
+++ b/kernel/umh.c
|
|
@@ -354,12 +354,12 @@ static void helper_unlock(void)
|
|
}
|
|
|
|
int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
|
|
- struct file **filp)
|
|
+ struct file **filp)
|
|
{
|
|
struct file *f[2];
|
|
|
|
if (create_pipe_files(f, 0) < 0)
|
|
- return PTR_ERR(f);
|
|
+ return PTR_ERR(f);
|
|
|
|
sub_info->stdout = f[1];
|
|
*filp = f[0];
|