kernel: bump 6.1 to 6.1.53
[openwrt/staging/stintel.git] / target / linux / uml / patches-6.1 / 102-pseudo-random-mac.patch
1 ===============================================================================
2
3 This patch makes MAC addresses of network interfaces predictable. In
4 particular, it adds a small routine that computes MAC addresses of based on
5 a SHA1 hash of the virtual machine name and interface ID.
6
7 TECHNICAL INFORMATION:
8
9 Applies to vanilla kernel 3.9.4.
10
11 ===============================================================================
12 --- a/arch/um/drivers/Kconfig
13 +++ b/arch/um/drivers/Kconfig
14 @@ -143,6 +143,20 @@ config UML_NET
15 enable at least one of the following transport options to actually
16 make use of UML networking.
17
18 +config UML_NET_DETERMINISTIC_MAC
19 + bool "Use deterministic MAC addresses for network interfaces"
20 + default y
21 + depends on UML_NET
22 + select CRYPTO_SHA1
23 + help
24 + Virtual network devices inside a User-Mode Linux instance must be
25 + assigned a MAC (Ethernet) address. If none is specified on the UML
26 + command line, one must be automatically computed. If this option is
27 + enabled, a randomly generated address is used. Otherwise, if this
28 + option is disabled, the address is generated from a SHA1 hash of
29 + the umid of the UML instance and the interface name. The latter choice
30 + is useful to make MAC addresses predictable.
31 +
32 config UML_NET_ETHERTAP
33 bool "Ethertap transport (obsolete)"
34 depends on UML_NET
35 --- a/arch/um/drivers/net_kern.c
36 +++ b/arch/um/drivers/net_kern.c
37 @@ -25,6 +25,14 @@
38 #include <net_kern.h>
39 #include <net_user.h>
40
41 +#include <crypto/sha1.h>
42 +#include <crypto/hash.h>
43 +#include <linux/string.h>
44 +#include <linux/crypto.h>
45 +#include <linux/err.h>
46 +#include <linux/scatterlist.h>
47 +#include "os.h"
48 +
49 #define DRIVER_NAME "uml-netdev"
50
51 static DEFINE_SPINLOCK(opened_lock);
52 @@ -274,9 +282,55 @@ static const struct ethtool_ops uml_net_
53 .get_ts_info = ethtool_op_get_ts_info,
54 };
55
56 +#ifdef CONFIG_UML_NET_DETERMINISTIC_MAC
57 +
58 +/* Compute a SHA1 hash of the UML instance's id and
59 + * * an interface name. */
60 +static int compute_hash(const char *umid, const char *ifname, char *hash)
61 +{
62 + struct ahash_request *desc = NULL;
63 + struct crypto_ahash *tfm = NULL;
64 + struct scatterlist sg;
65 + char *vmif = NULL;
66 + int ret = -ENOMEM;
67 +
68 + vmif = kmalloc(1024, GFP_KERNEL);
69 + if (!vmif)
70 + goto out;
71 +
72 + strcpy (vmif, umid);
73 + strcat (vmif, ifname);
74 +
75 + tfm = crypto_alloc_ahash("sha1", 0, CRYPTO_ALG_ASYNC);
76 + if (IS_ERR(tfm))
77 + goto out;
78 +
79 + desc = ahash_request_alloc(tfm, GFP_KERNEL);
80 + if (!desc)
81 + goto out;
82 +
83 + crypto_ahash_clear_flags(tfm, ~0);
84 +
85 + sg_init_table(&sg, 1);
86 + sg_set_buf(&sg, vmif, strlen(vmif));
87 +
88 + ahash_request_set_crypt(desc, &sg, hash, strlen(vmif));
89 +
90 + ret = crypto_ahash_digest(desc);
91 +out:
92 + crypto_free_ahash(tfm);
93 + ahash_request_free(desc);
94 + kfree(vmif);
95 +
96 + return ret;
97 +}
98 +
99 +#endif
100 +
101 void uml_net_setup_etheraddr(struct net_device *dev, char *str)
102 {
103 u8 addr[ETH_ALEN];
104 + u8 hash[SHA1_DIGEST_SIZE];
105 char *end;
106 int i;
107
108 @@ -320,9 +374,26 @@ void uml_net_setup_etheraddr(struct net_
109 return;
110
111 random:
112 +#ifndef CONFIG_UML_NET_DETERMINISTIC_MAC
113 printk(KERN_INFO
114 "Choosing a random ethernet address for device %s\n", dev->name);
115 eth_hw_addr_random(dev);
116 +#else
117 + printk(KERN_INFO
118 + "Computing a digest to use as ethernet address for device %s\n", dev->name);
119 + if (compute_hash(get_umid(), dev->name, hash) < 0) {
120 + printk(KERN_WARNING
121 + "Could not compute digest to use as ethernet address for device %s. "
122 + "Using random address instead.\n", dev->name);
123 + eth_random_addr(addr);
124 + }
125 + else {
126 + for (i=0; i < 6; i++)
127 + addr[i] = (hash[i] + hash[i+6]) % 0x100;
128 + }
129 + addr [0] &= 0xfe; /* clear multicast bit */
130 + addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
131 +#endif
132 }
133
134 static DEFINE_SPINLOCK(devices_lock);
135 --- a/kernel/umh.c
136 +++ b/kernel/umh.c
137 @@ -357,12 +357,12 @@ static void helper_unlock(void)
138 }
139
140 int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
141 - struct file **filp)
142 + struct file **filp)
143 {
144 struct file *f[2];
145
146 if (create_pipe_files(f, 0) < 0)
147 - return PTR_ERR(f);
148 + return PTR_ERR(f);
149
150 sub_info->stdout = f[1];
151 *filp = f[0];