+ netdev->ifindex = ifindex;
+
+ log_debug_netdev(netdev, "netdev has index %d", netdev->ifindex);
+
+ netdev_enter_ready(netdev);
+
+ return 0;
+}
+
+#define HASH_KEY SD_ID128_MAKE(52,e1,45,bd,00,6f,29,96,21,c6,30,6d,83,71,04,48)
+
+int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
+ _cleanup_free_ struct ether_addr *mac = NULL;
+ uint8_t result[8];
+ size_t l, sz;
+ uint8_t *v;
+ int r;
+
+ assert(ifname);
+ assert(ret);
+
+ mac = new0(struct ether_addr, 1);
+ if (!mac)
+ return -ENOMEM;
+
+ l = strlen(ifname);
+ sz = sizeof(sd_id128_t) + l;
+ v = alloca(sz);
+
+ /* fetch some persistent data unique to the machine */
+ r = sd_id128_get_machine((sd_id128_t*) v);
+ if (r < 0)
+ return r;
+
+ /* combine with some data unique (on this machine) to this
+ * netdev */
+ memcpy(v + sizeof(sd_id128_t), ifname, l);
+
+ /* Let's hash the host machine ID plus the container name. We
+ * use a fixed, but originally randomly created hash key here. */
+ siphash24(result, v, sz, HASH_KEY.bytes);
+
+ assert_cc(ETH_ALEN <= sizeof(result));
+ memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+
+ /* see eth_random_addr in the kernel */
+ mac->ether_addr_octet[0] &= 0xfe; /* clear multicast bit */
+ mac->ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */
+
+ *ret = mac;
+ mac = NULL;
+
+ return 0;
+}
+
+static int netdev_create(NetDev *netdev, Link *link) {
+ int r;
+
+ assert(netdev);
+
+ /* create netdev */
+ if (NETDEV_VTABLE(netdev)->create) {
+ r = NETDEV_VTABLE(netdev)->create(netdev);
+ if (r < 0)
+ return r;
+
+ log_debug_netdev(netdev, "created");
+ } else {
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not allocate RTM_NEWLINK message: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);