set_netdev_labels() {
	local dir
	local label
	local netdev
	local phase

	# park: move every mislabelled interface to a temporary name first,
	# so that swaps (e.g. eth0 <-> eth1) cannot collide
	# rename: give every interface its final name
	for phase in park rename; do
		for dir in /sys/class/net/*; do
			label=
			[ -r "$dir/of_node/label" ] && \
				read -r label < "$dir/of_node/label"
			[ -r "$dir/of_node/openwrt,netdev-name" ] && \
				read -r label < "$dir/of_node/openwrt,netdev-name"
			[ -n "$label" ] || continue

			netdev="${dir##*/}"
			[ "$netdev" = "$label" ] && continue

			if [ "$phase" = "park" ]; then
				ip link set "$netdev" name "tmp%d"
			else
				ip link set "$netdev" name "$label"
			fi
		done
	done
}

boot_hook_add preinit_main set_netdev_labels
