+int netdev_set_ifindex(NetDev *netdev, sd_rtnl_message *message) {
+ uint16_t type;
+ const char *kind;
+ char *received_kind;
+ char *received_name;
+ int r, ifindex;
+
+ assert(netdev);
+ assert(message);
+
+ r = sd_rtnl_message_get_type(message, &type);
+ if (r < 0) {
+ log_error_netdev(netdev, "Could not get rtnl message type");
+ return r;
+ }
+
+ if (type != RTM_NEWLINK) {
+ log_error_netdev(netdev, "Can not set ifindex from unexpected rtnl message type");
+ return -EINVAL;
+ }
+
+ r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
+ if (r < 0) {
+ log_error_netdev(netdev, "Could not get ifindex: %s", strerror(-r));
+ netdev_enter_failed(netdev);
+ return r;
+ } else if (ifindex <= 0) {
+ log_error_netdev(netdev, "Got invalid ifindex: %d", ifindex);
+ netdev_enter_failed(netdev);
+ return r;
+ }
+
+ if (netdev->ifindex > 0) {
+ if (netdev->ifindex != ifindex) {
+ log_error_netdev(netdev, "Could not set ifindex to %d, already set to %d",
+ ifindex, netdev->ifindex);
+ netdev_enter_failed(netdev);
+ return -EEXIST;
+ } else
+ /* ifindex already set to the same for this netdev */
+ return 0;
+ }
+
+ r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &received_name);
+ if (r < 0) {
+ log_error_netdev(netdev, "Could not get IFNAME");
+ return r;
+ }
+
+ if (!streq(netdev->ifname, received_name)) {
+ log_error_netdev(netdev, "Received newlink with wrong IFNAME %s",
+ received_name);
+ netdev_enter_failed(netdev);
+ return r;
+ }
+
+ r = sd_rtnl_message_enter_container(message, IFLA_LINKINFO);
+ if (r < 0) {
+ log_error_netdev(netdev, "Could not get LINKINFO");
+ return r;
+ }
+
+ r = sd_rtnl_message_read_string(message, IFLA_INFO_KIND, &received_kind);
+ if (r < 0) {
+ log_error_netdev(netdev, "Could not get KIND");
+ return r;
+ }
+
+ r = sd_rtnl_message_exit_container(message);
+ if (r < 0) {
+ log_error_netdev(netdev, "Could not exit container");
+ return r;
+ }
+
+ if (netdev->kind == NETDEV_KIND_TAP)
+ /* the kernel does not distinguish between tun and tap */
+ kind = "tun";
+ else {
+ kind = netdev_kind_to_string(netdev->kind);
+ if (!kind) {
+ log_error_netdev(netdev, "Could not get kind");
+ netdev_enter_failed(netdev);
+ return -EINVAL;
+ }
+ }
+
+ if (!streq(kind, received_kind)) {
+ log_error_netdev(netdev,
+ "Received newlink with wrong KIND %s, "
+ "expected %s", received_kind, kind);
+ netdev_enter_failed(netdev);
+ return r;
+ }
+
+ 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)
+
+static 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;