Browse Source

Merge branch 'v1.5' into LTS : 20200122

RISCi_ATOM 4 years ago
parent
commit
080730e92b
100 changed files with 3197 additions and 1492 deletions
  1. 2 0
      .gitignore
  2. 0 2
      Config.in
  3. 25 14
      Makefile
  4. 0 15
      README.md
  5. 62 8
      config/Config-build.in
  6. 14 5
      config/Config-devel.in
  7. 32 10
      config/Config-images.in
  8. 108 14
      config/Config-kernel.in
  9. 84 0
      docs/FAQ.md
  10. 2 0
      docs/GL-AR300M.md
  11. 0 1
      docs/List_of_Tested_Hardware.md
  12. 27 15
      docs/README.md
  13. 6 12
      docs/Supported_Hardware.md
  14. 10 7
      docs/TL_WR1043ND.md
  15. 1 1
      feeds.conf.default
  16. 6 4
      include/autotools.mk
  17. 5 4
      include/cmake.mk
  18. 7 1
      include/depends.mk
  19. 1 1
      include/device_table.txt
  20. 64 25
      include/download.mk
  21. 13 21
      include/feeds.mk
  22. 2 0
      include/hardened-ld-pie.specs
  23. 7 0
      include/hardening.mk
  24. 30 26
      include/host-build.mk
  25. 0 51
      include/host.mk
  26. 196 11
      include/image-commands.mk
  27. 101 32
      include/image.mk
  28. 13 10
      include/kernel-build.mk
  29. 16 36
      include/kernel-defaults.mk
  30. 20 2
      include/kernel-version.mk
  31. 113 65
      include/kernel.mk
  32. 56 15
      include/netfilter.mk
  33. 1 1
      include/nls.mk
  34. 14 4
      include/package-bin.mk
  35. 5 3
      include/package-defaults.mk
  36. 15 45
      include/package-dumpinfo.mk
  37. 46 35
      include/package-ipkg.mk
  38. 96 51
      include/package.mk
  39. 33 30
      include/prereq-build.mk
  40. 14 1
      include/prereq.mk
  41. 40 29
      include/quilt.mk
  42. 22 8
      include/rootfs.mk
  43. 1 1
      include/scan.awk
  44. 17 5
      include/scan.mk
  45. 26 0
      include/site/powerpc64
  46. 23 8
      include/subdir.mk
  47. 29 28
      include/target.mk
  48. 3 2
      include/toolchain-build.mk
  49. 45 18
      include/toplevel.mk
  50. 104 0
      include/u-boot.mk
  51. 2 7
      include/unpack.mk
  52. 11 11
      include/verbose.mk
  53. 42 43
      include/version.mk
  54. 16 10
      package/Makefile
  55. 54 18
      package/base-files/Makefile
  56. 50 31
      package/base-files/files/bin/config_generate
  57. 3 1
      package/base-files/files/etc/banner.failsafe
  58. 48 2
      package/base-files/files/etc/diag.sh
  59. 6 0
      package/base-files/files/etc/ethers
  60. 1 0
      package/base-files/files/etc/group
  61. 1 1
      package/base-files/files/etc/hotplug.d/net/00-sysctl
  62. 1 1
      package/base-files/files/etc/init.d/boot
  63. 10 4
      package/base-files/files/etc/init.d/gpio_switch
  64. 8 2
      package/base-files/files/etc/init.d/led
  65. 30 11
      package/base-files/files/etc/init.d/sysctl
  66. 4 8
      package/base-files/files/etc/init.d/system
  67. 6 1
      package/base-files/files/etc/init.d/umount
  68. 8 0
      package/base-files/files/etc/iproute2/ematch_map
  69. 1 2
      package/base-files/files/etc/openwrt_release
  70. 9 2
      package/base-files/files/etc/profile
  71. 12 0
      package/base-files/files/etc/rc.button/reboot
  72. 1 1
      package/base-files/files/etc/rc.button/reset
  73. 20 10
      package/base-files/files/etc/rc.common
  74. 4 2
      package/base-files/files/etc/services
  75. 1 30
      package/base-files/files/etc/sysctl.conf
  76. 27 0
      package/base-files/files/etc/sysctl.d/10-default.conf
  77. 0 16
      package/base-files/files/etc/uci-defaults/11_migrate-sysctl
  78. 51 46
      package/base-files/files/lib/functions.sh
  79. 14 0
      package/base-files/files/lib/functions/leds.sh
  80. 39 0
      package/base-files/files/lib/functions/migrations.sh
  81. 19 3
      package/base-files/files/lib/functions/network.sh
  82. 40 19
      package/base-files/files/lib/functions/system.sh
  83. 145 193
      package/base-files/files/lib/functions/uci-defaults.sh
  84. 0 0
      package/base-files/files/lib/preinit/02_sysinfo
  85. 5 7
      package/base-files/files/lib/preinit/10_indicate_preinit
  86. 1 1
      package/base-files/files/lib/preinit/30_failsafe_wait
  87. 5 1
      package/base-files/files/lib/preinit/40_run_failsafe_hook
  88. 0 24
      package/base-files/files/lib/preinit/81_urandom_seed
  89. 7 4
      package/base-files/files/lib/preinit/99_10_failsafe_login
  90. 79 194
      package/base-files/files/lib/upgrade/common.sh
  91. 25 0
      package/base-files/files/lib/upgrade/do_stage2
  92. 24 2
      package/base-files/files/lib/upgrade/fwtool.sh
  93. 323 0
      package/base-files/files/lib/upgrade/nand.sh
  94. 137 0
      package/base-files/files/lib/upgrade/stage2
  95. 130 0
      package/base-files/files/sbin/pkg_check
  96. 204 72
      package/base-files/files/sbin/sysupgrade
  97. 0 20
      package/base-files/files/sbin/urandom_seed
  98. 3 2
      package/base-files/files/sbin/wifi
  99. 12 12
      package/base-files/files/usr/lib/os-release
  100. 1 1
      package/base-files/files/usr/libexec/login.sh

+ 2 - 0
.gitignore

@@ -16,6 +16,7 @@
 /overlay
 /package/feeds
 /package/openwrt-packages
+/*.patch
 key-build*
 *.orig
 *.rej
@@ -30,3 +31,4 @@ git-src
 *.swp
 *.po~
 /package/luci/modules/luci-base/src/po2lmo
+/package/luci/modules/luci-base/src/jsmin

+ 0 - 2
Config.in

@@ -31,6 +31,4 @@ source "target/sdk/Config.in"
 
 source "target/toolchain/Config.in"
 
-source "target/ccsdisk/Config.in"
-
 source "tmp/.config-package.in"

+ 25 - 14
Makefile

@@ -1,4 +1,4 @@
-# Makefile for OpenWrt
+# Makefile for libreCMC
 #
 # Copyright (C) 2007 OpenWrt.org
 #
@@ -14,19 +14,22 @@ export TOPDIR LC_ALL LANG TZ
 
 empty:=
 space:= $(empty) $(empty)
-$(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the LEDE directory must not include any spaces))
+$(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the libreCMC directory must not include any spaces))
 
 world:
 
-include $(TOPDIR)/include/host.mk
+DISTRO_PKG_CONFIG:=$(shell which -a pkg-config | grep -E '\/usr' | head -n 1)
+export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
 
-ifneq ($(OPENWRT_BUILD),1)
+ifneq ($(LIBRECMC_BUILD),1)
   _SINGLE=export MAKEFLAGS=$(space);
 
-  override OPENWRT_BUILD=1
-  export OPENWRT_BUILD
+  override LIBRECMC_BUILD=1
+  export LIBRECMC_BUILD
   GREP_OPTIONS=
   export GREP_OPTIONS
+  CDPATH=
+  export CDPATH
   include $(TOPDIR)/include/debug.mk
   include $(TOPDIR)/include/depends.mk
   include $(TOPDIR)/include/toplevel.mk
@@ -39,8 +42,8 @@ else
   include tools/Makefile
   include toolchain/Makefile
 
-$(toolchain/stamp-install): $(tools/stamp-install)
-$(target/stamp-compile): $(toolchain/stamp-install) $(tools/stamp-install) $(BUILD_DIR)/.prepared
+$(toolchain/stamp-compile): $(tools/stamp-compile)
+$(target/stamp-compile): $(toolchain/stamp-compile) $(tools/stamp-compile) $(BUILD_DIR)/.prepared
 $(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
 $(package/stamp-install): $(package/stamp-compile)
 $(target/stamp-install): $(package/stamp-compile) $(package/stamp-install)
@@ -55,7 +58,7 @@ clean: FORCE
 	rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(BUILD_LOG_DIR) $(TOPDIR)/staging_dir/packages
 
 dirclean: clean
-	rm -rf $(STAGING_DIR_HOST) $(TOOLCHAIN_DIR) $(BUILD_DIR_HOST) $(BUILD_DIR_TOOLCHAIN)
+	rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/host $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
 	rm -rf $(TMP_DIR)
 
 ifndef DUMP_TARGET_DB
@@ -85,18 +88,26 @@ prereq: $(target/stamp-prereq) tmp/.prereq_packages
 	fi
 
 checksum: FORCE
-	$(call sha256sums,$(BIN_DIR))
+	$(call sha256sums,$(BIN_DIR),$(CONFIG_BUILDBOT))
 
-ccsdisk: $(target/ccsdisk/install)
+buildversion: FORCE
+	$(SCRIPT_DIR)/getver.sh > $(BIN_DIR)/version.buildinfo
+
+feedsversion: FORCE
+	$(SCRIPT_DIR)/feeds list -fs > $(BIN_DIR)/feeds.buildinfo
 
 diffconfig: FORCE
 	mkdir -p $(BIN_DIR)
-	$(SCRIPT_DIR)/diffconfig.sh > $(BIN_DIR)/config.seed
+	$(SCRIPT_DIR)/diffconfig.sh > $(BIN_DIR)/config.buildinfo
+
+buildinfo: FORCE
+	$(_SINGLE)$(SUBMAKE) -r diffconfig buildversion feedsversion
+
+prepare: .config $(tools/stamp-compile) $(toolchain/stamp-compile)
+	$(_SINGLE)$(SUBMAKE) -r buildinfo
 
-prepare: .config $(tools/stamp-install) $(toolchain/stamp-install)
 world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
 	$(_SINGLE)$(SUBMAKE) -r package/index
-	$(_SINGLE)$(SUBMAKE) -r diffconfig
 	$(_SINGLE)$(SUBMAKE) -r checksum
 
 .PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean

+ 0 - 15
README.md

@@ -1,15 +0,0 @@
-# libreCMC : The _libre_ Embedded GNU/Linux Distro.
-
-libreCMC is a set of fully [free](http://www.gnu.org/philosophy/free-sw.en.html) embedded Operating Systems for general purpose computers. It aims to give its users freedom and control over the software that runs on their hardware. Most of the hardware that libreCMC supports includes a wide range of routers and some small single board computers.
-
-## Useful links:
-
-* [Get libreCMC source code](/) : Checkout the latest libreCMC sources.
-
-* [Supported Hardware](/docs/Supported_Hardware.md): Devices officially supported by libreCMC.
-
-* [Router reset instructions](/docs/Router_Reset_Instructions.md) : Generic libreCMC router reset instructions.
-
-* [Report a bug or issue](https://gogs.librecmc.org/libreCMC/libreCMC/issues) : Is something broken? Did you find a non-free component or do you want to make libreCMC better? Submit an issue.
-
-* [Build Documentation](/docs/How_To_Build_libreCMC.md) : Learn how to build libreCMC for your device. 

+ 62 - 8
config/Config-build.in

@@ -9,15 +9,16 @@ menu "Global build settings"
 
 	config ALL_NONSHARED
 		bool "Select all target specific packages by default"
-		default ALL || BUILDBOT
+		select ALL_KMODS
+		default BUILDBOT
 
 	config ALL_KMODS
 		bool "Select all kernel module packages by default"
-		default ALL
 
 	config ALL
 		bool "Select all userspace packages by default"
-		default n
+		select ALL_KMODS
+		select ALL_NONSHARED
 
 	config BUILDBOT
 		bool "Set build defaults for automatic builds (e.g. via buildbot)"
@@ -33,14 +34,27 @@ menu "Global build settings"
 		bool "Cryptographically signed package lists"
 		default y
 
+	config SIGNATURE_CHECK
+		bool "Enable signature checking in opkg"
+		default SIGNED_PACKAGES
+
 	comment "General build options"
 
+	config TESTING_KERNEL
+		bool "Use the testing kernel version"
+		depends on HAS_TESTING_KERNEL
+		default n
+		help
+		  If the target supports a newer kernel version than the default,
+		  you can use this config option to enable it
+
+
 	config DISPLAY_SUPPORT
 		bool "Show packages that require graphics support (local or remote)"
 		default n
 
 	config BUILD_PATENTED
-		default y
+		default n
 		bool "Compile with support for patented functionality"
 		help
 		  When this option is disabled, software which provides patented functionality
@@ -52,7 +66,7 @@ menu "Global build settings"
 		bool "Compile with full language support"
 		help
 		  When this option is enabled, packages are built with the full versions of
-		  iconv and GNU gettext instead of the default OpenWrt stubs. If uClibc is
+		  iconv and GNU gettext instead of the default libreCMC stubs. If uClibc is
 		  used, it is also built with locale support.
 
 	config SHADOW_PASSWORDS
@@ -67,6 +81,20 @@ menu "Global build settings"
 		  This removes all ipkg/opkg status data files from the target directory
 		  before building the root filesystem.
 
+	config IPK_FILES_CHECKSUMS
+		bool
+		prompt "Record files checksums in package metadata"
+		default n
+		help
+		  This makes file checksums part of package metadata. It increases size
+		  but provides you with pkg_check command to check for flash coruptions.
+
+	config INCLUDE_CONFIG
+		bool "Include build configuration in firmware" if DEVEL
+		default n
+		help
+		  If enabled, config.buildinfo will be stored in /etc/build.config of firmware.
+
 	config COLLECT_KERNEL_DEBUG
 		bool
 		prompt "Collect kernel debug information"
@@ -77,10 +105,12 @@ menu "Global build settings"
 		  Useful for release builds, so that kernel issues can be debugged offline
 		  later.
 
-	comment "Kernel build options"
+	menu "Kernel build options"
 
 	source "config/Config-kernel.in"
 
+	endmenu
+
 	comment "Package build options"
 
 	config DEBUG
@@ -175,6 +205,22 @@ menu "Global build settings"
 		  this per package by adding PKG_CHECK_FORMAT_SECURITY:=0 in the package
 		  Makefile.
 
+	config PKG_ASLR_PIE
+		bool
+		prompt "User space ASLR PIE compilation"
+		select BUSYBOX_DEFAULT_PIE
+		default n
+		help
+		  Add -fPIC to CFLAGS and -specs=hardened-build-ld to LDFLAGS.
+		  This enables package build as Position Independent Executables (PIE)
+		  to protect against "return-to-text" attacks. This belongs to the
+		  feature of Address Space Layout Randomisation (ASLR), which is
+		  implemented by the kernel and the ELF loader by randomising the
+		  location of memory allocations. This makes memory addresses harder
+		  to predict when an attacker is attempting a memory-corruption exploit.
+		  You can disable this per package by adding PKG_ASLR_PIE:=0 in the package
+		  Makefile.
+
 	choice
 		prompt "User space Stack-Smashing Protection"
 		depends on USE_MUSL
@@ -185,11 +231,11 @@ menu "Global build settings"
 			bool "None"
 		config PKG_CC_STACKPROTECTOR_REGULAR
 			bool "Regular"
-			select SSP_SUPPORT if !USE_MUSL
+			select GCC_LIBSSP if !USE_MUSL
 			depends on KERNEL_CC_STACKPROTECTOR_REGULAR
 		config PKG_CC_STACKPROTECTOR_STRONG
 			bool "Strong"
-			select SSP_SUPPORT if !USE_MUSL
+			select GCC_LIBSSP if !USE_MUSL
 			depends on !GCC_VERSION_4_8
 			depends on KERNEL_CC_STACKPROTECTOR_STRONG
 	endchoice
@@ -209,6 +255,14 @@ menu "Global build settings"
 			bool "Strong"
 	endchoice
 
+	config  KERNEL_STACKPROTECTOR
+		bool
+		default KERNEL_CC_STACKPROTECTOR_REGULAR || KERNEL_CC_STACKPROTECTOR_STRONG
+
+	config  KERNEL_STACKPROTECTOR_STRONG
+		bool
+		default KERNEL_CC_STACKPROTECTOR_STRONG
+
 	choice
 		prompt "Enable buffer-overflows detection (FORTIFY_SOURCE)"
 		default PKG_FORTIFY_SOURCE_1

+ 14 - 5
config/Config-devel.in

@@ -27,7 +27,7 @@ menuconfig DEVEL
 		  If not set then defaults to './dl', which is removed by operations such as
 		  'git clean -xdf' or 'make distclean'.
 		  This option is useful if you have a low bandwidth Internet connection, and by
-		  setting a path outside the OpenWrt tree downloads will be saved.
+		  setting a path outside the libreCMC tree downloads will be saved.
 
 	config LOCALMIRROR
 		string "Local mirror for source packages" if DEVEL
@@ -39,6 +39,14 @@ menuconfig DEVEL
 		help
 		  Automatically rebuild packages when their files change.
 
+	config AUTOREMOVE
+		bool "Automatic removal of build directories" if DEVEL
+		default n
+		help
+		  Automatically delete build directories after make target completed.
+		  This allows you to symlink build_dir into a scratch location, e.g. a ramdisk,
+		  which does not have enough space to keep a complete build_dir.
+
 	config BUILD_SUFFIX
 		string "Build suffix to append to the target BUILD_DIR variable" if DEVEL
 		default ""
@@ -82,13 +90,14 @@ menuconfig DEVEL
 		  In this instance, the --reference option of git clone will
 		  be used thus creating a quick local clone of your repo.
 
-	config KERNEL_GIT_BRANCH
-		string "Enter git branch to clone" if DEVEL
+	config KERNEL_GIT_REF
+		string "Enter git ref at which to checkout" if DEVEL
 		depends on (KERNEL_GIT_CLONE_URI != "")
 		default ""
 		help
-		  Enter the branch name to checkout after cloning the git repository.
-		  In this instance, the --branch option of git clone will be used.
+		  Enter the git ref at which to checkout the git repository
+		  after it is cloned, and before making it a tar-ball.
+		  It can be a git hash or a branch name.
 		  If unused, the clone's repository HEAD will be checked-out.
 
 	config BUILD_LOG

+ 32 - 10
config/Config-images.in

@@ -14,9 +14,11 @@ menu "Target Images"
 
 		choice
 			prompt "Compression"
+			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_apm821xx
 			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ar71xx
+			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_lantiq
+			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_mpc85xx
 			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ramips
-			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_apm821xx
 			default TARGET_INITRAMFS_COMPRESSION_NONE
 			depends on TARGET_ROOTFS_INITRAMFS
 			help
@@ -51,6 +53,13 @@ menu "Target Images"
 			help
 			  Kernel uses specified external cpio as INITRAMFS_SOURCE.
 
+		config TARGET_INITRAMFS_FORCE
+                        bool "Force"
+                        depends on TARGET_ROOTFS_INITRAMFS
+                        default n
+                        help
+                          Ignore the initramfs passed by the bootloader.
+
 	comment "Root filesystem archives"
 
 	config TARGET_ROOTFS_CPIOGZ
@@ -141,6 +150,7 @@ menu "Target Images"
 			int "Block size (in KiB)"
 			depends on TARGET_ROOTFS_SQUASHFS
 			default 64 if LOW_MEMORY_FOOTPRINT
+			default 1024 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT)
 			default 256
 
 	menuconfig TARGET_ROOTFS_UBIFS
@@ -188,14 +198,12 @@ menu "Target Images"
 	config GRUB_CONSOLE
 		bool "Use Console Terminal (in addition to Serial)"
 		depends on GRUB_IMAGES
-		default n if (TARGET_x86_generic_Soekris45xx || TARGET_x86_generic_Soekris48xx || TARGET_x86_net5501 || TARGET_x86_geos || TARGET_x86_alix2)
 		default y
 
 	config GRUB_SERIAL
 		string "Serial port device"
 		depends on GRUB_IMAGES
-		default "hvc0" if TARGET_x86_xen_domu
-		default "ttyS0" if ! TARGET_x86_xen_domu
+		default "ttyS0"
 
 	config GRUB_BAUDRATE
 		int "Serial port baud rate"
@@ -203,10 +211,14 @@ menu "Target Images"
 		default 38400 if TARGET_x86_generic
 		default 115200
 
+	config GRUB_FLOWCONTROL
+		bool "Use RTE/CTS on serial console"
+		depends on GRUB_SERIAL != ""
+		default n
+
 	config GRUB_BOOTOPTS
 		string "Extra kernel boot options"
 		depends on GRUB_IMAGES
-		default "xencons=hvc" if TARGET_x86_xen_domu
 		help
 		  If you don't know, just leave it blank.
 
@@ -217,16 +229,24 @@ menu "Target Images"
 		help
 		  If you don't know, 5 seconds is a reasonable default.
 
+	config GRUB_TITLE
+		string "Title for the menu entry in GRUB"
+		depends on GRUB_IMAGES
+		default "libreCMC"
+		help
+		  This is the title of the GRUB menu entry.
+		  If unspecified, it defaults to libreCMC.
+
 	config VDI_IMAGES
 		bool "Build VirtualBox image files (VDI)"
-		depends on TARGET_x86 || TARGET_x86_64
+		depends on TARGET_x86
 		select GRUB_IMAGES
 		select TARGET_IMAGES_PAD
 		select PACKAGE_kmod-e1000
 
 	config VMDK_IMAGES
 		bool "Build VMware image files (VMDK)"
-		depends on TARGET_x86 || TARGET_x86_64
+		depends on TARGET_x86
 		select GRUB_IMAGES
 		select TARGET_IMAGES_PAD
 		select PACKAGE_kmod-e1000
@@ -237,7 +257,7 @@ menu "Target Images"
 
 	config TARGET_IMAGES_GZIP
 		bool "GZip images"
-		depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS
+		depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS || TARGET_x86
 		default y
 
 	comment "Image Options"
@@ -246,12 +266,14 @@ menu "Target Images"
 
 	config TARGET_KERNEL_PARTSIZE
 		int "Kernel partition size (in MB)"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || USES_BOOT_PART
+		default 8 if TARGET_apm821xx_sata
+		default 20 if TARGET_brcm2708
 		default 16
 
 	config TARGET_ROOTFS_PARTSIZE
 		int "Root filesystem partition size (in MB)"
-		depends on GRUB_IMAGES || TARGET_ROOTFS_EXT4FS || TARGET_rb532 || TARGET_mvebu || TARGET_uml
+		depends on GRUB_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_omap || TARGET_rb532 || TARGET_sunxi || TARGET_uml
 		default 256
 		help
 		  Select the root filesystem partition size.

+ 108 - 14
config/Config-kernel.in

@@ -6,6 +6,7 @@
 
 config KERNEL_BUILD_USER
 	string "Custom Kernel Build User Name"
+	default "builder" if BUILDBOT
 	default ""
 	help
 	  Sets the Kernel build user string, which for example will be returned
@@ -14,6 +15,7 @@ config KERNEL_BUILD_USER
 
 config KERNEL_BUILD_DOMAIN
 	string "Custom Kernel Build Domain Name"
+	default "buildhost" if BUILDBOT
 	default ""
 	help
 	  Sets the Kernel build domain string, which for example will be
@@ -31,7 +33,7 @@ config KERNEL_CRASHLOG
 
 config KERNEL_SWAP
 	bool "Support for paging of anonymous memory (swap)"
-	default y
+	default y if !SMALL_FLASH
 
 config KERNEL_DEBUG_FS
 	bool "Compile the kernel with debug filesystem enabled"
@@ -42,15 +44,20 @@ config KERNEL_DEBUG_FS
 	  write to these files. Many common debugging facilities, such as
 	  ftrace, require the existence of debugfs.
 
+config KERNEL_MIPS_FPU_EMULATOR
+	bool "Compile the kernel with MIPS FPU Emulator"
+	default y if TARGET_pistachio
+	depends on (mips || mipsel || mips64 || mips64el)
+
 config KERNEL_ARM_PMU
 	bool
 	default n
-	depends on (arm || arm64)
+	depends on (arm || aarch64)
 
 config KERNEL_PERF_EVENTS
-	bool
+	bool "Compile the kernel with performance events and counters"
 	default n
-	select KERNEL_ARM_PMU if (arm || arm64)
+	select KERNEL_ARM_PMU if (arm || aarch64)
 
 config KERNEL_PROFILING
 	bool "Compile the kernel with profiling enabled"
@@ -60,6 +67,27 @@ config KERNEL_PROFILING
 	  Enable the extended profiling support mechanisms used by profilers such
 	  as OProfile.
 
+config KERNEL_TASKSTATS
+	bool "Compile the kernel with task resource/io statistics and accounting"
+	default n
+	help
+	  Enable the collection and publishing of task/io statistics and
+	  accounting.  Enable this option to enable i/o monitoring in system
+	  monitors.
+
+if KERNEL_TASKSTATS
+
+	config KERNEL_TASK_DELAY_ACCT
+		def_bool y
+
+	config KERNEL_TASK_IO_ACCOUNTING
+		def_bool y
+
+	config KERNEL_TASK_XACCT
+		def_bool y
+
+endif
+
 config KERNEL_KALLSYMS
 	bool "Compile the kernel with symbol table information"
 	default y if !SMALL_FLASH
@@ -107,7 +135,7 @@ config KERNEL_DEBUG_KERNEL
 
 config KERNEL_DEBUG_INFO
 	bool "Compile the kernel with debug information"
-	default y
+	default y if !SMALL_FLASH
 	select KERNEL_DEBUG_KERNEL
 	help
 	  This will compile your kernel and modules with debug information.
@@ -166,14 +194,14 @@ config KERNEL_KPROBE_EVENT
 	bool
 	default y if KERNEL_KPROBES
 
+config KERNEL_KPROBE_EVENTS
+	bool
+	default y if KERNEL_KPROBES
+
 config KERNEL_AIO
 	bool "Compile the kernel with asynchronous IO support"
 	default n
 
-config KERNEL_DIRECT_IO
-	bool "Compile the kernel with direct IO support"
-	default n
-
 config KERNEL_FHANDLE
 	bool "Compile the kernel with support for fhandle syscalls"
 	default n
@@ -204,7 +232,7 @@ config KERNEL_COREDUMP
 config KERNEL_ELF_CORE
 	bool "Enable process core dump support"
 	select KERNEL_COREDUMP
-	default y
+	default y if !SMALL_FLASH
 
 config KERNEL_PROVE_LOCKING
 	bool "Enable kernel lock checking"
@@ -235,6 +263,16 @@ config KERNEL_RELAY
 config KERNEL_KEXEC
 	bool "Enable kexec support"
 
+config KERNEL_PROC_VMCORE
+	bool
+
+config KERNEL_CRASH_DUMP
+	depends on i386 || x86_64 || arm || armeb
+	select KERNEL_KEXEC
+	select KERNEL_PROC_VMCORE
+	bool "Enable support for kexec crashdump"
+	default y
+
 config USE_RFKILL
 	bool "Enable rfkill support"
 	default RFKILL_SUPPORT
@@ -248,7 +286,7 @@ config KERNEL_DEVTMPFS
 	default n
 	help
 	  devtmpfs is a simple, kernel-managed /dev filesystem. The kernel creates
-	  devices nodes for all registered devices ti simplify boot, but leaves more
+	  devices nodes for all registered devices to simplify boot, but leaves more
 	  complex tasks to userspace (e.g. udev).
 
 if KERNEL_DEVTMPFS
@@ -487,6 +525,20 @@ if KERNEL_CGROUPS
 		  CONFIG_CFQ_GROUP_IOSCHED=y; for enabling throttling policy, set
 		  CONFIG_BLK_DEV_THROTTLING=y.
 
+	if KERNEL_BLK_CGROUP
+
+		config KERNEL_CFQ_GROUP_IOSCHED
+			bool "Proportional weight of disk bandwidth in CFQ"
+
+		config KERNEL_BLK_DEV_THROTTLING
+			bool "Enable throttling policy"
+			default y if TARGET_brcm2708
+
+		config KERNEL_BLK_DEV_THROTTLING_LOW
+			bool "Block throttling .low limit interface support (EXPERIMENTAL)"
+			depends on KERNEL_BLK_DEV_THROTTLING
+	endif
+
 	config KERNEL_DEBUG_BLK_CGROUP
 		bool "Enable Block IO controller debugging"
 		default n
@@ -601,6 +653,17 @@ config KERNEL_SECCOMP
 		help
 		  Build kernel with support for seccomp.
 
+#
+# IPv4 configuration
+#
+
+config KERNEL_IP_MROUTE
+	bool "Enable IPv4 multicast routing"
+	default y
+	help
+	  Multicast routing requires a multicast routing daemon in
+	  addition to kernel support.
+
 #
 # IPv6 configuration
 #
@@ -617,7 +680,11 @@ if KERNEL_IPV6
 		def_bool y
 
 	config KERNEL_IPV6_MROUTE
-		def_bool y
+		bool "Enable IPv6 multicast routing"
+		default y
+		help
+		  Multicast routing requires a multicast routing daemon in
+		  addition to kernel support.
 
 	config KERNEL_IPV6_PIMSM_V2
 		def_bool n
@@ -666,7 +733,7 @@ menu "Filesystem ACL and attr support options"
 		  Make using ACLs (e.g. POSIX ACL, NFSv4 ACL) the default
 		  for kernel and packages, except tmpfs, flash filesystems,
 		  and old NFS.  Also enable userspace extended attribute support
-		  by default.  (OpenWrt already has an expection it will be
+		  by default.  (libreCMC already has an expection it will be
 		  present in the kernel).
 
 	config KERNEL_FS_POSIX_ACL
@@ -708,7 +775,7 @@ menu "Filesystem ACL and attr support options"
 		select KERNEL_FS_POSIX_ACL
 		default y if USE_FS_ACL_ATTR
 
-	config KERNEL_HFSPLUG_FS_POSIX_ACL
+	config KERNEL_HFSPLUS_FS_POSIX_ACL
 		bool "Enable POSIX ACL for HFS+ Filesystems"
 		select KERNEL_FS_POSIX_ACL
 		default y if USE_FS_ACL_ATTR
@@ -759,3 +826,30 @@ config KERNEL_DEVKMEM
 	  Say Y here if you want to support the /dev/kmem device. The
 	  /dev/kmem device is rarely used, but can be used for certain
 	  kind of kernel debugging operations.
+
+config KERNEL_SQUASHFS_FRAGMENT_CACHE_SIZE
+	int "Number of squashfs fragments cached"
+	default 2 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT)
+	default 3
+
+#
+# compile optimiziation setting
+#
+choice
+	prompt "Compiler optimization level"
+	default KERNEL_CC_OPTIMIZE_FOR_SIZE if SMALL_FLASH
+
+config KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE
+	bool "Optimize for performance"
+	help
+	  This is the default optimization level for the kernel, building
+	  with the "-O2" compiler flag for best performance and most
+	  helpful compile-time warnings.
+
+config KERNEL_CC_OPTIMIZE_FOR_SIZE
+	bool "Optimize for size"
+	help
+	  Enabling this option will pass "-Os" instead of "-O2" to
+	  your compiler resulting in a smaller kernel.
+
+endchoice

+ 84 - 0
docs/FAQ.md

@@ -0,0 +1,84 @@
+# The libreCMC FAQ
+
+## What is libreCMC?
+
+The libreCMC project provides replacement software for consumer-grade
+routers in the form of a small GNU/Linux distro. The software and tools
+that the project distributes allow users to take back control of
+their devices from hardware manufactures. Because libreCMC is [Free
+Software](http://www.gnu.org/philosophy/free-sw.en.html), users are
+able to unlock the ability to control and breath new life into
+devices the project supports.
+
+## Why should I care?
+
+In the light of recent events, it is more important now more than ever to fight
+for the freedom to control the software that runs on a given device. Users
+should have the freedom to control their devices, not the OEMs who originally
+made the device. Since libreCMC is free software, users have total control over
+what the software on their device is doing. This is important because it means
+that the community can add new features, review what the software is doing and
+make improvements that benefit the community as a whole.
+
+## What devices does libreCMC work with?
+
+The libreCMC project supports mostly consumer-grade routers and a few other
+embedded devices.  This list can be found on the Supported Hardware page. While
+this list is not extensive, the libreCMC project has very strict requirements
+for supporting devices. Some examples include:
+
+* libreCMC has to be installable from stock firmware. In most cases, devices
+have a complicated process or use of additional tools to replace the firmware /
+software. The project will still consider some level of support if it does not
+meet this requirement and meets all of the other requirements.
+
+* The hardware can't require non-free software or binary blobs to work. Non-free
+Software / Blobs are pieces of software where we (the community) do not have
+the source code under a proper Free Software [1] license. Non-free Software and
+blobs make supporting a device for any length of time a chore and usually
+support evaporates when device vendors stop releasing new blobs / components.
+If a device requires non-free software or blobs, the libreCMC project won't
+support devices that can't meet this requirement.
+
+* The device needs to have enough flash (storage) to work with. Sadly,
+the issue of bloat in modern times is seen as a non-issue for many
+software developers. While there are a lot of hardware that the
+project would like to support, there are some devices that just simply
+don't have enough flash. One of the long-term goals of the project is
+to eventually support devices with limited flash. Right now, the
+minimum requirement for libreCMC supported devices is 4M of flash,
+depending on the features that are desired.
+
+## Features
+
+The libreCMC project's main focus is on consumer-grade routers and a
+few other embedded devices. While libreCMC is based upon OpenWrt, the
+project does not support all of the same features and tries to strike
+a balance between functionality and bloat. The project *does not*
+support the following:
+
+* UPnP support: UPnP is a security nightmare and the project won't support it.
+
+* Services / Applications that belong on their own machine or can't
+run on 90% of targets : While it might be cool to run a particular
+service or application on your router, it is usually is a bad
+idea. Many of the devices that we support are not capable of running
+such things because of a lack of processing power, flash or RAM.
+
+## How often are releases made?
+
+libreCMC releases incremental every 3 - 6 months, depending on if
+there is a critical security or design flaw. The project tries to
+maintain major or LTS (long Term Support) releases for about 2 years.
+
+## How can I get started with libreCMC?
+
+[Getting Started]() Page : WIP?
+
+## How can I contribute to libreCMC?
+
+Pull requests can be made or issues can be filed against the project's
+[git](https://gogs.librecmc.org/libreCMC/libreCMC) repository.
+
+Information about monetary contributions can be found on the project's
+[contact](https://librecmc.org/contact.html) page.

+ 2 - 0
docs/GL-AR300M.md

@@ -33,6 +33,8 @@
 
 ## Notes:
 
+* This router is currently not officially supported by Librecmc
+
 * This router is dual flash and stock uboot attempts to boot nand flash first.
 
 * NOR flash uses .bin image and NAND flash uses .img image.

+ 0 - 1
docs/List_of_Tested_Hardware.md

@@ -11,7 +11,6 @@
 | TP-Link TL-WR842ND v2.0  |  zeus |  No |
 | TP-Link TL-WR1043ND v1.8| orly_owl | ??? |
 | TP-Link TL-WR1043ND v2.1| RISCi_ATOM | ??? |
-| TP-Link TL-WR1043N v5  | RISCi_ATOM | ??? |
 | D-Link DGL-5500 vA1 rm' wifi card| RISCi_ATOM | ??? |
 | Western Digital MyNet N750 | orly_owl | ??? |
 

+ 27 - 15
docs/README.md

@@ -1,15 +1,27 @@
-# libreCMC : The _libre_ Embedded GNU/Linux Distro.
-
-libreCMC is a set of fully [free](http://www.gnu.org/philosophy/free-sw.en.html) embedded Operating Systems for general purpose computers. It aims to give its users freedom and control over the software that runs on their hardware. Most of the hardware that libreCMC supports includes a wide range of routers and some small single board computers.
-
-## Useful links:
-
-* [Get libreCMC source code](https://gogs.librecmc.org/libreCMC/libreCMC) : Checkout the latest libreCMC sources.
-
-* [Supported Hardware](Supported_Hardware.md): Devices officially supported by libreCMC.
-
-* [Router reset instructions](Router_Reset_Instructions.md) : Generic libreCMC router reset instructions.
-
-* [Report a bug or issue](https://gogs.librecmc.org/libreCMC/libreCMC/issues) : Is something broken? Did you find a non-free component or do you want to make libreCMC better? Submit an issue.
-
-* [Build Documentation](How_To_Build_libreCMC.md) : Learn how to build libreCMC for your device. 
+# libreCMC : The _libre_ Embedded GNU/Linux Distro.
+
+The libreCMC project provides replacement software for consumer-grade
+routers in the form of a small GNU/Linux distro. The software and tools
+that the project distributes allow users to take back control of
+their devices from hardware manufactures. Because libreCMC is [Free
+Software](http://www.gnu.org/philosophy/free-sw.en.html), users are
+able to unlock the ability to control and breath new life into
+devices the project supports.
+
+## Useful links:
+
+* [libreCMC FAQ](FAQ.md) : WIP
+
+* [Getting Started with libreCMC]() : WIP
+
+* [Supported Hardware](Supported_Hardware.md): Devices officially supported by libreCMC.
+
+* [Router reset instructions](Router_Reset_Instructions.md) : Generic libreCMC router reset instructions.
+
+* [Report a bug or issue](https://gogs.librecmc.org/libreCMC/libreCMC/issues) : Is
+  something broken? Did you find a non-free component or do you want
+  to make libreCMC better? Submit an issue.
+
+* [Get libreCMC source code](https://gogs.librecmc.org/libreCMC/libreCMC) : Checkout the latest libreCMC sources.
+
+* [Build Documentation](How_To_Build_libreCMC.md) : Learn how to build libreCMC for your device. 

+ 6 - 12
docs/Supported_Hardware.md

@@ -1,17 +1,13 @@
 # libreCMC supported Hardware
 
-Officially supported devices generally fall into one of three categories : can
-easily be flashed from the stock firmware's web-ui, requires the usage of a tFTP
-server or the device must be opened. When choosing a router to use with libreCMC,
-please keep in mind the method which is required for the initial install of
-libreCMC. Unless otherwise noted, the listed devices fall into the first
-category [1].
+Officially supported devices generally fall into three categories : can easily
+be flashed from the stock firmware's web-ui, requires a tFTP flash or opening up
+the router. When choosing a router to use with libreCMC, please keep in mind the
+method which is required for the initial install of libreCMC.
 
 ### Buffalo
-
 * [WZR-HP-G300NH](/WZR_HP_G300NH.md)
 * WHR-HP-G300NH
-* WZR-600DHP [2]
 
 ### Netgear 
 
@@ -47,8 +43,6 @@ category [1].
 
 ## Notes:
 
-[1] Firmware can be flashed from the stock firmware's web-ui.
-
-[2] Requires a tFTP server for initial flashing.
+[2] requires a tFTP server for flashing.
 
-[3] Requires opening up the hardware and the usage of a few tools (SPI Flasher, serial cable or both).
+[3] requires opening up the router / external hardware for initial install (serial cable, SPI flasher or both).

+ 10 - 7
docs/TL_WR1043ND.md

@@ -36,10 +36,8 @@ v5.x (TL-WR1043N v5)
 Similar to v4.x
 
 * No USB
-* libreCMC v1.4.7+
-* Must be TFTP flashed for first install.
-* tftp file name (factory image) : WR1043v5_tp_recovery.bin
-* tftp server IP : 192.168.0.66
+* libreCMC images available but have *Not* been tested!
+* Most likely needs to be TFTP flashed
 
 ## Supported Versions:
 
@@ -47,7 +45,7 @@ Similar to v4.x
 * v2.x
 * v3.x
 * v4.x
-* v5.x : v1.4.7+ / v1.5
+* v5.x : images available, *Not Tested*
 
 # Reset instructions
 
@@ -79,9 +77,9 @@ See our [flavors](https://librecmc.org/flavors.html) page for a description of e
 [TL-WR1043ND v4 Sysupgrade](https://librecmc.org/librecmc/downloads/snapshots/current/main/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043nd-v4-squashfs-sysupgrade.bin)
 
 
-Beta images: [TL-WR1043N v5 Factory](https://librecmc.org/librecmc/downloads/snapshots/archive/v1.4.6-20190220/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043n-v5-squashfs-factory.bin)
+[TL-WR1043N v5 Factory](https://librecmc.org/librecmc/downloads/snapshots/current/main/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043n-v5-squashfs-factory.bin) *NOT TESTED!!
 
-Beta images: [TL-WR1043N v5 Sysupgrade](https://librecmc.org/librecmc/downloads/snapshots/archive/v1.4.6-20190220/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043n-v5-squashfs-sysupgrade.bin)
+[TL-WR1043N v5 Sysupgrade](https://librecmc.org/librecmc/downloads/snapshots/current/main/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043n-v5-squashfs-sysupgrade.bin) *NOT TESTED!!
 
 ## Core Images
 
@@ -105,6 +103,10 @@ Beta images: [TL-WR1043N v5 Sysupgrade](https://librecmc.org/librecmc/downloads/
 [TL-WR1043ND v4 Sysupgrade](https://librecmc.org/librecmc/downloads/snapshots/current/core/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043nd-v4-squashfs-sysupgrade.bin)
 
 
+[TL-WR1043N v5 Factory](https://librecmc.org/librecmc/downloads/snapshots/current/core/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043n-v5-squashfs-factory.bin) *NOT TESTED!!
+
+[TL-WR1043N v5 Sysupgrade](https://librecmc.org/librecmc/downloads/snapshots/current/core/ar71xx/generic/librecmc-ar71xx-generic-tl-wr1043n-v5-squashfs-sysupgrade.bin) *NOT TESTED!!
+
 ## Image File Signatures 
 
 [Main sha256sums](https://librecmc.org/librecmc/downloads/snapshots/current/main/ar71xx/generic/sha256sums)
@@ -115,3 +117,4 @@ Beta images: [TL-WR1043N v5 Sysupgrade](https://librecmc.org/librecmc/downloads/
 [Core sha256sums](https://librecmc.org/librecmc/downloads/snapshots/current/core/ar71xx/generic/sha256sums)
 
 [Core sha256sums.asc](https://librecmc.org/librecmc/downloads/snapshots/current/core/ar71xx/generic/sha256sums.asc)
+

+ 1 - 1
feeds.conf.default

@@ -1 +1 @@
-src-git packages https://gogs.librecmc.org/libreCMC/package-feed.git;LTS
+src-git packages https://gogs.librecmc.org/librecmc/package-feed.git;v1.5

+ 6 - 4
include/autotools.mk

@@ -39,7 +39,9 @@ define autoreconf
 				[ -e $(p)/config.rpath ] || \
 						ln -s $(SCRIPT_DIR)/config.rpath $(p)/config.rpath; \
 				touch NEWS AUTHORS COPYING ABOUT-NLS ChangeLog; \
-				$(AM_TOOL_PATHS) $(STAGING_DIR_HOST)/bin/autoreconf -v -f -i -s \
+				$(AM_TOOL_PATHS) \
+					LIBTOOLIZE='$(STAGING_DIR_HOST)/bin/libtoolize --install' \
+					$(STAGING_DIR_HOST)/bin/autoreconf -v -f -i -s \
 					$(if $(word 2,$(3)),--no-recursive) \
 					-B $(STAGING_DIR_HOST)/share/aclocal \
 					$(patsubst %,-I %,$(5)) \
@@ -75,7 +77,7 @@ define autoreconf_target
   $(strip $(call autoreconf, \
     $(PKG_BUILD_DIR), $(PKG_REMOVE_FILES), \
     $(PKG_AUTOMAKE_PATHS), $(PKG_LIBTOOL_PATHS), \
-    $(STAGING_DIR)/host/share/aclocal $(STAGING_DIR)/usr/share/aclocal $(PKG_MACRO_PATHS)))
+    $(STAGING_DIR)/host/share/aclocal $(STAGING_DIR_HOSTPKG)/share/aclocal $(STAGING_DIR)/usr/share/aclocal $(PKG_MACRO_PATHS)))
 endef
 
 define patch_libtool_target
@@ -105,14 +107,14 @@ ifneq ($(filter patch-libtool,$(PKG_FIXUP)),)
 endif
 
 ifneq ($(filter libtool,$(PKG_FIXUP)),)
-  PKG_BUILD_DEPENDS += libtool libintl libiconv
+  PKG_BUILD_DEPENDS += libtool gettext libiconv
  ifeq ($(filter no-autoreconf,$(PKG_FIXUP)),)
   Hooks/Configure/Pre += autoreconf_target
  endif
 endif
 
 ifneq ($(filter libtool-ucxx,$(PKG_FIXUP)),)
-  PKG_BUILD_DEPENDS += libtool libintl libiconv
+  PKG_BUILD_DEPENDS += libtool gettext libiconv
  ifeq ($(filter no-autoreconf,$(PKG_FIXUP)),)
   Hooks/Configure/Pre += autoreconf_target
  endif

+ 5 - 4
include/cmake.mk

@@ -2,13 +2,13 @@ cmake_bool = $(patsubst %,-D%:BOOL=$(if $($(1)),ON,OFF),$(2))
 
 PKG_INSTALL:=1
 
-ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
+ifneq ($(findstring c,$(LIBRECMC_VERBOSE)),)
   MAKE_FLAGS+=VERBOSE=1
 endif
 
 CMAKE_BINARY_DIR = $(PKG_BUILD_DIR)$(if $(CMAKE_BINARY_SUBDIR),/$(CMAKE_BINARY_SUBDIR))
-CMAKE_SOURCE_DIR = $(PKG_BUILD_DIR)
-HOST_CMAKE_SOURCE_DIR = $(HOST_BUILD_DIR)
+CMAKE_SOURCE_DIR = $(PKG_BUILD_DIR)$(if $(CMAKE_SOURCE_SUBDIR),/$(CMAKE_SOURCE_SUBDIR))
+HOST_CMAKE_SOURCE_DIR = $(HOST_BUILD_DIR)$(if $(CMAKE_SOURCE_SUBDIR),/$(CMAKE_SOURCE_SUBDIR))
 MAKE_PATH = $(firstword $(CMAKE_BINARY_SUBDIR) .)
 
 ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
@@ -34,7 +34,7 @@ CMAKE_NM:=$(call cmake_tool,$(TARGET_NM))
 CMAKE_RANLIB:=$(call cmake_tool,$(TARGET_RANLIB))
 
 CMAKE_FIND_ROOT_PATH:=$(STAGING_DIR)/usr;$(TOOLCHAIN_DIR)$(if $(CONFIG_EXTERNAL_TOOLCHAIN),;$(CONFIG_TOOLCHAIN_ROOT))
-CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOST)
+CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOSTPKG);$(STAGING_DIR_HOST)
 CMAKE_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions
 
 define Build/Configure/Default
@@ -103,6 +103,7 @@ define Host/Configure/Default
 			-DCMAKE_INSTALL_PREFIX=$(HOST_BUILD_PREFIX) \
 			-DCMAKE_PREFIX_PATH=$(HOST_BUILD_PREFIX) \
 			-DCMAKE_SKIP_RPATH=TRUE  \
+			-DCMAKE_INSTALL_LIBDIR=lib \
 			$(CMAKE_HOST_OPTIONS) \
 		$(HOST_CMAKE_SOURCE_DIR) \
 	)

+ 7 - 1
include/depends.mk

@@ -11,7 +11,7 @@
 #	3: tempfile for file listings
 #	4: find options
 
-DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp"
+DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp" -x "*/.pkgdir*"
 
 find_md5=find $(wildcard $(1)) -type f $(patsubst -x,-and -not -path,$(DEP_FINDPARAMS) $(2)) | mkhash md5
 
@@ -20,6 +20,7 @@ define rdep
   .SILENT: $(2)_check
 
   $(2): $(2)_check
+  check-depends: $(2)_check
 
 ifneq ($(wildcard $(2)),)
   $(2)_check::
@@ -46,3 +47,8 @@ endif
 
 endef
 
+ifeq ($(filter .%,$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),$(MAKECMDGOALS),x))
+  define rdep
+    $(2): $(2)_check
+  endef
+endif

+ 1 - 1
include/device_table.txt

@@ -1,4 +1,4 @@
-# minimal device table file for OpenWrt
+# minimal device table file for libreCMC
 
 #<name>		<type>	<mode>	<uid>	<gid>	<major>	<minor>	<start>	<inc>	<count>
 /dev		d	755	0	0	-	-	-	-	-

+ 64 - 25
include/download.mk

@@ -7,7 +7,8 @@
 #
 
 PROJECT_GIT = https://gogs.librecmc.org/OWEALs
-OPENWRT_GIT = $(PROJECT_GIT)
+
+LIBRECMC_GIT = $(PROJECT_GIT)
 LEDE_GIT = $(PROJECT_GIT)
 
 ifdef PKG_SOURCE_VERSION
@@ -18,17 +19,23 @@ endif
 
 DOWNLOAD_RDEP=$(STAMP_PREPARED) $(HOST_STAMP_PREPARED)
 
+define dl_method_git
+$(if $(filter https://github.com/% git://github.com/%,$(1)),github_archive,git)
+endef
+
 # Try to guess the download method from the URL
 define dl_method
 $(strip \
-  $(if $(2),$(2), \
-    $(if $(filter @APACHE/% @GNOME/% @GNU/% @KERNEL_LIBRE/% @KERNEL/% @SF/% @SAVANNAH/% ftp://% http://% https://% file://%,$(1)),default, \
-      $(if $(filter git://%,$(1)),git, \
-        $(if $(filter svn://%,$(1)),svn, \
-          $(if $(filter cvs://%,$(1)),cvs, \
-            $(if $(filter hg://%,$(1)),hg, \
-              $(if $(filter sftp://%,$(1)),bzr, \
-                unknown \
+  $(if $(filter git,$(2)),$(call dl_method_git,$(1),$(2)),
+    $(if $(2),$(2), \
+      $(if $(filter @APACHE/% @GITHUB/% @GNOME/% @GNU/% @KERNEL_LIBRE/% @KERNEL/% @SF/% @SAVANNAH/% ftp://% http://% https://% file://%,$(1)),default, \
+        $(if $(filter git://%,$(1)),$(call dl_method_git,$(1),$(2)), \
+          $(if $(filter svn://%,$(1)),svn, \
+            $(if $(filter cvs://%,$(1)),cvs, \
+              $(if $(filter hg://%,$(1)),hg, \
+                $(if $(filter sftp://%,$(1)),bzr, \
+                  unknown \
+                ) \
               ) \
             ) \
           ) \
@@ -48,13 +55,18 @@ define dl_pack
 	$(if $(dl_pack/$(call ext,$(1))),$(dl_pack/$(call ext,$(1))),$(dl_pack/unknown))
 endef
 define dl_tar_pack
-	$(TAR) --numeric-owner --owner=0 --group=0 --sort=name $$$${TAR_TIMESTAMP:+--mtime="$$$$TAR_TIMESTAMP"} -c $(2) | $(call dl_pack,$(1))
+	$(TAR) --numeric-owner --owner=0 --group=0 --mode=a-s --sort=name \
+		$$$${TAR_TIMESTAMP:+--mtime="$$$$TAR_TIMESTAMP"} -c $(2) | $(call dl_pack,$(1))
 endef
 
 ifdef CHECK
 check_escape=$(subst ','\'',$(1))
 #')
 
+# $(1): suffix of the F_, C_ variables, e.g. hash_deprecated, hash_mismatch, etc.
+# $(2): filename
+# $(3): expected hash value
+# $(4): var name of the the form: {PKG_,Download/<name>:}{,MIRROR_}{HASH,MIRROR_HASH}
 check_warn_nofix = $(info $(shell printf "$(_R)WARNING: %s$(_N)" '$(call check_escape,$(call C_$(1),$(2),$(3),$(4)))'))
 ifndef FIXUP
   check_warn = $(check_warn_nofix)
@@ -70,11 +82,17 @@ F_hash_mismatch = $(F_hash_deprecated)
 F_hash_missing = $(SCRIPT_DIR)/fixup-makefile.pl $(CURDIR)/Makefile add-hash $(3) $(call gen_sha256sum,$(1))
 endif
 
+# $(1): filename
+# $(2): expected hash value
+# $(3): var name of the the form: {PKG_,Download/<name>:}{,MIRROR_}{HASH,MIRROR_HASH}
 C_download_missing = $(1) is missing, please run make download before re-running this check
 C_hash_mismatch = $(3) does not match $(1) hash $(call gen_sha256sum,$(1))
 C_hash_deprecated = $(3) uses deprecated hash, set to $(call gen_sha256sum,$(1))
 C_hash_missing = $(3) is missing, set to $(call gen_sha256sum,$(1))
 
+# $(1): filename
+# $(2): expected hash value
+# $(3): var name of the the form: {PKG_,Download/<name>:}{,MIRROR_}{HASH,MIRROR_HASH}
 check_hash = \
   $(if $(wildcard $(DL_DIR)/$(1)), \
     $(if $(filter-out x,$(2)), \
@@ -104,7 +122,7 @@ hash_var = $(if $(filter-out x,$(1)),MD5SUM,HASH)
 endif
 
 define DownloadMethod/unknown
-	@echo "ERROR: No download method available"; false
+	echo "ERROR: No download method available"; false
 endef
 
 define DownloadMethod/default
@@ -115,6 +133,9 @@ define DownloadMethod/default
 	)
 endef
 
+# $(1): "check"
+# $(2): "PKG_" if <name> as in Download/<name> is "default", otherwise "Download/<name>:"
+# $(3): shell command sequence to do the download
 define wrap_mirror
 $(if $(if $(MIRROR),$(filter-out x,$(MIRROR_HASH))),$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(FILE)" "$(MIRROR_HASH)" "" || ( $(3) ),$(3)) \
 $(if $(filter check,$(1)), \
@@ -158,23 +179,41 @@ endef
 
 define DownloadMethod/git
 	$(call wrap_mirror,$(1),$(2), \
-		echo "Checking out files from the git repository..."; \
-		mkdir -p $(TMP_DIR)/dl && \
-		cd $(TMP_DIR)/dl && \
-		rm -rf $(SUBDIR) && \
-		[ \! -d $(SUBDIR) ] && \
-		git clone $(OPTS) $(URL) $(SUBDIR) && \
-		(cd $(SUBDIR) && git checkout $(VERSION) && \
-		git submodule update --init --recursive) && \
-		echo "Packing checkout..." && \
-		export TAR_TIMESTAMP=`cd $(SUBDIR) && git log -1 --format='@%ct'` && \
-		rm -rf $(SUBDIR)/.git && \
-		$(call dl_tar_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
-		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
-		rm -rf $(SUBDIR); \
+		$(call DownloadMethod/rawgit) \
+	)
+endef
+
+define DownloadMethod/github_archive
+	$(call wrap_mirror,$(1),$(2), \
+		$(SCRIPT_DIR)/dl_github_archive.py \
+			--dl-dir="$(DL_DIR)" \
+			--url="$(URL)" \
+			--version="$(VERSION)" \
+			--subdir="$(SUBDIR)" \
+			--source="$(FILE)" \
+			--hash="$(MIRROR_HASH)" \
+		|| ( $(call DownloadMethod/rawgit) ); \
 	)
 endef
 
+# Only intends to be called as a submethod from other DownloadMethod
+define DownloadMethod/rawgit
+	echo "Checking out files from the git repository..."; \
+	mkdir -p $(TMP_DIR)/dl && \
+	cd $(TMP_DIR)/dl && \
+	rm -rf $(SUBDIR) && \
+	[ \! -d $(SUBDIR) ] && \
+	git clone $(OPTS) $(URL) $(SUBDIR) && \
+	(cd $(SUBDIR) && git checkout $(VERSION) && \
+	git submodule update --init --recursive) && \
+	echo "Packing checkout..." && \
+	export TAR_TIMESTAMP=`cd $(SUBDIR) && git log -1 --format='@%ct'` && \
+	rm -rf $(SUBDIR)/.git && \
+	$(call dl_tar_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+	mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+	rm -rf $(SUBDIR);
+endef
+
 define DownloadMethod/bzr
 	$(call wrap_mirror,$(1),$(2), \
 		echo "Checking out files from the bzr repository..."; \

+ 13 - 21
include/feeds.mk

@@ -6,35 +6,21 @@
 # See /LICENSE for more information.
 #
 
--include $(TMP_DIR)/.packagesubdirs
+-include $(TMP_DIR)/.packageauxvars
 
 FEEDS_INSTALLED:=$(notdir $(wildcard $(TOPDIR)/package/feeds/*))
-FEEDS_AVAILABLE:=$(sort $(FEEDS_INSTALLED) $(shell $(SCRIPT_DIR)/feeds list -n))
-FEEDS_ENABLED:=$(foreach feed,$(FEEDS_AVAILABLE),$(if $(CONFIG_FEED_$(feed)),$(feed)))
-FEEDS_DISABLED:=$(filter-out $(FEEDS_ENABLED),$(FEEDS_AVAILABLE))
+FEEDS_AVAILABLE:=$(sort $(FEEDS_INSTALLED) $(shell $(SCRIPT_DIR)/feeds list -n 2>/dev/null))
 
 PACKAGE_SUBDIRS=$(PACKAGE_DIR)
 ifneq ($(CONFIG_PER_FEED_REPO),)
   PACKAGE_SUBDIRS += $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/base
-  ifneq ($(CONFIG_PER_FEED_REPO_ADD_DISABLED),)
-    PACKAGE_SUBDIRS += $(foreach FEED,$(FEEDS_AVAILABLE),$(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/$(FEED))
-  else
-    PACKAGE_SUBDIRS += $(foreach FEED,$(FEEDS_ENABLED),$(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/$(FEED))
-  endif
+  PACKAGE_SUBDIRS += $(foreach FEED,$(FEEDS_AVAILABLE),$(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/$(FEED))
 endif
 
-PACKAGE_DIR_ALL := $(TOPDIR)/staging_dir/packages/$(BOARD)
-
 opkg_package_files = $(wildcard \
 	$(foreach dir,$(PACKAGE_SUBDIRS), \
 	  $(foreach pkg,$(1), $(dir)/$(pkg)_*.ipk)))
 
-PKG_CONFIG_DEPENDS += \
-	CONFIG_PER_FEED_REPO \
-	CONFIG_PER_FEED_REPO_ADD_DISABLED \
-	CONFIG_PER_FEED_REPO_ADD_COMMENTED \
-	$(foreach feed,$(FEEDS_INSTALLED),CONFIG_FEED_$(feed))
-
 # 1: package name
 define FeedPackageDir
 $(strip $(if $(CONFIG_PER_FEED_REPO), \
@@ -47,10 +33,16 @@ endef
 # 1: destination file
 define FeedSourcesAppend
 ( \
-  echo "src/gz %n_core %U/%S/packages"; \
+  echo 'src/gz %d_core %U/targets/%S/packages'; \
   $(strip $(if $(CONFIG_PER_FEED_REPO), \
-	$(foreach feed,base $(FEEDS_ENABLED),echo "src/gz %n_$(feed) %U/packages/%A/$(feed)";) \
-	$(if $(CONFIG_PER_FEED_REPO_ADD_DISABLED), \
-		$(foreach feed,$(FEEDS_DISABLED),echo "$(if $(CONFIG_PER_FEED_REPO_ADD_COMMENTED),# )src/gz %n_$(feed) %U/packages/%A/$(feed)";)))) \
+	echo 'src/gz %d_base %U/packages/%A/base'; \
+	$(foreach feed,$(FEEDS_AVAILABLE), \
+		$(if $(CONFIG_FEED_$(feed)), \
+			echo '$(if $(filter m,$(CONFIG_FEED_$(feed))),# )src/gz %d_$(feed) %U/packages/%A/$(feed)';)))) \
 ) >> $(1)
 endef
+
+# 1: package name
+define GetABISuffix
+$(if $(filter-out kmod-%,$(1)),$(if $(Package/$(1)/abiversion),$(if $(filter %0 %1 %2 %3 %4 %5 %6 %7 %8 %9,$(1)),-)$(Package/$(1)/abiversion)))
+endef

+ 2 - 0
include/hardened-ld-pie.specs

@@ -0,0 +1,2 @@
+*self_spec:
++ %{no-pie|static|r|shared:;:-pie}

+ 7 - 0
include/hardening.mk

@@ -6,6 +6,7 @@
 #
 
 PKG_CHECK_FORMAT_SECURITY ?= 1
+PKG_ASLR_PIE ?= 1
 PKG_SSP ?= 1
 PKG_FORTIFY_SOURCE ?= 1
 PKG_RELRO ?= 1
@@ -15,6 +16,12 @@ ifdef CONFIG_PKG_CHECK_FORMAT_SECURITY
     TARGET_CFLAGS += -Wformat -Werror=format-security
   endif
 endif
+ifdef CONFIG_PKG_ASLR_PIE
+  ifeq ($(strip $(PKG_ASLR_PIE)),1)
+    TARGET_CFLAGS += $(FPIC)
+    TARGET_LDFLAGS += $(FPIC) -specs=$(INCLUDE_DIR)/hardened-ld-pie.specs
+  endif
+endif
 ifdef CONFIG_PKG_CC_STACKPROTECTOR_REGULAR
   ifeq ($(strip $(PKG_SSP)),1)
     TARGET_CFLAGS += -fstack-protector

+ 30 - 26
include/host-build.mk

@@ -19,22 +19,23 @@ else
 HOST_JOBS?=$(if $(HOST_BUILD_PARALLEL),$(HOST_MAKE_J),-j1)
 endif
 
-include $(INCLUDE_DIR)/host.mk
 include $(INCLUDE_DIR)/unpack.mk
 include $(INCLUDE_DIR)/depends.mk
+include $(INCLUDE_DIR)/quilt.mk
 
 BUILD_TYPES += host
-HOST_STAMP_PREPARED=$(HOST_BUILD_DIR)/.prepared$(if $(HOST_QUILT)$(DUMP),,$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),)))
+HOST_STAMP_PREPARED=$(HOST_BUILD_DIR)/.prepared$(if $(HOST_QUILT)$(DUMP),,$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))_$(call confvar,CONFIG_AUTOREMOVE $(HOST_PREPARED_DEPENDS)))
 HOST_STAMP_CONFIGURED:=$(HOST_BUILD_DIR)/.configured
 HOST_STAMP_BUILT:=$(HOST_BUILD_DIR)/.built
-HOST_BUILD_PREFIX:=$(if $(IS_PACKAGE_BUILD),$(STAGING_DIR_HOSTPKG),$(STAGING_DIR_HOST))
+HOST_BUILD_PREFIX?=$(if $(IS_PACKAGE_BUILD),$(STAGING_DIR_HOSTPKG),$(STAGING_DIR_HOST))
 HOST_STAMP_INSTALLED:=$(HOST_BUILD_PREFIX)/stamp/.$(PKG_NAME)_installed
 
 override MAKEFLAGS=
 
-include $(INCLUDE_DIR)/quilt.mk
 include $(INCLUDE_DIR)/autotools.mk
 
+_host_target:=$(if $(HOST_QUILT),,.)
+
 Host/Patch:=$(Host/Patch/Default)
 ifneq ($(strip $(HOST_UNPACK)),)
   define Host/Prepare/Default
@@ -51,6 +52,7 @@ endef
 HOST_CONFIGURE_VARS = \
 	CC="$(HOSTCC)" \
 	CFLAGS="$(HOST_CFLAGS)" \
+	CXX="$(HOSTCXX)" \
 	CPPFLAGS="$(HOST_CPPFLAGS)" \
 	LDFLAGS="$(HOST_LDFLAGS)" \
 	CONFIG_SHELL="$(SHELL)"
@@ -110,7 +112,7 @@ define Host/Compile
 endef
 
 define Host/Install/Default
-	$(_SINGLE)$(MAKE) -C $(HOST_BUILD_DIR) install
+	$(call Host/Compile/Default,install)
 endef
 
 define Host/Install
@@ -126,11 +128,11 @@ ifneq ($(if $(HOST_QUILT),,$(CONFIG_AUTOREBUILD)),)
 endif
 
 define Host/Exports/Default
-  $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR_HOST)/share/aclocal $$(STAGING_DIR_HOST)/share/aclocal-* $(if $(IS_PACKAGE_BUILD),$$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*)),-I $$(p))
+  $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR_HOST)/share/aclocal $$(STAGING_DIR_HOST)/share/aclocal-* $(if $(IS_PACKAGE_BUILD),$$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR_HOSTPKG)/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*)),-I $$(p))
   $(1) : export STAGING_PREFIX=$$(HOST_BUILD_PREFIX)
   $(1) : export PKG_CONFIG_PATH=$$(STAGING_DIR_HOST)/lib/pkgconfig:$$(HOST_BUILD_PREFIX)/lib/pkgconfig
   $(1) : export PKG_CONFIG_LIBDIR=$$(HOST_BUILD_PREFIX)/lib/pkgconfig
-  $(1) : export CCACHE_DIR:=$(STAGING_DIR_HOST)/ccache
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(STAGING_DIR_HOST)/ccache)
   $(if $(HOST_CONFIG_SITE),$(1) : export CONFIG_SITE:=$(HOST_CONFIG_SITE))
   $(if $(IS_PACKAGE_BUILD),$(1) : export PATH=$$(TARGET_PATH_PKG))
 endef
@@ -173,32 +175,34 @@ ifndef DUMP
 		touch $(HOST_STAMP_BUILT)
 		touch $$@
 
+  $(call DefaultTargets,$(patsubst %,host-%,$(DEFAULT_SUBDIR_TARGETS)))
   ifndef STAMP_BUILT
-    prepare: host-prepare
-    compile: host-compile
-    install: host-install
-    clean: host-clean
-    update: host-update
-    refresh: host-refresh
+    $(foreach t,$(DEFAULT_SUBDIR_TARGETS),
+      $(t): host-$(t)
+      .$(t): .host-$(t)
+    )
+    clean-build: host-clean-build
   endif
 
-  host-prepare: $(HOST_STAMP_PREPARED)
-  host-configure: $(HOST_STAMP_CONFIGURED)
-  host-compile: $(HOST_STAMP_BUILT) $(if $(STAMP_BUILT),$(HOST_STAMP_INSTALLED))
-  host-install: $(HOST_STAMP_INSTALLED)
-  host-clean: FORCE
+  $(_host_target)host-prepare: $(HOST_STAMP_PREPARED)
+  $(_host_target)host-configure: $(HOST_STAMP_CONFIGURED)
+  $(_host_target)host-compile: $(HOST_STAMP_BUILT) $(HOST_STAMP_INSTALLED)
+  host-install: host-compile
+
+  host-clean-build: FORCE
+	rm -rf $(HOST_BUILD_DIR) $(HOST_STAMP_BUILT)
+
+  host-clean: host-clean-build
 	$(call Host/Clean)
 	$(call Host/Uninstall)
-	rm -rf $(HOST_BUILD_DIR) $(HOST_STAMP_INSTALLED) $(HOST_STAMP_BUILT)
+	rm -rf $(HOST_STAMP_INSTALLED)
 
+    ifneq ($(CONFIG_AUTOREMOVE),)
+      host-compile:
+		$(FIND) $(HOST_BUILD_DIR) -mindepth 1 -maxdepth 1 -not '(' -type f -and -name '.*' -and -size 0 ')' | \
+			$(XARGS) rm -rf
+    endif
   endef
-
-  download:
-  prepare:
-  compile:
-  install:
-  clean:
-
 endif
 
 define HostBuild

+ 0 - 51
include/host.mk

@@ -1,51 +0,0 @@
-#
-# Copyright (C) 2007-2015 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-TMP_DIR ?= $(TOPDIR)/tmp
-ifeq ($(if $(TARGET_BUILD),,$(DUMP)),)
-  -include $(TMP_DIR)/.host.mk
-endif
-
-ifneq ($(__host_inc),1)
-__host_inc:=1
-
-export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
-
-try-run = $(shell set -e; \
-	TMP_F="$(TMP_DIR)/try-run.$$$$.tmp"; \
-	if ($(1)) >/dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi; \
-	rm -f "$$TMP_F"; \
-)
-
-host-cc-option = $(call try-run, \
-	$(HOSTCC) $(HOST_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP_F",$(1),$(2) \
-)
-
-.PRECIOUS: $(TMP_DIR)/.host.mk
-$(TMP_DIR)/.host.mk: $(TOPDIR)/include/host.mk
-	@mkdir -p $(TMP_DIR)
-	@( \
-		HOST_OS=`uname`; \
-		case "$$HOST_OS" in \
-			Linux) HOST_ARCH=`uname -m`;; \
-			Darwin) HOST_ARCH=`uname -m`;; \
-			*) HOST_ARCH=`uname -p`;; \
-		esac; \
-		GNU_HOST_NAME=`gcc -dumpmachine`; \
-		[ -z "$$GNU_HOST_NAME" -o "$$HOST_OS" = "Darwin" ] && \
-			GNU_HOST_NAME=`$(TOPDIR)/scripts/config.guess`; \
-		echo "HOST_OS:=$$HOST_OS" > $@; \
-		echo "HOST_ARCH:=$$HOST_ARCH" >> $@; \
-		echo "GNU_HOST_NAME:=$$GNU_HOST_NAME" >> $@; \
-		if gfind -L /dev/null || find -L /dev/null; then \
-			echo "FIND_L=find -L \$$(1)" >> $@; \
-		else \
-			echo "FIND_L=find \$$(1) -follow" >> $@; \
-		fi \
-	) >/dev/null 2>/dev/null
-
-endif

+ 196 - 11
include/image-commands.mk

@@ -7,8 +7,71 @@ define Build/uImage
 	mkimage -A $(LINUX_KARCH) \
 		-O linux -T kernel \
 		-C $(1) -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
-		-n '$(if $(UIMAGE_NAME),$(UIMAGE_NAME),$(call toupper,$(LINUX_KARCH)) libreCMC Linux-$(LINUX_VERSION))' -d $@ $@.new
-	@mv $@.new $@
+		-n '$(if $(UIMAGE_NAME),$(UIMAGE_NAME),$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION))' -d $@ $@.new
+	mv $@.new $@
+endef
+
+define Build/buffalo-enc
+	$(eval product=$(word 1,$(1)))
+	$(eval version=$(word 2,$(1)))
+	$(eval args=$(wordlist 3,$(words $(1)),$(1)))
+	$(STAGING_DIR_HOST)/bin/buffalo-enc \
+		-p $(product) -v $(version) $(args) \
+		-i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/buffalo-enc-tag
+	$(call Build/buffalo-enc,'' '' -S 152 $(1))
+endef
+
+define Build/buffalo-tag-dhp
+	$(eval product=$(word 1,$(1)))
+	$(eval region=$(word 2,$(1)))
+	$(eval language=$(word 3,$(1)))
+	$(STAGING_DIR_HOST)/bin/buffalo-tag \
+		-d 0x01000000 -w 1 \
+		-a $(BUFFALO_TAG_PLATFORM) \
+		-v $(BUFFALO_TAG_VERSION) -m $(BUFFALO_TAG_MINOR) \
+		-b $(product) -p $(product) \
+		-r $(region) -r $(region) -l $(language) \
+		-I $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/buffalo-dhp-image
+	$(STAGING_DIR_HOST)/bin/mkdhpimg $@ $@.new
+	mv $@.new $@
+endef
+
+define Build/eva-image
+	$(STAGING_DIR_HOST)/bin/lzma2eva $(KERNEL_LOADADDR) $(KERNEL_LOADADDR) $@ $@.new
+	mv $@.new $@
+endef
+
+define Build/seama
+	$(STAGING_DIR_HOST)/bin/seama -i $@ \
+		-m "dev=/dev/mtdblock/$(SEAMA_MTDBLOCK)" -m "type=firmware"
+	mv $@.seama $@
+endef
+
+define Build/seama-seal
+	$(STAGING_DIR_HOST)/bin/seama -i $@ -s $@.seama \
+		-m "signature=$(SEAMA_SIGNATURE)"
+	mv $@.seama $@
+endef
+
+define Build/zyxel-ras-image
+	let \
+		newsize="$(subst k,* 1024,$(RAS_ROOTFS_SIZE))"; \
+		$(STAGING_DIR_HOST)/bin/mkrasimage \
+			-b $(RAS_BOARD) \
+			-v $(RAS_VERSION) \
+			-r $@ \
+			-s $$newsize \
+			-o $@.new \
+			$(if $(findstring separate-kernel,$(word 1,$(1))),-k $(IMAGE_KERNEL)) \
+		&& mv $@.new $@
 endef
 
 define Build/netgear-chk
@@ -16,22 +79,49 @@ define Build/netgear-chk
 		-o $@.new \
 		-k $@ \
 		-b $(NETGEAR_BOARD_ID) \
-		-r $(NETGEAR_REGION)
+		$(if $(NETGEAR_REGION),-r $(NETGEAR_REGION),)
 	mv $@.new $@
 endef
 
 define Build/netgear-dni
 	$(STAGING_DIR_HOST)/bin/mkdniimg \
-		-B $(NETGEAR_BOARD_ID) -v libreCMC.$(REVISION) \
+		-B $(NETGEAR_BOARD_ID) -v $(VERSION_DIST).$(firstword $(subst -, ,$(REVISION))) \
 		$(if $(NETGEAR_HW_ID),-H $(NETGEAR_HW_ID)) \
 		-r "$(1)" \
 		-i $@ -o $@.new
 	mv $@.new $@
 endef
 
+define Build/append-squashfs-fakeroot-be
+	rm -rf $@.fakefs $@.fakesquashfs
+	mkdir $@.fakefs
+	$(STAGING_DIR_HOST)/bin/mksquashfs-lzma \
+		$@.fakefs $@.fakesquashfs \
+		-noappend -root-owned -be -nopad -b 65536 \
+		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
+	cat $@.fakesquashfs >> $@
+endef
+
+define Build/append-string
+	echo -n $(1) >> $@
+endef
+
+# append a fake/empty uImage header, to fool bootloaders rootfs integrity check
+# for example
+define Build/append-uImage-fakehdr
+	touch $@.fakehdr
+	$(STAGING_DIR_HOST)/bin/mkimage \
+		-A $(LINUX_KARCH) -O linux -T $(1) -C none \
+		-n '$(VERSION_DIST) fake $(1)' \
+		-d $@.fakehdr \
+		-s \
+		$@.fakehdr
+	cat $@.fakehdr >> $@
+endef
+
 define Build/tplink-safeloader
-       -$(STAGING_DIR_HOST)/bin/tplink-safeloader \
-		-B $(TPLINK_BOARD_NAME) \
+	-$(STAGING_DIR_HOST)/bin/tplink-safeloader \
+		-B $(TPLINK_BOARD_ID) \
 		-V $(REVISION) \
 		-k $(IMAGE_KERNEL) \
 		-r $@ \
@@ -42,8 +132,7 @@ define Build/tplink-safeloader
 endef
 
 define Build/append-dtb
-	$(call Image/BuildDTB,$(if $(DEVICE_DTS_DIR),$(DEVICE_DTS_DIR),$(DTS_DIR))/$(DEVICE_DTS).dts,$@.dtb)
-	cat $@.dtb >> $@
+	cat $(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb >> $@
 endef
 
 define Build/install-dtb
@@ -59,6 +148,7 @@ define Build/fit
 		-D $(DEVICE_NAME) -o $@.its -k $@ \
 		$(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \
 		-a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
+		-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
 		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
 	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
 	@mv $@.new $@
@@ -74,10 +164,20 @@ define Build/lzma-no-dict
 endef
 
 define Build/gzip
-	gzip -9n -c $@ $(1) > $@.new
+	gzip -f -9n -c $@ $(1) > $@.new
 	@mv $@.new $@
 endef
 
+define Build/zip
+	mkdir $@.tmp
+	mv $@ $@.tmp/$(1)
+
+	zip -j -X \
+		$(if $(SOURCE_DATE_EPOCH),--mtime="$(SOURCE_DATE_EPOCH)") \
+		$@ $@.tmp/$(if $(1),$(1),$@)
+	rm -rf $@.tmp
+endef
+
 define Build/jffs2
 	rm -rf $(KDIR_TMP)/$(DEVICE_NAME)/jffs2 && \
 		mkdir -p $(KDIR_TMP)/$(DEVICE_NAME)/jffs2/$$(dirname $(1)) && \
@@ -125,6 +225,10 @@ define Build/append-ubi
 	rm $@.tmp
 endef
 
+define Build/append-uboot
+	dd if=$(UBOOT_PATH) >> $@
+endef
+
 define Build/pad-to
 	dd if=$@ of=$@.new bs=$(1) conv=sync
 	mv $@.new $@
@@ -150,6 +254,11 @@ define Build/pad-offset
 	mv $@.new $@
 endef
 
+define Build/xor-image
+	$(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1)
+	mv $@.xor $@
+endef
+
 define Build/check-size
 	@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$(stat -c%s $@)" ] || { \
 		echo "WARNING: Image file $@ is too big" >&2; \
@@ -165,6 +274,45 @@ define Build/combined-image
 	@mv $@.new $@
 endef
 
+define Build/linksys-image
+	$(TOPDIR)/scripts/linksys-image.sh \
+		"$(call param_get_default,type,$(1),$(DEVICE_NAME))" \
+		$@ $@.new
+		mv $@.new $@
+endef
+
+define Build/openmesh-image
+	$(TOPDIR)/scripts/om-fwupgradecfg-gen.sh \
+		"$(call param_get_default,ce_type,$(1),$(DEVICE_NAME))" \
+		"$@-fwupgrade.cfg" \
+		"$(call param_get_default,kernel,$(1),$(IMAGE_KERNEL))" \
+		"$(call param_get_default,rootfs,$(1),$@)"
+	$(TOPDIR)/scripts/combined-ext-image.sh \
+		"$(call param_get_default,ce_type,$(1),$(DEVICE_NAME))" "$@" \
+		"$@-fwupgrade.cfg" "fwupgrade.cfg" \
+		"$(call param_get_default,kernel,$(1),$(IMAGE_KERNEL))" "kernel" \
+		"$(call param_get_default,rootfs,$(1),$@)" "rootfs"
+endef
+
+define Build/qsdk-ipq-factory-nand
+	$(TOPDIR)/scripts/mkits-qsdk-ipq-image.sh \
+		$@.its ubi $@
+	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
+	@mv $@.new $@
+endef
+
+define Build/qsdk-ipq-factory-nor
+	$(TOPDIR)/scripts/mkits-qsdk-ipq-image.sh \
+		$@.its hlos $(IMAGE_KERNEL) rootfs $(IMAGE_ROOTFS)
+	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
+	@mv $@.new $@
+endef
+
+define Build/senao-header
+	$(STAGING_DIR_HOST)/bin/mksenaofw $(1) -e $@ -o $@.new
+	mv $@.new $@
+endef
+
 define Build/sysupgrade-tar
 	sh $(TOPDIR)/scripts/sysupgrade-tar.sh \
 		--board $(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)) \
@@ -173,22 +321,59 @@ define Build/sysupgrade-tar
 		$@
 endef
 
+define Build/tplink-v1-header
+	$(STAGING_DIR_HOST)/bin/mktplinkfw \
+		-c -H $(TPLINK_HWID) -W $(TPLINK_HWREV) -L $(KERNEL_LOADADDR) \
+		-E $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
+		-m $(TPLINK_HEADER_VERSION) -N "$(VERSION_DIST)" -V $(REVISION) \
+		-k $@ -o $@.new $(1)
+	@mv $@.new $@
+endef
+
+define Build/tplink-v2-header
+	$(STAGING_DIR_HOST)/bin/mktplinkfw2 \
+		-c -H $(TPLINK_HWID) -W $(TPLINK_HWREV) -L $(KERNEL_LOADADDR) \
+		-E $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR))  \
+		-w $(TPLINK_HWREVADD) -F "$(TPLINK_FLASHLAYOUT)" \
+		-T $(TPLINK_HVERSION) -V "ver. 2.0" \
+		-k $@ -o $@.new $(1)
+	@mv $@.new $@
+endef
+
+define Build/tplink-v2-image
+	$(STAGING_DIR_HOST)/bin/mktplinkfw2 \
+		-H $(TPLINK_HWID) -W $(TPLINK_HWREV) \
+		-w $(TPLINK_HWREVADD) -F "$(TPLINK_FLASHLAYOUT)" \
+		-T $(TPLINK_HVERSION) -V "ver. 2.0" -a 0x4 -j \
+		-k $(IMAGE_KERNEL) -r $(IMAGE_ROOTFS) -o $@.new $(1)
+	cat $@.new >> $@
+	rm -rf $@.new
+endef
+
 json_quote=$(subst ','\'',$(subst ",\",$(1)))
 #")')
 metadata_devices=$(if $(1),$(subst "$(space)","$(comma)",$(strip $(foreach v,$(1),"$(call json_quote,$(v))"))))
 metadata_json = \
 	'{ $(if $(IMAGE_METADATA),$(IMAGE_METADATA)$(comma)) \
+		"metadata_version": "1.0", \
 		"supported_devices":[$(call metadata_devices,$(1))], \
 		"version": { \
 			"dist": "$(call json_quote,$(VERSION_DIST))", \
 			"version": "$(call json_quote,$(VERSION_NUMBER))", \
 			"revision": "$(call json_quote,$(REVISION))", \
-			"board": "$(call json_quote,$(BOARD))" \
+			"target": "$(call json_quote,$(TARGETID))", \
+			"board": "$(call json_quote,$(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)))" \
 		} \
 	}'
 
 define Build/append-metadata
-	$(if $(SUPPORTED_DEVICES),echo $(call metadata_json,$(SUPPORTED_DEVICES)) | fwtool -I - $@)
+	$(if $(SUPPORTED_DEVICES),-echo $(call metadata_json,$(SUPPORTED_DEVICES)) | fwtool -I - $@)
+	[ ! -s "$(BUILD_KEY)" -o ! -s "$(BUILD_KEY).ucert" -o ! -s "$@" ] || { \
+		cp "$(BUILD_KEY).ucert" "$@.ucert" ;\
+		usign -S -m "$@" -s "$(BUILD_KEY)" -x "$@.sig" ;\
+		ucert -A -c "$@.ucert" -x "$@.sig" ;\
+		fwtool -S "$@.ucert" "$@" ;\
+	}
 endef
 
 define Build/kernel2minor

+ 101 - 32
include/image.mk

@@ -8,7 +8,6 @@
 override TARGET_BUILD=
 include $(INCLUDE_DIR)/prereq.mk
 include $(INCLUDE_DIR)/kernel.mk
-include $(INCLUDE_DIR)/host.mk
 include $(INCLUDE_DIR)/version.mk
 include $(INCLUDE_DIR)/image-commands.mk
 
@@ -19,10 +18,8 @@ ifndef IB
 endif
 
 include $(INCLUDE_DIR)/image-legacy.mk
-
-ifdef TARGET_PER_DEVICE_ROOTFS
-  include $(INCLUDE_DIR)/rootfs.mk
-endif
+include $(INCLUDE_DIR)/feeds.mk
+include $(INCLUDE_DIR)/rootfs.mk
 
 override MAKE:=$(_SINGLE)$(SUBMAKE)
 override NO_TRACE_MAKE:=$(_SINGLE)$(NO_TRACE_MAKE)
@@ -137,12 +134,13 @@ endef
 
 define Image/BuildKernel/MkuImage
 	mkimage -A $(ARCH) -O linux -T kernel -C $(1) -a $(2) -e $(3) \
-		-n '$(call toupper,$(ARCH)) libreCMC Linux-$(LINUX_VERSION)' -d $(4) $(5)
+		-n '$(call toupper,$(ARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION)' -d $(4) $(5)
 endef
 
 define Image/BuildKernel/MkFIT
 	$(TOPDIR)/scripts/mkits.sh \
 		-D $(1) -o $(KDIR)/fit-$(1).its -k $(2) $(if $(3),-d $(3)) -C $(4) -a $(5) -e $(6) \
+		-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
 		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
 	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $(KDIR)/fit-$(1).its $(KDIR)/fit-$(1)$(7).itb
 endef
@@ -154,6 +152,32 @@ ifdef CONFIG_TARGET_IMAGES_GZIP
   endef
 endif
 
+
+# Disable noisy checks by default as in upstream
+ifeq ($(strip $(call kernel_patchver_ge,4.7.0)),1)
+  DTC_FLAGS += -Wno-unit_address_vs_reg
+endif
+ifeq ($(strip $(call kernel_patchver_ge,4.12.0)),1)
+  DTC_FLAGS += \
+	-Wno-unit_address_vs_reg \
+	-Wno-simple_bus_reg \
+	-Wno-unit_address_format \
+	-Wno-pci_bridge \
+	-Wno-pci_device_bus_num \
+	-Wno-pci_device_reg
+endif
+ifeq ($(strip $(call kernel_patchver_ge,4.17.0)),1)
+  DTC_FLAGS += \
+	-Wno-avoid_unnecessary_addr_size \
+	-Wno-alias_paths
+endif
+ifeq ($(strip $(call kernel_patchver_ge,4.18.0)),1)
+  DTC_FLAGS += \
+	-Wno-graph_child_address \
+	-Wno-graph_port \
+	-Wno-unique_unit_address
+endif
+
 # $(1) source dts file
 # $(2) target dtb file
 # $(3) extra CPP flags
@@ -162,10 +186,11 @@ define Image/BuildDTB
 	$(TARGET_CROSS)cpp -nostdinc -x assembler-with-cpp \
 		-I$(DTS_DIR) \
 		-I$(DTS_DIR)/include \
+		-I$(LINUX_DIR)/include/ \
 		-undef -D__DTS__ $(3) \
 		-o $(2).tmp $(1)
 	$(LINUX_DIR)/scripts/dtc/dtc -O dtb \
-		-i$(dir $(1)) $(4) \
+		-i$(dir $(1)) $(DTC_FLAGS) $(4) \
 		-o $(2) $(2).tmp
 	$(RM) $(2).tmp
 endef
@@ -204,21 +229,21 @@ define Image/mkfs/squashfs
 	$(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mkfs_target_dir,$(1)) $@ \
 		-nopad -noappend -root-owned \
 		-comp $(SQUASHFSCOMP) $(SQUASHFSOPT) \
-		-processors 1 \
-		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
+		-processors 1
 endef
 
 # $(1): board name
 # $(2): rootfs type
 # $(3): kernel image
+# $(4): compat string
 ifneq ($(CONFIG_NAND_SUPPORT),)
    define Image/Build/SysupgradeNAND
-	mkdir -p "$(KDIR_TMP)/sysupgrade-$(1)/"
-	echo "BOARD=$(1)" > "$(KDIR_TMP)/sysupgrade-$(1)/CONTROL"
-	[ -z "$(2)" ] || $(CP) "$(KDIR)/root.$(2)" "$(KDIR_TMP)/sysupgrade-$(1)/root"
-	[ -z "$(3)" ] || $(CP) "$(3)" "$(KDIR_TMP)/sysupgrade-$(1)/kernel"
+	mkdir -p "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/"
+	echo "BOARD=$(if $(4),$(4),$(1))" > "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/CONTROL"
+	[ -z "$(2)" ] || $(CP) "$(KDIR)/root.$(2)" "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/root"
+	[ -z "$(3)" ] || $(CP) "$(3)" "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/kernel"
 	(cd "$(KDIR_TMP)"; $(TAR) cvf \
-		"$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2)-sysupgrade.tar" sysupgrade-$(1) \
+		"$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2)-sysupgrade.tar" sysupgrade-$(if $(4),$(4),$(1)) \
 			$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
 	)
    endef
@@ -260,16 +285,13 @@ define Image/mkfs/ext4
 endef
 
 define Image/Manifest
-	$(STAGING_DIR_HOST)/bin/opkg \
-		--offline-root $(TARGET_DIR) \
-		--add-arch all:100 \
-		--add-arch $(if $(ARCH_PACKAGES),$(ARCH_PACKAGES),$(BOARD)):200 list-installed > \
+	$(call opkg,$(TARGET_DIR_ORIG)) list-installed > \
 		$(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).manifest
 endef
 
 ifdef CONFIG_TARGET_ROOTFS_TARGZ
   define Image/Build/targz
-	$(TAR) -cp --numeric-owner --owner=0 --group=0 --sort=name \
+	$(TAR) -cp --numeric-owner --owner=0 --group=0 --mode=a-s --sort=name \
 		$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
 		-C $(TARGET_DIR)/ . | gzip -9n > $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED))-rootfs.tar.gz
   endef
@@ -282,8 +304,8 @@ ifdef CONFIG_TARGET_ROOTFS_CPIOGZ
 endif
 
 mkfs_packages = $(filter-out @%,$(PACKAGES_$(call param_get,pkg,pkg=$(target_params))))
-mkfs_packages_add = $(filter-out -%,$(mkfs_packages))
-mkfs_packages_remove = $(patsubst -%,%,$(filter -%,$(mkfs_packages)))
+mkfs_packages_add = $(foreach pkg,$(filter-out -%,$(mkfs_packages)),$(pkg)$(call GetABISuffix,$(pkg)))
+mkfs_packages_remove = $(foreach pkg,$(patsubst -%,%,$(filter -%,$(mkfs_packages))),$(pkg)$(call GetABISuffix,$(pkg)))
 mkfs_cur_target_dir = $(call mkfs_target_dir,pkg=$(target_params))
 
 opkg_target = \
@@ -302,9 +324,9 @@ target-dir-%: FORCE
 		$(opkg_target) update && \
 		$(opkg_target) install \
 			$(call opkg_package_files,$(mkfs_packages_add)))
-	$(call prepare_rootfs,$(mkfs_cur_target_dir))
-	-mv $(mkfs_cur_target_dir).opkg $(mkfs_cur_target_dir)/etc/opkg
-	rm -f $(mkfs_cur_target_dir).conf
+	-$(CP) -T $(mkfs_cur_target_dir).opkg/ $(mkfs_cur_target_dir)/etc/opkg/
+	rm -rf $(mkfs_cur_target_dir).opkg $(mkfs_cur_target_dir).conf
+	$(call prepare_rootfs,$(mkfs_cur_target_dir),$(TOPDIR)/files)
 
 $(KDIR)/root.%: kernel_prepare
 	$(call Image/mkfs/$(word 1,$(target_params)),$(target_params))
@@ -324,6 +346,7 @@ define Device/Init
   CMDLINE:=
 
   IMAGES :=
+  ARTIFACTS :=
   IMAGE_PREFIX := $(IMG_PREFIX)-$(1)
   IMAGE_NAME = $$(IMAGE_PREFIX)-$$(1)-$$(2)
   KERNEL_PREFIX = $$(IMAGE_PREFIX)
@@ -351,6 +374,7 @@ define Device/Init
   FS_OPTIONS/ubifs = $$(MKUBIFS_OPTS)
 
   DEVICE_DTS :=
+  DEVICE_DTS_CONFIG :=
   DEVICE_DTS_DIR :=
 
   BOARD_NAME :=
@@ -359,15 +383,18 @@ define Device/Init
   IMAGE_METADATA :=
 
   FILESYSTEMS := $(TARGET_FILESYSTEMS)
+
+  UBOOT_PATH :=  $(STAGING_DIR_IMAGE)/uboot-$(1)
+
+  DEFAULT :=
 endef
 
 DEFAULT_DEVICE_VARS := \
-  DEVICE_NAME KERNEL KERNEL_INITRAMFS KERNEL_SIZE KERNEL_INITRAMFS_IMAGE \
-  DEVICE_DTS DEVICE_DTS_DIR BOARD_NAME CMDLINE \
-  UBOOTENV_IN_UBI KERNEL_IN_UBI \
-  BLOCKSIZE PAGESIZE SUBPAGESIZE VID_HDR_OFFSET \
-  UBINIZE_OPTS UIMAGE_NAME UBINIZE_PARTS \
-  SUPPORTED_DEVICES IMAGE_METADATA
+  DEVICE_NAME KERNEL KERNEL_INITRAMFS KERNEL_INITRAMFS_IMAGE KERNEL_SIZE \
+  CMDLINE UBOOTENV_IN_UBI KERNEL_IN_UBI BLOCKSIZE PAGESIZE SUBPAGESIZE \
+  VID_HDR_OFFSET UBINIZE_OPTS UBINIZE_PARTS MKUBIFS_OPTS DEVICE_DTS \
+  DEVICE_DTS_CONFIG DEVICE_DTS_DIR BOARD_NAME UIMAGE_NAME SUPPORTED_DEVICES \
+  IMAGE_METADATA KERNEL_ENTRY KERNEL_LOADADDR UBOOT_PATH
 
 define Device/ExportVar
   $(1) : $(2):=$$($(2))
@@ -395,6 +422,7 @@ endef
 
 define Device/Check/Common
   _PROFILE_SET = $$(strip $$(foreach profile,$$(PROFILES) DEVICE_$(1),$$(call DEVICE_CHECK_PROFILE,$$(profile))))
+  DEVICE_PACKAGES += $$(call extra_packages,$$(DEVICE_PACKAGES))
   ifdef TARGET_PER_DEVICE_ROOTFS
     $$(eval $$(call merge_packages,_PACKAGES,$$(DEVICE_PACKAGES) $$(call DEVICE_EXTRA_PACKAGES,$(1))))
     ROOTFS_ID/$(1) := $$(if $$(_PROFILE_SET),$$(call mkfs_packages_id,$$(_PACKAGES)))
@@ -434,7 +462,27 @@ define Device/Build/compile
 
 endef
 
+ifndef IB
+define Device/Build/dtb
+  ifndef BUILD_DTS_$(1)
+  BUILD_DTS_$(1) := 1
+  $(KDIR)/image-$(1).dtb: FORCE
+	$(call Image/BuildDTB,$(strip $(2))/$(strip $(3)).dts,$$@)
+
+  image_prepare: $(KDIR)/image-$(1).dtb
+  endif
+
+endef
+endif
+
 define Device/Build/kernel
+  $$(eval $$(foreach dts,$$(DEVICE_DTS), \
+	$$(call Device/Build/dtb,$$(notdir $$(dts)), \
+		$$(if $$(DEVICE_DTS_DIR),$$(DEVICE_DTS_DIR),$$(DTS_DIR)), \
+		$$(dts) \
+	) \
+  ))
+
   $(KDIR)/$$(KERNEL_NAME):: image_prepare
   $$(_TARGET): $$(if $$(KERNEL_INSTALL),$(BIN_DIR)/$$(KERNEL_IMAGE))
   $(call Device/Export,$$(KDIR_KERNEL_IMAGE),$(1))
@@ -479,6 +527,20 @@ define Device/Build/image
 
 endef
 
+define Device/Build/artifact
+  $$(_TARGET): $(BIN_DIR)/$(IMAGE_PREFIX)-$(1)
+  $(eval $(call Device/Export,$(KDIR)/tmp/$(IMAGE_PREFIX)-$(1)))
+  $(KDIR)/tmp/$(IMAGE_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE)
+	@rm -f $$@
+	$$(call concat_cmd,$(ARTIFACT/$(1)))
+
+  .IGNORE: $(BIN_DIR)/$(IMAGE_PREFIX)-$(1)
+
+  $(BIN_DIR)/$(IMAGE_PREFIX)-$(1): $(KDIR)/tmp/$(IMAGE_PREFIX)-$(1)
+	cp $$^ $$@
+
+endef
+
 define Device/Build
   $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(call Device/Build/initramfs,$(1)))
   $(call Device/Build/kernel,$(1))
@@ -489,12 +551,19 @@ define Device/Build
   $$(eval $$(foreach image,$$(IMAGES), \
     $$(foreach fs,$$(filter $(TARGET_FILESYSTEMS),$$(FILESYSTEMS)), \
       $$(call Device/Build/image,$$(fs),$$(image),$(1)))))
+
+  $$(eval $$(foreach artifact,$$(ARTIFACTS), \
+    $$(call Device/Build/artifact,$$(artifact))))
+
 endef
 
 define Device/DumpInfo
 Target-Profile: DEVICE_$(1)
 Target-Profile-Name: $(DEVICE_TITLE)
 Target-Profile-Packages: $(DEVICE_PACKAGES)
+Target-Profile-hasImageMetadata: $(if $(foreach image,$(IMAGES),$(findstring append-metadata,$(IMAGE/$(image)))),1,0)
+Target-Profile-SupportedDevices: $(SUPPORTED_DEVICES)
+$(if $(DEFAULT),Target-Profile-Default: $(DEFAULT))
 Target-Profile-Description:
 $(DEVICE_DESCRIPTION)
 @@
@@ -544,7 +613,7 @@ define BuildImage
 		$(call Image/Prepare)
 
     legacy-images-prepare-make: image_prepare
-		$(MAKE) legacy-images-prepare
+		$(MAKE) legacy-images-prepare BIN_DIR="$(BIN_DIR)"
 
   else
     image_prepare:
@@ -568,7 +637,7 @@ define BuildImage
 
   legacy-images-make: install-images
 	$(call Image/mkfs/ubifs/legacy)
-	$(MAKE) legacy-images
+	$(MAKE) legacy-images BIN_DIR="$(BIN_DIR)"
 
   install: install-images
 	$(call Image/Manifest)

+ 13 - 10
include/kernel-build.mk

@@ -4,7 +4,6 @@
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
 #
-include $(INCLUDE_DIR)/host.mk
 include $(INCLUDE_DIR)/prereq.mk
 include $(INCLUDE_DIR)/depends.mk
 
@@ -12,7 +11,7 @@ ifneq ($(DUMP),1)
   all: compile
 endif
 
-KERNEL_FILE_DEPENDS=$(GENERIC_PATCH_DIR) $(PATCH_DIR) $(GENERIC_FILES_DIR) $(FILES_DIR)
+KERNEL_FILE_DEPENDS=$(GENERIC_BACKPORT_DIR) $(GENERIC_PATCH_DIR) $(GENERIC_HACK_DIR) $(PATCH_DIR) $(GENERIC_FILES_DIR) $(FILES_DIR)
 STAMP_PREPARED=$(LINUX_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,$(KERNEL_FILE_DEPENDS),)))
 STAMP_CONFIGURED:=$(LINUX_DIR)/.configured
 include $(INCLUDE_DIR)/download.mk
@@ -51,14 +50,10 @@ ifneq ($(strip $(CONFIG_KERNEL_GIT_LOCAL_REPOSITORY)),"")
   KERNEL_GIT_OPTS+=--reference $(CONFIG_KERNEL_GIT_LOCAL_REPOSITORY)
 endif
 
-ifneq ($(strip $(CONFIG_KERNEL_GIT_BRANCH)),"")
-  KERNEL_GIT_OPTS+=--branch $(CONFIG_KERNEL_GIT_BRANCH)
-endif
-
 define Download/git-kernel
   URL:=$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI))
   PROTO:=git
-  VERSION:=$(CONFIG_KERNEL_GIT_BRANCH)
+  VERSION:=$(CONFIG_KERNEL_GIT_REF)
   FILE:=$(LINUX_SOURCE)
   SUBDIR:=linux-$(LINUX_VERSION)
   OPTS:=$(KERNEL_GIT_OPTS)
@@ -105,7 +100,7 @@ define BuildKernel
   $(KERNEL_BUILD_DIR)/symtab.h: FORCE
 	rm -f $(KERNEL_BUILD_DIR)/symtab.h
 	touch $(KERNEL_BUILD_DIR)/symtab.h
-	+$(MAKE) $(KERNEL_MAKEOPTS) vmlinux
+	+$(KERNEL_MAKE) vmlinux
 	find $(LINUX_DIR) $(STAGING_DIR_ROOT)/lib/modules -name \*.ko | \
 		xargs $(TARGET_CROSS)nm | \
 		awk '$$$$1 == "U" { print $$$$2 } ' | \
@@ -136,10 +131,16 @@ define BuildKernel
 	$(Kernel/Configure)
 	touch $$@
 
+  $(LINUX_DIR)/.modules: export STAGING_PREFIX=$$(STAGING_DIR_HOST)
+  $(LINUX_DIR)/.modules: export PKG_CONFIG_PATH=$$(STAGING_DIR_HOST)/lib/pkgconfig
+  $(LINUX_DIR)/.modules: export PKG_CONFIG_LIBDIR=$$(STAGING_DIR_HOST)/lib/pkgconfig
   $(LINUX_DIR)/.modules: $(STAMP_CONFIGURED) $(LINUX_DIR)/.config FORCE
 	$(Kernel/CompileModules)
 	touch $$@
 
+  $(LINUX_DIR)/.image: export STAGING_PREFIX=$$(STAGING_DIR_HOST)
+  $(LINUX_DIR)/.image: export PKG_CONFIG_PATH=$$(STAGING_DIR_HOST)/lib/pkgconfig
+  $(LINUX_DIR)/.image: export PKG_CONFIG_LIBDIR=$$(STAGING_DIR_HOST)/lib/pkgconfig
   $(LINUX_DIR)/.image: $(STAMP_CONFIGURED) $(if $(CONFIG_STRIP_KERNEL_EXPORTS),$(KERNEL_BUILD_DIR)/symtab.h) FORCE
 	$(Kernel/CompileImage)
 	$(Kernel/CollectDebug)
@@ -152,7 +153,7 @@ define BuildKernel
   endef
 
   download: $(if $(LINUX_SITE),$(DL_DIR)/$(LINUX_SOURCE))
-  prepare: $(STAMP_CONFIGURED)
+  prepare: $(STAMP_PREPARED)
   compile: $(LINUX_DIR)/.modules
 	$(MAKE) -C image compile TARGET_BUILD=
 
@@ -160,7 +161,9 @@ define BuildKernel
 	rm -f $(LINUX_DIR)/.config.prev
 	rm -f $(STAMP_CONFIGURED)
 	$(LINUX_RECONF_CMD) > $(LINUX_DIR)/.config
-	$(_SINGLE)$(MAKE) -C $(LINUX_DIR) $(KERNEL_MAKEOPTS) HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib -lncurses" $$@
+	$(_SINGLE)$(KERNEL_MAKE) \
+		$(if $(findstring Darwin,$(HOST_OS)),HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib -lncurses") \
+		$$@
 	$(LINUX_RECONF_DIFF) $(LINUX_DIR)/.config > $(LINUX_RECONFIG_TARGET)
 
   install: $(LINUX_DIR)/.image

+ 16 - 36
include/kernel-defaults.mk

@@ -5,26 +5,6 @@
 # See /LICENSE for more information.
 #
 
-ifneq ($(SOURCE_DATE_EPOCH),)
-  ifndef DUMP
-    KBUILD_BUILD_TIMESTAMP:=$(shell perl -e 'print scalar gmtime($(SOURCE_DATE_EPOCH))')
-  endif
-endif
-
-KERNEL_MAKEOPTS := -C $(LINUX_DIR) \
-	HOSTCFLAGS="$(HOST_CFLAGS) -Wall -Wmissing-prototypes -Wstrict-prototypes" \
-	CROSS_COMPILE="$(KERNEL_CROSS)" \
-	ARCH="$(LINUX_KARCH)" \
-	KBUILD_HAVE_NLS=no \
-	KBUILD_BUILD_USER="$(call qstrip,$(CONFIG_KERNEL_BUILD_USER))" \
-	KBUILD_BUILD_HOST="$(call qstrip,$(CONFIG_KERNEL_BUILD_DOMAIN))" \
-	KBUILD_BUILD_TIMESTAMP="$(KBUILD_BUILD_TIMESTAMP)" \
-	KBUILD_BUILD_VERSION="0" \
-	HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib" \
-	CONFIG_SHELL="$(BASH)" \
-	$(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
-	$(if $(PKG_BUILD_ID),LDFLAGS_MODULE=--build-id=0x$(PKG_BUILD_ID))
-
 ifdef CONFIG_STRIP_KERNEL_EXPORTS
   KERNEL_MAKEOPTS += \
 	EXTRA_LDSFLAGS="-I$(KERNEL_BUILD_DIR) -include symtab.h"
@@ -36,29 +16,27 @@ ifneq (,$(KERNEL_CC))
   KERNEL_MAKEOPTS += CC="$(KERNEL_CC)"
 endif
 
-ifdef CONFIG_USE_SPARSE
-  KERNEL_MAKEOPTS += C=1 CHECK=$(STAGING_DIR_HOST)/bin/sparse
-endif
-
-ifneq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
- KERNEL_MAKEOPTS += LOCALVERSION=
-endif
-
 export HOST_EXTRACFLAGS=-I$(STAGING_DIR_HOST)/include
 
 # defined in quilt.mk
 Kernel/Patch:=$(Kernel/Patch/Default)
 
+ifneq (,$(findstring .xz,$(LINUX_SOURCE)))
+  LINUX_CAT:=xzcat
+else
+  LINUX_CAT:=zcat
+endif
+
 ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"")
   ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
     define Kernel/Prepare/Default
-	xzcat $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
+	$(LINUX_CAT) $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
 	$(Kernel/Patch)
 	$(if $(QUILT),touch $(LINUX_DIR)/.quilt_used)
     endef
   else
     define Kernel/Prepare/Default
-	xzcat $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
+	$(LINUX_CAT) $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
     endef
   endif
 else
@@ -91,6 +69,7 @@ ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
 	$(call Kernel/SetInitramfs/PreConfigure)
 	echo 'CONFIG_INITRAMFS_ROOT_UID=$(shell id -u)' >> $(LINUX_DIR)/.config
 	echo 'CONFIG_INITRAMFS_ROOT_GID=$(shell id -g)' >> $(LINUX_DIR)/.config
+	echo "$(if $(CONFIG_TARGET_INITRAMFS_FORCE),CONFIG_INITRAMFS_FORCE=y,# CONFIG_INITRAMFS_FORCE is not set)" >> $(LINUX_DIR)/.config
 	echo "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_NONE),CONFIG_INITRAMFS_COMPRESSION_NONE=y,# CONFIG_INITRAMFS_COMPRESSION_NONE is not set)" >> $(LINUX_DIR)/.config
 	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),CONFIG_INITRAMFS_COMPRESSION_GZIP=y\nCONFIG_RD_GZIP=y,# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set\n# CONFIG_RD_GZIP is not set)" >> $(LINUX_DIR)/.config
 	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),CONFIG_INITRAMFS_COMPRESSION_BZIP2=y\nCONFIG_RD_BZIP2=y,# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set\n# CONFIG_RD_BZIP2 is not set)" >> $(LINUX_DIR)/.config
@@ -106,6 +85,7 @@ define Kernel/SetNoInitramfs
 	mv $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.old
 	grep -v INITRAMFS $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config.set
 	echo 'CONFIG_INITRAMFS_SOURCE=""' >> $(LINUX_DIR)/.config.set
+	echo '# CONFIG_INITRAMFS_FORCE is not set' >> $(LINUX_DIR)/.config.set
 endef
 
 define Kernel/Configure/Default
@@ -124,7 +104,7 @@ define Kernel/Configure/Default
 		cp $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config; \
 		cp $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.prev; \
 	}
-	$(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(MAKE) $(KERNEL_MAKEOPTS) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install
+	$(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(KERNEL_MAKE) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install
 	grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | mkhash md5 > $(LINUX_DIR)/.vermagic
 endef
 
@@ -134,7 +114,7 @@ endef
 
 define Kernel/CompileModules/Default
 	rm -f $(LINUX_DIR)/vmlinux $(LINUX_DIR)/System.map
-	+$(MAKE) $(KERNEL_MAKEOPTS) modules
+	+$(KERNEL_MAKE) modules
 endef
 
 OBJCOPY_STRIP = -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id
@@ -150,7 +130,7 @@ define Kernel/CopyImage
 		$(KERNEL_CROSS)objcopy $(OBJCOPY_STRIP) -S $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).elf; \
 		$(CP) $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).debug; \
 		$(foreach k, \
-			$(if $(KERNEL_IMAGES),$(KERNEL_IMAGES),$(filter-out dtbs,$(KERNELNAME))), \
+			$(if $(KERNEL_IMAGES),$(KERNEL_IMAGES),$(filter-out vmlinux dtbs,$(KERNELNAME))), \
 			$(CP) $(LINUX_DIR)/arch/$(LINUX_KARCH)/boot/$(IMAGES_DIR)/$(k) $(KERNEL_BUILD_DIR)/$(k)$(1); \
 		) \
 	}
@@ -158,16 +138,16 @@ endef
 
 define Kernel/CompileImage/Default
 	rm -f $(TARGET_DIR)/init
-	+$(MAKE) $(KERNEL_MAKEOPTS) $(if $(KERNELNAME),$(KERNELNAME),all) modules
+	+$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules
 	$(call Kernel/CopyImage)
 endef
 
 ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
 define Kernel/CompileImage/Initramfs
 	$(call Kernel/Configure/Initramfs)
-	$(CP) $(GENERIC_PLATFORM_DIR)/base-files/init $(TARGET_DIR)/init
+	$(CP) $(GENERIC_PLATFORM_DIR)/other-files/init $(TARGET_DIR)/init
 	rm -rf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/usr/initramfs_data.cpio*
-	+$(MAKE) $(KERNEL_MAKEOPTS) $(if $(KERNELNAME),$(KERNELNAME),all) modules
+	+$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules
 	$(call Kernel/CopyImage,-initramfs)
 endef
 else

+ 20 - 2
include/kernel-version.mk

@@ -2,13 +2,31 @@
 
 LINUX_RELEASE?=1
 
-LINUX_VERSION-4.4 = .202
+ifdef CONFIG_TESTING_KERNEL
+  KERNEL_PATCHVER:=$(KERNEL_TESTING_PATCHVER)
+endif
+
+LINUX_VERSION-4.14 = .165
+
+LINUX_KERNEL_HASH-4.14.165 = ca362003caa7f865abca5162f01b58a564ff8a107f6c5f61c5e181e9a4b62817
 
-LINUX_KERNEL_HASH-4.4.202 = a8491f36ec77f643e566da7e2877ccc0b96cb8eacd37a13f2ed34cc98c31b21e
+remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
+sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))
 
+ifneq ($(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+  LINUX_VERSION:=$(call sanitize_uri,$(call remove_uri_prefix,$(CONFIG_KERNEL_GIT_CLONE_URI)))
+  ifeq ($(call qstrip,$(CONFIG_KERNEL_GIT_REF)),)
+    CONFIG_KERNEL_GIT_REF:=HEAD
+  endif
+  LINUX_VERSION:=$(LINUX_VERSION)-$(call sanitize_uri,$(CONFIG_KERNEL_GIT_REF))
+else
 ifdef KERNEL_PATCHVER
   LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER)))
 endif
+ifdef KERNEL_TESTING_PATCHVER
+  LINUX_TESTING_VERSION:=$(KERNEL_TESTING_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_TESTING_PATCHVER)))
+endif
+endif
 
 split_version=$(subst ., ,$(1))
 merge_version=$(subst $(space),.,$(1))

+ 113 - 65
include/kernel.mk

@@ -10,6 +10,12 @@ CHECK:=1
 DUMP:=1
 endif
 
+ifneq ($(SOURCE_DATE_EPOCH),)
+  ifndef DUMP
+    KBUILD_BUILD_TIMESTAMP:=$(shell perl -e 'print scalar gmtime($(SOURCE_DATE_EPOCH))')
+  endif
+endif
+
 ifeq ($(__target_inc),)
   ifndef CHECK
     include $(INCLUDE_DIR)/target.mk
@@ -46,24 +52,32 @@ else
   LINUX_VERMAGIC:=$(strip $(shell cat $(LINUX_DIR)/.vermagic 2>/dev/null))
   LINUX_VERMAGIC:=$(if $(LINUX_VERMAGIC),$(LINUX_VERMAGIC),unknown)
 
-  LINUX_UNAME_VERSION:=$(if $(word 3,$(subst ., ,$(KERNEL_BASE))),$(KERNEL_BASE),$(KERNEL_BASE).0)
+  LINUX_UNAME_VERSION:=$(KERNEL_BASE)
   ifneq ($(findstring -rc,$(LINUX_VERSION)),)
     LINUX_UNAME_VERSION:=$(LINUX_UNAME_VERSION)-$(strip $(lastword $(subst -, ,$(LINUX_VERSION))))
   endif
 
-  MODULES_SUBDIR:=lib/modules/$(LINUX_UNAME_VERSION)-gnu
-  TARGET_MODULES_DIR := $(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)
-
   LINUX_KERNEL:=$(KERNEL_BUILD_DIR)/vmlinux
 
-  LINUX_SOURCE:=linux-libre-$(LINUX_VERSION)-gnu.tar.xz
-  TESTING:=$(if $(findstring -rc,$(LINUX_VERSION)),/testing,)
-  ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
-	LINUX_SITE:=@KERNEL_LIBRE/$(LINUX_VERSION)-gnu$(TESTING)
+  ifneq (,$(findstring -rc,$(LINUX_VERSION)))
+      LINUX_SOURCE:=linux-libre-$(LINUX_VERSION)-gnu.tar.gz
+  else
+      LINUX_SOURCE:=linux-libre-$(LINUX_VERSION)-gnu.tar.xz
+  endif
+
+  ifneq (,$(findstring -rc,$(LINUX_VERSION)))
+      LINUX_SITE:=
+  else ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+      LINUX_SITE:=@KERNEL_LIBRE/$(LINUX_VERSION)-gnu$(TESTING)
+  else
+      LINUX_UNAME_VERSION:=$(strip $(shell cat $(LINUX_DIR)/include/config/kernel.release 2>/dev/null))
   endif
 
+  MODULES_SUBDIR:=lib/modules/$(LINUX_UNAME_VERSION)
+  TARGET_MODULES_DIR:=$(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)
+
   ifneq ($(TARGET_BUILD),1)
-    PKG_BUILD_DIR ?= $(KERNEL_BUILD_DIR)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
+    PKG_BUILD_DIR ?= $(KERNEL_BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
   endif
 endif
 
@@ -77,6 +91,8 @@ else ifneq (,$(findstring $(ARCH) , armeb ))
   LINUX_KARCH := arm
 else ifneq (,$(findstring $(ARCH) , mipsel mips64 mips64el ))
   LINUX_KARCH := mips
+else ifneq (,$(findstring $(ARCH) , powerpc64 ))
+  LINUX_KARCH := powerpc
 else ifneq (,$(findstring $(ARCH) , sh2 sh3 sh4 ))
   LINUX_KARCH := sh
 else ifneq (,$(findstring $(ARCH) , i386 x86_64 ))
@@ -85,61 +101,88 @@ else
   LINUX_KARCH := $(ARCH)
 endif
 
+KERNEL_MAKE = $(MAKE) $(KERNEL_MAKEOPTS)
+
+KERNEL_MAKE_FLAGS = \
+	HOSTCFLAGS="$(HOST_CFLAGS) -Wall -Wmissing-prototypes -Wstrict-prototypes" \
+	CROSS_COMPILE="$(KERNEL_CROSS)" \
+	ARCH="$(LINUX_KARCH)" \
+	KBUILD_HAVE_NLS=no \
+	KBUILD_BUILD_USER="$(call qstrip,$(CONFIG_KERNEL_BUILD_USER))" \
+	KBUILD_BUILD_HOST="$(call qstrip,$(CONFIG_KERNEL_BUILD_DOMAIN))" \
+	KBUILD_BUILD_TIMESTAMP="$(KBUILD_BUILD_TIMESTAMP)" \
+	KBUILD_BUILD_VERSION="0" \
+	HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib" \
+	CONFIG_SHELL="$(BASH)" \
+	$(if $(findstring c,$(LIBRECMC_VERBOSE)),V=1,V='') \
+	$(if $(PKG_BUILD_ID),LDFLAGS_MODULE=--build-id=0x$(PKG_BUILD_ID)) \
+	cmd_syscalls=
+
+ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+  KERNEL_MAKE_FLAGS += \
+	KERNELRELEASE=$(LINUX_VERSION)
+endif
+
+KERNEL_MAKEOPTS := -C $(LINUX_DIR) $(KERNEL_MAKE_FLAGS)
+
+ifdef CONFIG_USE_SPARSE
+  KERNEL_MAKEOPTS += C=1 CHECK=$(STAGING_DIR_HOST)/bin/sparse
+endif
+
+ifeq ($(HOST_OS),Darwin)
+  export SKIP_STACK_VALIDATION:=1
+endif
+
+PKG_EXTMOD_SUBDIRS ?= .
+
+define populate_module_symvers
+	@mkdir -p $(PKG_INFO_DIR)
+	cat /dev/null > $(PKG_INFO_DIR)/$(PKG_NAME).symvers; \
+	for subdir in $(PKG_EXTMOD_SUBDIRS); do \
+		cat $(PKG_INFO_DIR)/*.symvers 2>/dev/null > $(PKG_BUILD_DIR)/$$$$subdir/Module.symvers; \
+	done
+endef
+
+define collect_module_symvers
+	for subdir in $(PKG_EXTMOD_SUBDIRS); do \
+		realdir=$$$$(readlink -f $(PKG_BUILD_DIR)); \
+		grep -F $(PKG_BUILD_DIR) $(PKG_BUILD_DIR)/$$$$subdir/Module.symvers >> $(PKG_BUILD_DIR)/Module.symvers.tmp; \
+		[ "$(PKG_BUILD_DIR)" = "$$$$realdir" ] || \
+			grep -F $$$$realdir $(PKG_BUILD_DIR)/$$$$subdir/Module.symvers >> $(PKG_BUILD_DIR)/Module.symvers.tmp; \
+	done; \
+	sort -u $(PKG_BUILD_DIR)/Module.symvers.tmp > $(PKG_BUILD_DIR)/Module.symvers; \
+	mv $(PKG_BUILD_DIR)/Module.symvers $(PKG_INFO_DIR)/$(PKG_NAME).symvers
+endef
+
+define KernelPackage/hooks
+  ifneq ($(PKG_NAME),kernel)
+    Hooks/Compile/Pre += populate_module_symvers
+    Hooks/Compile/Post += collect_module_symvers
+  endif
+  define KernelPackage/hooks
+  endef
+endef
+
 define KernelPackage/Defaults
   FILES:=
   AUTOLOAD:=
+  MODPARAMS:=
   PKGFLAGS+=nonshared
 endef
 
+# 1: name
+# 2: install prefix
+# 3: module priority prefix
+# 4: required for boot
+# 5: module list
 define ModuleAutoLoad
-	$(SH_FUNC) \
-	export modules=; \
-	probe_module() { \
-		local mods="$$$$$$$$1"; \
-		local boot="$$$$$$$$2"; \
-		local mod; \
-		shift 2; \
-		for mod in $$$$$$$$mods; do \
-			mkdir -p $(2)/etc/modules.d; \
-			echo "$$$$$$$$mod" >> $(2)/etc/modules.d/$(1); \
-		done; \
-		if [ -e $(2)/etc/modules.d/$(1) ]; then \
-			if [ "$$$$$$$$boot" = "1" -a ! -e $(2)/etc/modules-boot.d/$(1) ]; then \
-				mkdir -p $(2)/etc/modules-boot.d; \
-				ln -s ../modules.d/$(1) $(2)/etc/modules-boot.d/; \
-			fi; \
-			modules="$$$$$$$${modules:+$$$$$$$$modules }$$$$$$$$mods"; \
-		fi; \
-	}; \
-	add_module() { \
-		local priority="$$$$$$$$1"; \
-		local mods="$$$$$$$$2"; \
-		local boot="$$$$$$$$3"; \
-		local mod; \
-		shift 3; \
-		for mod in $$$$$$$$mods; do \
-			mkdir -p $(2)/etc/modules.d; \
-			echo "$$$$$$$$mod" >> $(2)/etc/modules.d/$$$$$$$$priority-$(1); \
-		done; \
-		if [ -e $(2)/etc/modules.d/$$$$$$$$priority-$(1) ]; then \
-			if [ "$$$$$$$$boot" = "1" -a ! -e $(2)/etc/modules-boot.d/$$$$$$$$priority-$(1) ]; then \
-				mkdir -p $(2)/etc/modules-boot.d; \
-				ln -s ../modules.d/$$$$$$$$priority-$(1) $(2)/etc/modules-boot.d/; \
-			fi; \
-			modules="$$$$$$$${modules:+$$$$$$$$modules }$$$$$$$$priority-$(1)"; \
-		fi; \
-	}; \
-	$(3) \
-	if [ -n "$$$$$$$$modules" ]; then \
-		modules="$$$$$$$$(echo "$$$$$$$$modules" | tr ' ' '\n' | sort | uniq | paste -s -d' ' -)"; \
-		mkdir -p $(2)/etc/modules.d; \
-		mkdir -p $(2)/CONTROL; \
-		echo "#!/bin/sh" > $(2)/CONTROL/postinst-pkg; \
-		echo "[ -z \"\$$$$$$$$IPKG_INSTROOT\" ] || exit 0" >> $(2)/CONTROL/postinst-pkg; \
-		echo ". /lib/functions.sh" >> $(2)/CONTROL/postinst-pkg; \
-		echo "insert_modules $$$$$$$$modules" >> $(2)/CONTROL/postinst-pkg; \
-		chmod 0755 $(2)/CONTROL/postinst-pkg; \
-	fi
+  $(if $(5), \
+    mkdir -p $(2)/etc/modules.d; \
+    ($(foreach mod,$(5), \
+      echo "$(mod)$(if $(MODPARAMS.$(mod)), $(MODPARAMS.$(mod)),$(if $(MODPARAMS), $(MODPARAMS)))"; )) > $(2)/etc/modules.d/$(3)$(1); \
+    $(if $(4), \
+      mkdir -p $(2)/etc/modules-boot.d; \
+      ln -sf ../modules.d/$(3)$(1) $(2)/etc/modules-boot.d/;))
 endef
 
 ifeq ($(DUMP)$(TARGET_BUILD),)
@@ -192,10 +235,10 @@ $(call KernelPackage/$(1)/config)
   endif
 
   $(call KernelPackage/depends)
+  $(call KernelPackage/hooks)
 
   ifneq ($(if $(filter-out %=y %=n %=m,$(KCONFIG)),$(filter m y,$(foreach c,$(filter-out %=y %=n %=m,$(KCONFIG)),$($(c)))),.),)
-    ifneq ($(strip $(FILES)),)
-      define Package/kmod-$(1)/install
+    define Package/kmod-$(1)/install
 		  @for mod in $$(call version_filter,$$(FILES)); do \
 			if grep -q "$$$$$$$${mod##$(LINUX_DIR)/}" "$(LINUX_DIR)/modules.builtin"; then \
 				echo "NOTICE: module '$$$$$$$$mod' is built-in."; \
@@ -207,10 +250,9 @@ $(call KernelPackage/$(1)/config)
 				exit 1; \
 			fi; \
 		  done;
-		  $(call ModuleAutoLoad,$(1),$$(1),$(AUTOLOAD))
+		  $(call ModuleAutoLoad,$(1),$$(1),$(filter-out 0-,$(word 1,$(AUTOLOAD))-),$(filter-out 0,$(word 2,$(AUTOLOAD))),$(sort $(wordlist 3,99,$(AUTOLOAD))))
 		  $(call KernelPackage/$(1)/install,$$(1))
-      endef
-    endif
+    endef
   $(if $(CONFIG_PACKAGE_kmod-$(1)),
     else
       compile: $(1)-disabled
@@ -224,17 +266,23 @@ $(call KernelPackage/$(1)/config)
   endif
   $$(eval $$(call BuildPackage,kmod-$(1)))
 
-  $$(IPKG_kmod-$(1)): $$(wildcard $$(FILES))
+  $$(IPKG_kmod-$(1)): $$(wildcard $$(call version_filter,$$(FILES)))
+
 endef
 
 version_filter=$(if $(findstring @,$(1)),$(shell $(SCRIPT_DIR)/package-metadata.pl version_filter $(KERNEL_PATCHVER) $(1)),$(1))
 
+# 1: priority (optional)
+# 2: module list
+# 3: boot flag
 define AutoLoad
-  add_module "$(1)" "$(call version_filter,$(2))" "$(3)";
+  $(if $(1),$(1),0) $(if $(3),1,0) $(call version_filter,$(2))
 endef
 
+# 1: module list
+# 2: boot flag
 define AutoProbe
-  probe_module "$(call version_filter,$(1))" "$(2)";
+  $(call AutoLoad,,$(1),$(2))
 endef
 
 version_field=$(if $(word $(1),$(2)),$(word $(1),$(2)),0)

+ 56 - 15
include/netfilter.mk

@@ -30,9 +30,10 @@ endef
 # core
 
 # kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_REJECT,CONFIG_NF_REJECT_IPV4, $(P_V4)nf_reject_ipv4),))
+
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT,CONFIG_IP_NF_IPTABLES, $(P_V4)ip_tables),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT,CONFIG_NETFILTER_XTABLES, $(P_XT)x_tables),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT,CONFIG_NF_REJECT_IPV4, $(P_V4)nf_reject_ipv4),))
 
 $(eval $(if $(NF_KMOD),$(call nf_add,IPT_CORE,CONFIG_NETFILTER_XTABLES, $(P_XT)xt_tcpudp),))
 $(eval $(if $(NF_KMOD),$(call nf_add,IPT_CORE,CONFIG_IP_NF_FILTER, $(P_V4)iptable_filter),))
@@ -79,26 +80,34 @@ $(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_MATCH_CONNTRACK, $(P_XT)x
 
 $(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_CONNBYTES, $(P_XT)xt_connbytes))
 $(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_CONNLIMIT, $(P_XT)xt_connlimit))
+$(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_CONNCOUNT, $(P_XT)nf_conncount))
 $(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_CONNMARK, $(P_XT)xt_connmark))
 $(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_HELPER, $(P_XT)xt_helper))
 $(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_RECENT, $(P_XT)xt_recent))
 
 $(eval $(if $(NF_KMOD),,$(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_CONNMARK, $(P_XT)xt_CONNMARK)))
 
+#conntrack-label
+
+$(eval $(call nf_add,IPT_CONNTRACK_LABEL,CONFIG_NETFILTER_XT_MATCH_CONNLABEL, $(P_XT)xt_connlabel))
+
 # extra
 
 $(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_ADDRTYPE, $(if $(NF_KMOD),$(P_XT)xt_addrtype,$(P_XT)ipt_addrtype)))
 $(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_OWNER, $(P_XT)xt_owner))
-$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_PHYSDEV, $(P_XT)xt_physdev))
 $(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_PKTTYPE, $(P_XT)xt_pkttype))
 $(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_QUOTA, $(P_XT)xt_quota))
 
 #$(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_TARGET_ROUTE, $(P_V4)ipt_ROUTE))
 
+# physdev
+
+$(eval $(call nf_add,IPT_PHYSDEV,CONFIG_NETFILTER_XT_MATCH_PHYSDEV, $(P_XT)xt_physdev))
 
 # filter
 
 $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_string))
+$(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_BPF, $(P_XT)xt_bpf))
 
 
 # ipopt
@@ -106,6 +115,8 @@ $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_stri
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_DSCP, $(P_XT)xt_dscp))
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_TARGET_DSCP, $(P_XT)xt_DSCP))
 $(eval $(call nf_add,IPT_HASHLIMIT,CONFIG_NETFILTER_XT_MATCH_HASHLIMIT, $(P_XT)xt_hashlimit))
+$(eval $(call nf_add,IPT_RPFILTER,CONFIG_IP_NF_MATCH_RPFILTER, $(P_V4)ipt_rpfilter))
+$(eval $(call nf_add,IPT_RPFILTER,CONFIG_IP6_NF_MATCH_RPFILTER, $(P_V6)ip6t_rpfilter))
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_LENGTH, $(P_XT)xt_length))
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_STATISTIC, $(P_XT)xt_statistic))
 $(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_TCPMSS, $(P_XT)xt_tcpmss))
@@ -136,14 +147,18 @@ $(eval $(call nf_add,IPT_IPSEC,CONFIG_IP_NF_MATCH_AH, $(P_V4)ipt_ah))
 $(eval $(call nf_add,IPT_IPSEC,CONFIG_NETFILTER_XT_MATCH_ESP, $(P_XT)xt_esp))
 $(eval $(call nf_add,IPT_IPSEC,CONFIG_NETFILTER_XT_MATCH_POLICY, $(P_XT)xt_policy))
 
+# flow offload support
+$(eval $(call nf_add,IPT_FLOW,CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD, $(P_XT)xt_FLOWOFFLOAD))
 
 # IPv6
 
 # kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_REJECT6,CONFIG_NF_REJECT_IPV6, $(P_V6)nf_reject_ipv6),))
+
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT6,CONFIG_IP6_NF_IPTABLES, $(P_V6)ip6_tables),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT6,CONFIG_NF_REJECT_IPV6, $(P_V6)nf_reject_ipv6),))
 
-$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK6,CONFIG_NF_DEFRAG_IPV6, $(P_V6)nf_defrag_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK,CONFIG_NF_DEFRAG_IPV6, $(P_V6)nf_defrag_ipv6, ge 4.19),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK6,CONFIG_NF_DEFRAG_IPV6, $(P_V6)nf_defrag_ipv6, lt 4.19),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK6,CONFIG_NF_CONNTRACK_IPV6, $(P_V6)nf_conntrack_ipv6),))
 
 $(eval $(if $(NF_KMOD),$(call nf_add,IPT_IPV6,CONFIG_IP6_NF_FILTER, $(P_V6)ip6table_filter),))
@@ -172,10 +187,10 @@ $(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_RT, $(P_V6)ip6t_rt))
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT, $(P_XT)nf_nat),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_REDIRECT, $(P_XT)nf_nat_redirect, ge 3.19.0),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_IPV4, $(P_V4)nf_nat_ipv4),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_MASQUERADE_IPV4, $(P_V4)nf_nat_masquerade_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_MASQUERADE_IPV4, $(P_V4)nf_nat_masquerade_ipv4, lt 4.18),))
 
 $(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT6,CONFIG_NF_NAT_IPV6, $(P_V6)nf_nat_ipv6),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT6,CONFIG_NF_NAT_MASQUERADE_IPV6, $(P_V6)nf_nat_masquerade_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT6,CONFIG_NF_NAT_MASQUERADE_IPV6, $(P_V6)nf_nat_masquerade_ipv6, lt 4.18),))
 
 $(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT,CONFIG_NETFILTER_XT_NAT, $(P_XT)xt_nat),))
 $(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT,CONFIG_IP_NF_NAT, $(P_V4)iptable_nat),))
@@ -245,7 +260,11 @@ $(eval $(call nf_add,IPT_DEBUG,CONFIG_NETFILTER_XT_TARGET_TRACE, $(P_XT)xt_TRACE
 # tproxy
 
 $(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_MATCH_SOCKET, $(P_XT)xt_socket))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_SOCKET_IPV4, $(P_V4)nf_socket_ipv4, ge 4.10))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_SOCKET_IPV6, $(P_V6)nf_socket_ipv6, ge 4.10))
 $(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_TARGET_TPROXY, $(P_XT)xt_TPROXY))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_TPROXY_IPV4, $(P_V4)nf_tproxy_ipv4, ge 4.18))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_TPROXY_IPV6, $(P_V6)nf_tproxy_ipv6, ge 4.18))
 
 # led
 $(eval $(call nf_add,IPT_LED,CONFIG_NETFILTER_XT_TARGET_LED, $(P_XT)xt_LED))
@@ -260,6 +279,10 @@ $(eval $(if $(NF_KMOD),$(call nf_add,IPT_TEE,CONFIG_NF_DUP_IPV6, $(P_V6)nf_dup_i
 
 $(eval $(call nf_add,IPT_U32,CONFIG_NETFILTER_XT_MATCH_U32, $(P_XT)xt_u32))
 
+# checksum
+
+$(eval $(call nf_add,IPT_CHECKSUM,CONFIG_NETFILTER_XT_TARGET_CHECKSUM, $(P_XT)xt_CHECKSUM))
+
 
 # netlink
 
@@ -311,31 +334,48 @@ $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFQUEUE, $(P_EBT)ebt_nf
 
 # nftables
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES, $(P_XT)nf_tables),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_INET, $(P_XT)nf_tables_inet),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_INET, $(P_XT)nf_tables_inet, lt 4.17),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_EXTHDR, $(P_XT)nft_exthdr),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_META, $(P_XT)nft_meta),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_NUMGEN, $(P_XT)nft_numgen, ge 4.9.0),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_CT, $(P_XT)nft_ct),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_RBTREE, $(P_XT)nft_rbtree),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_HASH, $(P_XT)nft_hash),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_SET_RBTREE, $(P_XT)nft_set_rbtree, ge 4.9.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_RBTREE, $(P_XT)nft_rbtree, lt 4.9.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_SET_HASH, $(P_XT)nft_set_hash, ge 4.9.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_HASH, $(P_XT)nft_hash, lt 4.9.0),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_COUNTER, $(P_XT)nft_counter),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_LOG, $(P_XT)nft_log),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_LIMIT, $(P_XT)nft_limit),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_REJECT, $(P_XT)nft_reject $(P_V4)nft_reject_ipv4 $(P_V6)nft_reject_ipv6),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_REJECT_INET, $(P_XT)nft_reject_inet),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV4, $(P_V4)nf_tables_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV4, $(P_V4)nf_tables_ipv4, lt 4.17),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_CHAIN_ROUTE_IPV4, $(P_V4)nft_chain_route_ipv4),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV6, $(P_V6)nf_tables_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV6, $(P_V6)nf_tables_ipv6, lt 4.17),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_CHAIN_ROUTE_IPV6, $(P_V6)nft_chain_route_ipv6),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_REDIR, $(P_XT)nft_redir, ge 3.19.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_QUOTA, $(P_XT)nft_quota, ge 4.9.0),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_ARP,CONFIG_NF_TABLES_ARP, $(P_V4)nf_tables_arp, lt 4.17),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_BRIDGE,CONFIG_NF_TABLES_BRIDGE, $(P_EBT)nf_tables_bridge, lt 4.17),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_BRIDGE,CONFIG_NFT_BRIDGE_META, $(P_EBT)nft_meta_bridge),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_BRIDGE,CONFIG_NFT_BRIDGE_REJECT, $(P_EBT)nft_reject_bridge),))
 
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_NAT, $(P_XT)nft_nat),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_CHAIN_NAT_IPV4, $(P_V4)nft_chain_nat_ipv4),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_REDIR_IPV4, $(P_V4)nft_redir_ipv4, ge 3.19.0),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_REDIR_IPV6, $(P_V6)nft_redir_ipv6, ge 3.19.0),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_CHAIN_NAT_IPV6, $(P_V6)nft_chain_nat_ipv6),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_MASQ, $(P_XT)nft_masq),))
 $(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_MASQ_IPV4, $(P_V4)nft_masq_ipv4),))
-$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_MASQ_IPV6, $(P_V6)nft_masq_ipv6),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_REDIR_IPV6, $(P_V6)nft_redir_ipv6, ge 3.19.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_CHAIN_NAT_IPV6, $(P_V6)nft_chain_nat_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_MASQ_IPV6, $(P_V6)nft_masq_ipv6),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB, $(P_XT)nft_fib),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB_INET, $(P_XT)nft_fib_inet),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB_IPV4, $(P_V4)nft_fib_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB_IPV6, $(P_V6)nft_fib_ipv6),))
+
 
 # userland only
 IPT_BUILTIN += $(NF_IPT-y) $(NF_IPT-m)
@@ -345,7 +385,9 @@ IPT_BUILTIN += $(NF_CONNTRACK6-y)
 IPT_BUILTIN += $(IPT_CONNTRACK-y)
 IPT_BUILTIN += $(IPT_CONNTRACK_EXTRA-y)
 IPT_BUILTIN += $(IPT_EXTRA-y)
+IPT_BUILTIN += $(IPT_PHYSDEV-y)
 IPT_BUILTIN += $(IPT_FILTER-y)
+IPT_BUILTIN += $(IPT_FLOW-y) $(IPT_FLOW-m)
 IPT_BUILTIN += $(IPT_IPOPT-y)
 IPT_BUILTIN += $(IPT_IPRANGE-y)
 IPT_BUILTIN += $(IPT_CLUSTER-y)
@@ -360,7 +402,6 @@ IPT_BUILTIN += $(IPT_NAT_EXTRA-y)
 IPT_BUILTIN += $(NF_NATHELPER-y)
 IPT_BUILTIN += $(NF_NATHELPER_EXTRA-y)
 IPT_BUILTIN += $(IPT_ULOG-y)
-IPT_BUILTIN += $(IPT_DEBUG-y)
 IPT_BUILTIN += $(IPT_TPROXY-y)
 IPT_BUILTIN += $(NFNETLINK-y)
 IPT_BUILTIN += $(NFNETLINK_LOG-y)

+ 1 - 1
include/nls.mk

@@ -23,7 +23,7 @@ else
 endif
 
 PKG_CONFIG_DEPENDS += CONFIG_BUILD_NLS
-PKG_BUILD_DEPENDS += !BUILD_NLS:libiconv !BUILD_NLS:libintl
+PKG_BUILD_DEPENDS += !BUILD_NLS:libiconv !BUILD_NLS:gettext
 
 ICONV_DEPENDS:=+BUILD_NLS:libiconv-full
 ICONV_CFLAGS:=-I$(ICONV_PREFIX)/include

+ 14 - 4
include/package-bin.mk

@@ -10,6 +10,7 @@ ifeq ($(DUMP),)
     ifeq ($(if $(VARIANT),$(BUILD_VARIANT)),$(VARIANT))
     ifdef Package/$(1)/install
       ifneq ($(CONFIG_PACKAGE_$(1))$(DEVELOPER),)
+        $(_pkg_target)compile: $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
         compile: install-bin-$(1)
       else
         compile: $(1)-disabled
@@ -19,10 +20,19 @@ ifeq ($(DUMP),)
     endif
     endif
 
-    install-bin-$(1): $(STAMP_BUILT)
-	  rm -rf $(BIN_DIR)/$(1)
-	  $(INSTALL_DIR) $(BIN_DIR)/$(1)
-	  $(call Package/$(1)/install,$(BIN_DIR)/$(1))
+    $(PKG_BUILD_DIR)/.pkgdir/$(1).installed: $(STAMP_BUILT)
+		rm -rf $(PKG_BUILD_DIR)/.pkgdir/$(1) $$@
+		mkdir -p $(PKG_BUILD_DIR)/.pkgdir/$(1)
+		$(call Package/$(1)/install,$(PKG_BUILD_DIR)/.pkgdir/$(1))
+		touch $$@
+
+    install-bin-$(1): $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
+	rm -rf $(BIN_DIR)/$(1)
+	-rmdir $(PKG_BUILD_DIR)/.pkgdir/$(1) >/dev/null 2>/dev/null
+	if [ -d $(PKG_BUILD_DIR)/.pkgdir/$(1) ]; then \
+		$(INSTALL_DIR) $(BIN_DIR)/$(1) && \
+		$(CP) $(PKG_BUILD_DIR)/.pkgdir/$(1)/. $(BIN_DIR)/$(1)/; \
+	fi
 
     clean-$(1):
 	  rm -rf $(BIN_DIR)/$(1)

+ 5 - 3
include/package-defaults.mk

@@ -5,7 +5,7 @@
 # See /LICENSE for more information.
 #
 
-PKG_DEFAULT_DEPENDS = +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread
+PKG_DEFAULT_DEPENDS = +libc +GCC_LIBSSP:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread
 
 ifneq ($(PKG_NAME),toolchain)
   PKG_FIXUP_DEPENDS = $(if $(filter kmod-%,$(1)),$(2),$(PKG_DEFAULT_DEPENDS) $(filter-out $(PKG_DEFAULT_DEPENDS),$(2)))
@@ -56,13 +56,16 @@ define Package/Default
   VARIANT:=
   DEFAULT_VARIANT:=
   USERID:=
+  ALTERNATIVES:=
+  LICENSE:=$(PKG_LICENSE)
+  LICENSE_FILES:=$(PKG_LICENSE_FILES)
 endef
 
 Build/Patch:=$(Build/Patch/Default)
 ifneq ($(strip $(PKG_UNPACK)),)
   define Build/Prepare/Default
 	$(PKG_UNPACK)
-	[ ! -d ./src/ ] || $(CP) ./src/* $(PKG_BUILD_DIR)
+	[ ! -d ./src/ ] || $(CP) ./src/. $(PKG_BUILD_DIR)
 	$(Build/Patch)
   endef
 endif
@@ -92,7 +95,6 @@ CONFIGURE_ARGS = \
 		--mandir=$(CONFIGURE_PREFIX)/man \
 		--infodir=$(CONFIGURE_PREFIX)/info \
 		$(DISABLE_NLS) \
-		$(DISABLE_LARGEFILE) \
 		$(DISABLE_IPV6)
 
 CONFIGURE_VARS = \

+ 15 - 45
include/package-dumpinfo.mk

@@ -7,47 +7,39 @@
 
 ifneq ($(DUMP),)
 
-dumpinfo: FORCE
-
-define Config/template
-Preconfig: $(1)
-Preconfig-Type: $(2)
-Preconfig-Default: $(3)
-Preconfig-Label: $(4)
 
-endef
+define SOURCE_INFO
+$(if $(PKG_BUILD_DEPENDS),Build-Depends: $(PKG_BUILD_DEPENDS)
+)$(if $(HOST_BUILD_DEPENDS),Build-Depends/host: $(HOST_BUILD_DEPENDS)
+)$(if $(BUILD_TYPES),Build-Types: $(BUILD_TYPES)
+)
 
-define Config
-  Preconfig/$(1) = $$(call Config/template,$(1),$(2),$(3),$(4))
-  preconfig_$$(1) += $(1)
 endef
 
 define Dumpinfo/Package
-$(info Package: $(1)
+$(info $(SOURCE_INFO)Package: $(1)
 $(if $(MENU),Menu: $(MENU)
 )$(if $(SUBMENU),Submenu: $(SUBMENU)
 )$(if $(SUBMENUDEP),Submenu-Depends: $(SUBMENUDEP)
 )$(if $(DEFAULT),Default: $(DEFAULT)
 )$(if $(findstring $(PREREQ_CHECK),1),Prereq-Check: 1
 )Version: $(VERSION)
-Depends: $(call PKG_FIXUP_DEPENDS,$(1),$(DEPENDS))
+$(if $(ABI_VERSION),ABIVersion: $(ABI_VERSION)
+)Depends: $(call PKG_FIXUP_DEPENDS,$(1),$(DEPENDS))
 Conflicts: $(CONFLICTS)
 Menu-Depends: $(MDEPENDS)
 Provides: $(PROVIDES)
 $(if $(VARIANT),Build-Variant: $(VARIANT)
 $(if $(DEFAULT_VARIANT),Default-Variant: $(VARIANT)
-))$(if $(PKG_BUILD_DEPENDS),Build-Depends: $(PKG_BUILD_DEPENDS)
-)$(if $(HOST_BUILD_DEPENDS),Build-Depends/host: $(HOST_BUILD_DEPENDS)
-)$(if $(BUILD_TYPES),Build-Types: $(BUILD_TYPES)
-)Section: $(SECTION)
+))Section: $(SECTION)
 Category: $(CATEGORY)
 $(if $(filter nonshared,$(PKGFLAGS)),,Repository: $(if $(FEED),$(FEED),base)
 )Title: $(TITLE)
 Maintainer: $(MAINTAINER)
 $(if $(USERID),Require-User: $(USERID)
 )Source: $(PKG_SOURCE)
-$(if $(PKG_LICENSE),License: $(PKG_LICENSE)
-)$(if $(PKG_LICENSE_FILES),LicenseFiles: $(PKG_LICENSE_FILES)
+$(if $(LICENSE),License: $(LICENSE)
+)$(if $(LICENSE_FILES),LicenseFiles: $(LICENSE_FILES)
 )Type: $(if $(Package/$(1)/targets),$(Package/$(1)/targets),$(if $(PKG_TARGETS),$(PKG_TARGETS),ipkg))
 $(if $(KCONFIG),Kernel-Config: $(KCONFIG)
 )$(if $(BUILDONLY),Build-Only: $(BUILDONLY)
@@ -59,33 +51,11 @@ $(if $(URL),$(URL)
 $(if $(Package/$(1)/config),Config:
 $(Package/$(1)/config)
 @@
-)$(foreach pc,$(preconfig_$(1)),
-$(Preconfig/$(pc))))
+))
+SOURCE_INFO :=
 endef
 
-define Feature/Default
-  TARGET_NAME:=
-  TARGET_TITLE:=
-  PRIORITY:=
-  NAME:=
-endef
-
-define Feature
-  $(eval $(Feature/Default))
-  $(eval $(Feature/$(1)))
-  $(if $(DUMP),$(call Dumpinfo/Feature,$(1)))
-endef
-
-define Dumpinfo/Feature
-$(info Feature: $(TARGET_NAME)_$(1)
-Target-Name: $(TARGET_NAME)
-Target-Title: $(TARGET_TITLE)
-Feature-Name: $(NAME)
-$(if $(PRIORITY),Feature-Priority: $(PRIORITY)
-)Feature-Description:
-$(Feature/$(1)/description)
-@@
-)
-endef
+dumpinfo: FORCE
+	$(if $(SOURCE_INFO),$(info $(SOURCE_INFO)))
 
 endif

+ 46 - 35
include/package-ipkg.mk

@@ -13,6 +13,9 @@ endif
 IPKG_BUILD:= \
   $(SCRIPT_DIR)/ipkg-build -c -o 0 -g 0
 
+IPKG_REMOVE:= \
+  $(SCRIPT_DIR)/ipkg-remove
+
 IPKG_STATE_DIR:=$(TARGET_DIR)/usr/lib/opkg
 
 # 1: package name
@@ -32,7 +35,8 @@ PARENR :=)
 
 dep_split=$(subst :,$(space),$(1))
 dep_rem=$(subst !,,$(subst $(strip $(PARENL)),,$(subst $(strip $(PARENR)),,$(word 1,$(call dep_split,$(1))))))
-dep_confvar=$(strip $(foreach cond,$(subst ||, ,$(call dep_rem,$(1))),$(CONFIG_$(cond))))
+dep_and=dep_and_res:=$$(and $(subst $(space),$(comma),$(foreach cond,$(subst &&, ,$(1)),$$(CONFIG_$(cond)))))
+dep_confvar=$(strip $(foreach cond,$(subst ||, ,$(call dep_rem,$(1))),$(eval $(call dep_and,$(cond)))$(dep_and_res)))
 dep_pos=$(if $(call dep_confvar,$(1)),$(call dep_val,$(1)))
 dep_neg=$(if $(call dep_confvar,$(1)),,$(call dep_val,$(1)))
 dep_if=$(if $(findstring !,$(1)),$(call dep_neg,$(1)),$(call dep_pos,$(1)))
@@ -90,8 +94,9 @@ _endef=endef
 
 ifeq ($(DUMP),)
   define BuildTarget/ipkg
+    ABIV_$(1):=$(call GetABISuffix,$(1))
     PDIR_$(1):=$(call FeedPackageDir,$(1))
-    IPKG_$(1):=$$(PDIR_$(1))/$(1)_$(VERSION)_$(PKGARCH).ipk
+    IPKG_$(1):=$$(PDIR_$(1))/$(1)$$(ABIV_$(1))_$(VERSION)_$(PKGARCH).ipk
     IDIR_$(1):=$(PKG_BUILD_DIR)/ipkg-$(PKGARCH)/$(1)
     KEEP_$(1):=$(strip $(call Package/$(1)/conffiles))
 
@@ -106,25 +111,21 @@ ifeq ($(DUMP),)
     ifdef do_install
       ifneq ($(CONFIG_PACKAGE_$(1))$(DEVELOPER),)
         IPKGS += $(1)
-        compile: $$(IPKG_$(1)) $(PKG_INFO_DIR)/$(1).provides $(STAGING_DIR_ROOT)/stamp/.$(1)_installed
-        ifneq ($(ABI_VERSION),)
-        compile: $(PKG_INFO_DIR)/$(1).version
-        endif
+        $(_pkg_target)compile: $$(IPKG_$(1)) $(PKG_INFO_DIR)/$(1).provides $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
+        prepare-package-install: $$(IPKG_$(1))
+        compile: $(STAGING_DIR_ROOT)/stamp/.$(1)_installed
       else
         $(if $(CONFIG_PACKAGE_$(1)),$$(info WARNING: skipping $(1) -- package not selected))
       endif
 
       .PHONY: $(PKG_INSTALL_STAMP).$(1)
-      compile: $(PKG_INSTALL_STAMP).$(1)
-      $(PKG_INSTALL_STAMP).$(1):
-			if [ -f $(PKG_INSTALL_STAMP).clean ]; then \
-				rm -f \
-					$(PKG_INSTALL_STAMP) \
-					$(PKG_INSTALL_STAMP).clean; \
-			fi
       ifeq ($(CONFIG_PACKAGE_$(1)),y)
-			echo "$(1)" >> $(PKG_INSTALL_STAMP)
+        compile: $(PKG_INSTALL_STAMP).$(1)
       endif
+      $(PKG_INSTALL_STAMP).$(1): prepare-package-install
+		echo "$(1)" >> $(PKG_INSTALL_STAMP)
+    else
+      $(if $(CONFIG_PACKAGE_$(1)),$$(warning WARNING: skipping $(1) -- package has no install section))
     endif
     endif
 
@@ -140,34 +141,36 @@ ifeq ($(DUMP),)
     $(eval $(call BuildIPKGVariable,$(1),prerm,-pkg,1))
     $(eval $(call BuildIPKGVariable,$(1),postrm,,1))
 
-    $(STAGING_DIR_ROOT)/stamp/.$(1)_installed : export PATH=$$(TARGET_PATH_PKG)
-    $(STAGING_DIR_ROOT)/stamp/.$(1)_installed: $(STAMP_BUILT)
-	rm -rf $(STAGING_DIR_ROOT)/tmp-$(1)
-	mkdir -p $(STAGING_DIR_ROOT)/stamp $(STAGING_DIR_ROOT)/tmp-$(1)
-	$(call Package/$(1)/install,$(STAGING_DIR_ROOT)/tmp-$(1))
-	$(call Package/$(1)/install_lib,$(STAGING_DIR_ROOT)/tmp-$(1))
-	$(call locked,$(CP) $(STAGING_DIR_ROOT)/tmp-$(1)/. $(STAGING_DIR_ROOT)/,root-copy)
-	rm -rf $(STAGING_DIR_ROOT)/tmp-$(1)
+    $(PKG_BUILD_DIR)/.pkgdir/$(1).installed : export PATH=$$(TARGET_PATH_PKG)
+    $(PKG_BUILD_DIR)/.pkgdir/$(1).installed: $(STAMP_BUILT)
+	rm -rf $$@ $(PKG_BUILD_DIR)/.pkgdir/$(1)
+	mkdir -p $(PKG_BUILD_DIR)/.pkgdir/$(1)
+	$(call Package/$(1)/install,$(PKG_BUILD_DIR)/.pkgdir/$(1))
+	$(call Package/$(1)/install_lib,$(PKG_BUILD_DIR)/.pkgdir/$(1))
 	touch $$@
 
-    $(PKG_INFO_DIR)/$(1).version: $$(IPKG_$(1))
-	echo '$(ABI_VERSION)' | cmp -s - $$@ || \
-		echo '$(ABI_VERSION)' > $$@
+    $(STAGING_DIR_ROOT)/stamp/.$(1)_installed: $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
+	mkdir -p $(STAGING_DIR_ROOT)/stamp
+	$(if $(ABI_VERSION),echo '$(ABI_VERSION)' | cmp -s - $(PKG_INFO_DIR)/$(1).version || echo '$(ABI_VERSION)' > $(PKG_INFO_DIR)/$(1).version)
+	$(call locked,$(CP) $(PKG_BUILD_DIR)/.pkgdir/$(1)/. $(STAGING_DIR_ROOT)/,root-copy)
+	touch $$@
 
-    Package/$(1)/DEPENDS := $$(call mergelist,$$(filter-out @%,$$(IDEPEND_$(1))))
+    Package/$(1)/DEPENDS := $$(call mergelist,$$(foreach dep,$$(filter-out @%,$$(IDEPEND_$(1))),$$(dep)$$(call GetABISuffix,$$(dep))))
     ifneq ($$(EXTRA_DEPENDS),)
       Package/$(1)/DEPENDS := $$(EXTRA_DEPENDS)$$(if $$(Package/$(1)/DEPENDS),$$(comma) $$(Package/$(1)/DEPENDS))
     endif
 
 $(_define) Package/$(1)/CONTROL
-Package: $(1)
+Package: $(1)$$(ABIV_$(1))
 Version: $(VERSION)
 $$(call addfield,Depends,$$(Package/$(1)/DEPENDS)
 )$$(call addfield,Conflicts,$$(call mergelist,$(CONFLICTS))
-)$$(call addfield,Provides,$$(call mergelist,$(PROVIDES))
+)$$(call addfield,Provides,$$(call mergelist,$$(filter-out $(1)$$(ABIV_$(1)),$(PROVIDES)$$(if $$(ABIV_$(1)), $(1) $(foreach provide,$(PROVIDES),$(provide)$$(call GetABISuffix,$(provide))))))
+)$$(call addfield,Alternatives,$$(call mergelist,$(ALTERNATIVES))
 )$$(call addfield,Source,$(SOURCE)
-)$$(call addfield,License,$$(PKG_LICENSE)
-)$$(call addfield,LicenseFiles,$$(PKG_LICENSE_FILES)
+)$$(call addfield,SourceName,$(1)
+)$$(call addfield,License,$(LICENSE)
+)$$(call addfield,LicenseFiles,$(LICENSE_FILES)
 )$$(call addfield,Section,$(SECTION)
 )$$(call addfield,Require-User,$(USERID)
 )$(if $(filter hold,$(PKG_FLAGS)),Status: unknown hold not-installed
@@ -177,12 +180,11 @@ $$(call addfield,Depends,$$(Package/$(1)/DEPENDS)
 Installed-Size: 0
 $(_endef)
 
-    $(PKG_INFO_DIR)/$(1).provides: $$(IPKG_$(1))
     $$(IPKG_$(1)) : export CONTROL=$$(Package/$(1)/CONTROL)
     $$(IPKG_$(1)) : export DESCRIPTION=$$(Package/$(1)/description)
     $$(IPKG_$(1)) : export PATH=$$(TARGET_PATH_PKG)
-    $$(IPKG_$(1)): $(STAMP_BUILT) $(INCLUDE_DIR)/package-ipkg.mk
-	@rm -rf $$(IDIR_$(1)) $$(call opkg_package_files,$(1))
+    $(PKG_INFO_DIR)/$(1).provides $$(IPKG_$(1)): $(STAMP_BUILT) $(INCLUDE_DIR)/package-ipkg.mk
+	@rm -rf $$(IDIR_$(1)) $$(if $$(call opkg_package_files,$(1)*),; $$(IPKG_REMOVE) $(1) $$(call opkg_package_files,$(1)*))
 	mkdir -p $(PACKAGE_DIR) $$(IDIR_$(1))/CONTROL $(PKG_INFO_DIR)
 	$(call Package/$(1)/install,$$(IDIR_$(1)))
 	$(if $(Package/$(1)/install-overlay),mkdir -p $(PACKAGE_DIR) $$(IDIR_$(1))/rootfs-overlay)
@@ -196,10 +198,19 @@ $(_endef)
 			fi; \
 		done; $(Package/$(1)/extra_provides) \
 	) | sort -u > $(PKG_INFO_DIR)/$(1).provides
-	$(if $(PROVIDES),@for pkg in $(PROVIDES); do cp $(PKG_INFO_DIR)/$(1).provides $(PKG_INFO_DIR)/$$$$pkg.provides; done)
+	$(if $(PROVIDES),@for pkg in $(filter-out $(1),$(PROVIDES)); do cp $(PKG_INFO_DIR)/$(1).provides $(PKG_INFO_DIR)/$$$$pkg.provides; done)
 	$(CheckDependencies)
 
 	$(RSTRIP) $$(IDIR_$(1))
+
+    ifneq ($$(CONFIG_IPK_FILES_CHECKSUMS),)
+	(cd $$(IDIR_$(1)); \
+		( \
+			find . -type f \! -path ./CONTROL/\* -exec sha256sum \{\} \; 2> /dev/null | \
+			sed 's|\([[:blank:]]\)\./|\1/|' > $$(IDIR_$(1))/CONTROL/files-sha256 \
+		) || true \
+	)
+    endif
 	(cd $$(IDIR_$(1))/CONTROL; \
 		( \
 			echo "$$$$CONTROL"; \
@@ -241,7 +252,7 @@ $(_endef)
 	@[ -f $$(IPKG_$(1)) ]
 
     $(1)-clean:
-	$$(if $$(call opkg_package_files,$(1)),rm -f $$(call opkg_package_files,$(1)))
+	$$(if $$(call opkg_package_files,$(1)*),$$(IPKG_REMOVE) $(1) $$(call opkg_package_files,$(1)*))
 
     clean: $(1)-clean
 

+ 96 - 51
include/package.mk

@@ -11,7 +11,7 @@ all: $(if $(DUMP),dumpinfo,$(if $(CHECK),check,compile))
 
 include $(INCLUDE_DIR)/download.mk
 
-PKG_BUILD_DIR ?= $(BUILD_DIR)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
+PKG_BUILD_DIR ?= $(BUILD_DIR)/$(if $(BUILD_VARIANT),$(PKG_NAME)-$(BUILD_VARIANT)/)$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
 PKG_INSTALL_DIR ?= $(PKG_BUILD_DIR)/ipkg-install
 PKG_BUILD_PARALLEL ?=
 PKG_USE_MIPS16 ?= 1
@@ -37,18 +37,46 @@ endif
 
 include $(INCLUDE_DIR)/hardening.mk
 include $(INCLUDE_DIR)/prereq.mk
-include $(INCLUDE_DIR)/host.mk
 include $(INCLUDE_DIR)/unpack.mk
 include $(INCLUDE_DIR)/depends.mk
 
-find_library_dependencies = $(wildcard $(patsubst %,$(STAGING_DIR)/pkginfo/%.version, \
-	$(filter-out $(BUILD_PACKAGES),$(foreach dep, \
-		$(filter-out @%, $(patsubst +%,%,$(1))), \
-		$(if $(findstring :,$(dep)), \
-			$(word 2,$(subst :,$(space),$(dep))), \
-			$(dep) \
-		) \
-	))))
+ifneq ($(wildcard $(TOPDIR)/git-src/$(PKG_NAME)/.git),)
+  USE_GIT_SRC_CHECKOUT:=1
+  QUILT:=1
+endif
+ifneq ($(if $(CONFIG_SRC_TREE_OVERRIDE),$(wildcard ./git-src)),)
+  USE_GIT_TREE:=1
+  QUILT:=1
+endif
+ifdef USE_SOURCE_DIR
+  QUILT:=1
+endif
+ifneq ($(wildcard $(PKG_BUILD_DIR)/.source_dir),)
+  QUILT:=1
+endif
+
+include $(INCLUDE_DIR)/quilt.mk
+
+find_library_dependencies = \
+	$(wildcard $(patsubst %,$(STAGING_DIR)/pkginfo/%.version, \
+		$(sort $(foreach dep4, \
+			$(sort $(foreach dep3, \
+				$(sort $(foreach dep2, \
+					$(sort $(foreach dep1, \
+						$(sort $(foreach dep0, \
+							$(Package/$(1)/depends), \
+							$(Package/$(dep0)/depends) $(dep0) \
+						)), \
+						$(Package/$(dep1)/depends) $(dep1) \
+					)), \
+					$(Package/$(dep2)/depends) $(dep2) \
+				)), \
+				$(Package/$(dep3)/depends) $(dep3) \
+			)), \
+			$(Package/$(dep4)/depends) $(dep4) \
+		)), \
+	))
+
 
 PKG_DIR_NAME:=$(lastword $(subst /,$(space),$(CURDIR)))
 STAMP_NO_AUTOREBUILD=$(wildcard $(PKG_BUILD_DIR)/.no_autorebuild)
@@ -57,7 +85,7 @@ ifneq ($(PREV_STAMP_PREPARED),)
   STAMP_PREPARED:=$(PREV_STAMP_PREPARED)
   CONFIG_AUTOREBUILD:=
 else
-  STAMP_PREPARED=$(PKG_BUILD_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))$(call confvar,$(PKG_PREPARED_DEPENDS)))
+  STAMP_PREPARED=$(PKG_BUILD_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))_$(call confvar,CONFIG_AUTOREMOVE $(PKG_PREPARED_DEPENDS)))
 endif
 STAMP_CONFIGURED=$(PKG_BUILD_DIR)/.configured$(if $(DUMP),,_$(call confvar,$(PKG_CONFIG_DEPENDS)))
 STAMP_CONFIGURED_WILDCARD=$(PKG_BUILD_DIR)/.configured_*
@@ -69,33 +97,25 @@ STAGING_FILES_LIST:=$(PKG_DIR_NAME)$(if $(BUILD_VARIANT),.$(BUILD_VARIANT),).lis
 define CleanStaging
 	rm -f $(STAMP_INSTALLED)
 	@-(\
-		cd "$(STAGING_DIR)"; \
-		if [ -f packages/$(STAGING_FILES_LIST) ]; then \
-			cat packages/$(STAGING_FILES_LIST) | xargs -r rm -f 2>/dev/null; \
+		if [ -f $(STAGING_DIR)/packages/$(STAGING_FILES_LIST) ]; then \
+			$(SCRIPT_DIR)/clean-package.sh \
+				"$(STAGING_DIR)/packages/$(STAGING_FILES_LIST)" \
+				"$(STAGING_DIR)"; \
 		fi; \
 	)
 endef
 
-ifneq ($(if $(CONFIG_SRC_TREE_OVERRIDE),$(wildcard ./git-src)),)
-  USE_GIT_TREE:=1
-  QUILT:=1
-endif
-ifdef USE_SOURCE_DIR
-  QUILT:=1
-endif
-ifneq ($(wildcard $(PKG_BUILD_DIR)/.source_dir),)
-  QUILT:=1
-endif
 
 PKG_INSTALL_STAMP:=$(PKG_INFO_DIR)/$(PKG_DIR_NAME).$(if $(BUILD_VARIANT),$(BUILD_VARIANT),default).install
 
-include $(INCLUDE_DIR)/quilt.mk
 include $(INCLUDE_DIR)/package-defaults.mk
 include $(INCLUDE_DIR)/package-dumpinfo.mk
 include $(INCLUDE_DIR)/package-ipkg.mk
 include $(INCLUDE_DIR)/package-bin.mk
 include $(INCLUDE_DIR)/autotools.mk
 
+_pkg_target:=$(if $(QUILT),,.)
+
 override MAKEFLAGS=
 CONFIG_SITE:=$(INCLUDE_DIR)/site/$(ARCH)
 CUR_MAKEFILE:=$(filter-out Makefile,$(firstword $(MAKEFILE_LIST)))
@@ -113,11 +133,28 @@ ifeq ($(DUMP)$(filter prereq clean refresh update,$(MAKECMDGOALS)),)
   endif
 endif
 
+ifdef USE_GIT_SRC_CHECKOUT
+  define Build/Prepare/Default
+	mkdir -p $(PKG_BUILD_DIR)
+	ln -s $(TOPDIR)/git-src/$(PKG_NAME)/.git $(PKG_BUILD_DIR)/.git
+	( cd $(PKG_BUILD_DIR); \
+		git checkout .; \
+		git submodule update --recursive; \
+		git submodule foreach git config --unset core.worktree; \
+		git submodule foreach git checkout .; \
+	)
+  endef
+endif
 ifdef USE_GIT_TREE
   define Build/Prepare/Default
 	mkdir -p $(PKG_BUILD_DIR)
 	ln -s $(CURDIR)/git-src $(PKG_BUILD_DIR)/.git
-	( cd $(PKG_BUILD_DIR); git checkout .)
+	( cd $(PKG_BUILD_DIR); \
+		git checkout .; \
+		git submodule update --recursive; \
+		git submodule foreach git config --unset core.worktree; \
+		git submodule foreach git checkout .; \
+	)
   endef
 endif
 ifdef USE_SOURCE_DIR
@@ -130,19 +167,23 @@ ifdef USE_SOURCE_DIR
 endif
 
 define Build/Exports/Default
-  $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR)/usr/share/aclocal $$(STAGING_DIR)/usr/share/aclocal-* $$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*),-I $$(p))
+  $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR)/usr/share/aclocal $$(STAGING_DIR)/usr/share/aclocal-* $$(STAGING_DIR_HOSTPKG)/share/aclocal $$(STAGING_DIR_HOSTPKG)/share/aclocal-* $$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*),-I $$(p))
   $(1) : export STAGING_PREFIX=$$(STAGING_DIR)/usr
   $(1) : export PATH=$$(TARGET_PATH_PKG)
   $(1) : export CONFIG_SITE:=$$(CONFIG_SITE)
   $(1) : export PKG_CONFIG_PATH:=$$(PKG_CONFIG_PATH)
   $(1) : export PKG_CONFIG_LIBDIR:=$$(PKG_CONFIG_PATH)
-  $(1) : export CCACHE_DIR:=$(STAGING_DIR)/ccache
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(STAGING_DIR)/ccache)
 endef
 Build/Exports=$(Build/Exports/Default)
 
 define Build/CoreTargets
+  STAMP_PREPARED:=$$(STAMP_PREPARED)
+  STAMP_CONFIGURED:=$$(STAMP_CONFIGURED)
+
   $(if $(QUILT),$(Build/Quilt))
   $(call Build/Autoclean)
+  $(call DefaultTargets)
 
   download:
 	$(foreach hook,$(Hooks/Download),
@@ -153,6 +194,7 @@ define Build/CoreTargets
   $(STAMP_PREPARED): $(STAMP_PREPARED_DEPENDS)
 	@-rm -rf $(PKG_BUILD_DIR)
 	@mkdir -p $(PKG_BUILD_DIR)
+	touch $$@_check
 	$(foreach hook,$(Hooks/Prepare/Pre),$(call $(hook))$(sep))
 	$(Build/Prepare)
 	$(foreach hook,$(Hooks/Prepare/Post),$(call $(hook))$(sep))
@@ -160,15 +202,17 @@ define Build/CoreTargets
 
   $(call Build/Exports,$(STAMP_CONFIGURED))
   $(STAMP_CONFIGURED): $(STAMP_PREPARED) $(STAMP_CONFIGURED_DEPENDS)
+	rm -f $(STAMP_CONFIGURED_WILDCARD)
 	$(CleanStaging)
 	$(foreach hook,$(Hooks/Configure/Pre),$(call $(hook))$(sep))
 	$(Build/Configure)
 	$(foreach hook,$(Hooks/Configure/Post),$(call $(hook))$(sep))
-	rm -f $(STAMP_CONFIGURED_WILDCARD)
 	touch $$@
 
   $(call Build/Exports,$(STAMP_BUILT))
   $(STAMP_BUILT): $(STAMP_CONFIGURED) $(STAMP_BUILT_DEPENDS)
+	rm -f $$@
+	touch $$@_check
 	$(foreach hook,$(Hooks/Compile/Pre),$(call $(hook))$(sep))
 	$(Build/Compile)
 	$(foreach hook,$(Hooks/Compile/Post),$(call $(hook))$(sep))
@@ -203,31 +247,31 @@ define Build/CoreTargets
 	touch $$@
 
   ifdef Build/InstallDev
-    compile: $(STAMP_INSTALLED)
+    $(_pkg_target)compile: $(STAMP_INSTALLED)
   endif
 
-  prepare: $(STAMP_PREPARED)
-  configure: $(STAMP_CONFIGURED)
-  dist: $(STAMP_CONFIGURED)
-  distcheck: $(STAMP_CONFIGURED)
+  $(_pkg_target)prepare: $(STAMP_PREPARED)
+  $(_pkg_target)configure: $(STAMP_CONFIGURED)
+  $(_pkg_target)dist: $(STAMP_CONFIGURED)
+  $(_pkg_target)distcheck: $(STAMP_CONFIGURED)
+
+  ifneq ($(CONFIG_AUTOREMOVE),)
+    compile:
+		-touch -r $(PKG_BUILD_DIR)/.built $(PKG_BUILD_DIR)/.autoremove 2>/dev/null >/dev/null
+		$(FIND) $(PKG_BUILD_DIR) -mindepth 1 -maxdepth 1 -not '(' -type f -and -name '.*' -and -size 0 ')' -and -not -name '.pkgdir' | \
+			$(XARGS) rm -rf
+  endif
 endef
 
 define Build/DefaultTargets
-  $(if $(USE_SOURCE_DIR)$(USE_GIT_TREE),,$(if $(strip $(PKG_SOURCE_URL)),$(call Download,default)))
+  $(if $(USE_SOURCE_DIR)$(USE_GIT_TREE)$(USE_GIT_SRC_CHECKOUT),,$(if $(strip $(PKG_SOURCE_URL)),$(call Download,default)))
   $(if $(DUMP),,$(Build/CoreTargets))
 
   define Build/DefaultTargets
   endef
 endef
 
-define Build/IncludeOverlay
-  $(eval -include $(wildcard $(TOPDIR)/overlay/*/$(PKG_DIR_NAME).mk))
-  define Build/IncludeOverlay
-  endef
-endef
-
 define BuildPackage
-  $(Build/IncludeOverlay)
   $(eval $(Package/Default))
   $(eval $(Package/$(1)))
 
@@ -242,7 +286,7 @@ endef
 endif
 
   BUILD_PACKAGES += $(1)
-  $(STAMP_PREPARED): $$(if $(QUILT)$(DUMP),,$(call find_library_dependencies,$(DEPENDS)))
+  $(STAMP_PREPARED): $$(if $(QUILT)$(DUMP),,$(call find_library_dependencies,$(1)))
 
   $(foreach FIELD, TITLE CATEGORY SECTION VERSION,
     ifeq ($($(FIELD)),)
@@ -281,25 +325,26 @@ Build/DistCheck=$(call Build/DistCheck/Default,)
 .PHONY: prepare-package-install
 prepare-package-install:
 	@mkdir -p $(PKG_INFO_DIR)
-	@touch $(PKG_INSTALL_STAMP).clean
+	@rm -f $(PKG_INSTALL_STAMP)
 	@echo "$(filter-out essential nonshared,$(PKG_FLAGS))" > $(PKG_INSTALL_STAMP).flags
 
 $(PACKAGE_DIR):
 	mkdir -p $@
 
-dumpinfo:
-download:
-prepare:
-configure:
-compile: prepare-package-install
+compile:
+.install: .compile
 install: compile
 
-clean: FORCE
+force-clean-build: FORCE
+	rm -rf $(PKG_BUILD_DIR)
+
+clean-build: $(if $(wildcard $(PKG_BUILD_DIR)/.autoremove),force-clean-build)
+
+clean: force-clean-build
 	$(CleanStaging)
 	$(call Build/UninstallDev,$(STAGING_DIR),$(STAGING_DIR_HOST))
 	$(Build/Clean)
 	rm -f $(STAGING_DIR)/packages/$(STAGING_FILES_LIST) $(STAGING_DIR_HOST)/packages/$(STAGING_FILES_LIST)
-	rm -rf $(PKG_BUILD_DIR)
 
 dist:
 	$(Build/Dist)

+ 33 - 30
include/prereq-build.mk

@@ -7,8 +7,6 @@
 
 include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/prereq.mk
-include $(INCLUDE_DIR)/host.mk
-include $(INCLUDE_DIR)/host-build.mk
 
 SHELL:=sh
 PKG_NAME:=Build dependency
@@ -26,35 +24,43 @@ $(eval $(call TestHostCommand,case-sensitive-fs, \
 
 $(eval $(call TestHostCommand,proper-umask, \
 	Please build with umask 022 - other values produce broken packages, \
-	umask | grep -xE 00[012][012]))
+	umask | grep -xE 0?0[012][012]))
 
 $(eval $(call SetupHostCommand,gcc, \
-	Please install the GNU C Compiler (gcc), \
-	$(CC) --version | grep gcc, \
-	gcc --version | grep gcc, \
-	gcc49 --version | grep gcc, \
+	Please install the GNU C Compiler (gcc) 4.8 or later, \
+	$(CC) -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
+	gcc -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
 	gcc48 --version | grep gcc, \
-	gcc47 --version | grep gcc, \
-	gcc46 --version | grep gcc, \
-	gcc --version | grep Apple.LLVM ))
+	gcc49 --version | grep gcc, \
+	gcc5 --version | grep gcc, \
+	gcc6 --version | grep gcc, \
+	gcc7 --version | grep gcc, \
+	gcc8 --version | grep gcc, \
+	gcc9 --version | grep gcc, \
+	gcc --version | grep -E 'Apple.(LLVM|clang)' ))
 
 $(eval $(call TestHostCommand,working-gcc, \
-	Please reinstall the GNU C Compiler - it appears to be broken, \
+	\nPlease reinstall the GNU C Compiler (4.8 or later) - \
+	it appears to be broken, \
 	echo 'int main(int argc, char **argv) { return 0; }' | \
 		gcc -x c -o $(TMP_DIR)/a.out -))
 
 $(eval $(call SetupHostCommand,g++, \
-	Please install the GNU C++ Compiler (g++), \
-	$(CXX) --version | grep g++, \
-	g++ --version | grep g++, \
-	g++49 --version | grep g++, \
+	Please install the GNU C++ Compiler (g++) 4.8 or later, \
+	$(CXX) -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
+	g++ -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
 	g++48 --version | grep g++, \
-	g++47 --version | grep g++, \
-	g++46 --version | grep g++, \
-	g++ --version | grep Apple.LLVM ))
+	g++49 --version | grep g++, \
+	g++5 --version | grep g++, \
+	g++6 --version | grep g++, \
+	g++7 --version | grep g++, \
+	g++8 --version | grep g++, \
+	g++9 --version | grep g++, \
+	g++ --version | grep -E 'Apple.(LLVM|clang)' ))
 
 $(eval $(call TestHostCommand,working-g++, \
-	Please reinstall the GNU C++ Compiler - it appears to be broken, \
+	\nPlease reinstall the GNU C++ Compiler (4.8 or later) - \
+	it appears to be broken, \
 	echo 'int main(int argc, char **argv) { return 0; }' | \
 		g++ -x c++ -o $(TMP_DIR)/a.out - -lstdc++ && \
 		$(TMP_DIR)/a.out))
@@ -70,11 +76,6 @@ else
   zlib_link_flags := -lz
 endif
 
-$(eval $(call TestHostCommand,zlib, \
-	Please install a static zlib. (Missing libz.a or zlib.h), \
-	echo 'int main(int argc, char **argv) { gzdopen(0, "rb"); return 0; }' | \
-		gcc -include zlib.h -x c -o $(TMP_DIR)/a.out - $(zlib_link_flags)))
-
 $(eval $(call TestHostCommand,perl-thread-queue, \
 	Please install the Perl Thread::Queue module, \
 	perl -MThread::Queue -e 1))
@@ -123,9 +124,9 @@ $(eval $(call SetupHostCommand,getopt, \
 	getopt -o t --long test -- --test | grep '^ *--test *--'))
 
 $(eval $(call SetupHostCommand,stat,Cannot find a file stat utility, \
-	gnustat -c%s $(TMP_DIR)/.host.mk, \
-	gstat -c%s $(TMP_DIR)/.host.mk, \
-	stat -c%s $(TMP_DIR)/.host.mk))
+	gnustat -c%s $(TOPDIR)/Makefile, \
+	gstat -c%s $(TOPDIR)/Makefile, \
+	stat -c%s $(TOPDIR)/Makefile))
 
 $(eval $(call SetupHostCommand,unzip,Please install 'unzip', \
 	unzip 2>&1 | grep zipfile, \
@@ -140,10 +141,12 @@ $(eval $(call SetupHostCommand,wget,Please install GNU 'wget', \
 $(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \
 	perl --version | grep "perl.*v5"))
 
+$(eval $(call CleanupPython3))
+
 $(eval $(call SetupHostCommand,python,Please install Python 2.x, \
-	python2.7 -V 2>&1 | grep Python, \
-	python2 -V 2>&1 | grep Python, \
-	python -V 2>&1 | grep Python))
+	python2.7 -V 2>&1 | grep 'Python 2.7', \
+	python2 -V 2>&1 | grep 'Python 2', \
+	python -V 2>&1 | grep 'Python 2'))
 
 $(eval $(call SetupHostCommand,git,Please install Git (git-core) >= 1.7.12.2, \
 	git --exec-path | xargs -I % -- grep -q -- --recursive %/git-submodule))

+ 14 - 1
include/prereq.mk

@@ -66,6 +66,18 @@ define RequireHeader
   $$(eval $$(call Require,$(1),$(2)))
 endef
 
+define CleanupPython3
+  define Require/python3-cleanup
+	if [ -f "$(STAGING_DIR_HOST)/bin/python" ] && \
+		$(STAGING_DIR_HOST)/bin/python -V 2>&1 | \
+		grep -q 'Python 3'; then \
+			rm $(STAGING_DIR_HOST)/bin/python; \
+	fi
+  endef
+
+  $$(eval $$(call Require,python3-cleanup))
+endef
+
 define QuoteHostCommand
 '$(subst ','"'"',$(strip $(1)))'
 endef
@@ -90,7 +102,8 @@ define SetupHostCommand
 	for cmd in $(call QuoteHostCommand,$(3)) $(call QuoteHostCommand,$(4)) \
 	           $(call QuoteHostCommand,$(5)) $(call QuoteHostCommand,$(6)) \
 	           $(call QuoteHostCommand,$(7)) $(call QuoteHostCommand,$(8)) \
-			   $(call QuoteHostCommand,$(9)); do \
+	           $(call QuoteHostCommand,$(9)) $(call QuoteHostCommand,$(10)) \
+	           $(call QuoteHostCommand,$(11)) $(call QuoteHostCommand,$(12)); do \
 		if [ -n "$$$$$$$$cmd" ]; then \
 			bin="$$$$$$$$(PATH="$(subst $(space),:,$(filter-out $(STAGING_DIR_HOST)/%,$(subst :,$(space),$(PATH))))" \
 				which "$$$$$$$${cmd%% *}")"; \

+ 40 - 29
include/quilt.mk

@@ -4,22 +4,43 @@
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
 
-ifneq ($(if $(DUMP),1,$(__quilt_inc)),1)
-__quilt_inc:=1
-
 ifeq ($(TARGET_BUILD),1)
   PKG_BUILD_DIR:=$(LINUX_DIR)
 endif
-PATCH_DIR?=./patches
-FILES_DIR?=./files
-HOST_PATCH_DIR?=$(PATCH_DIR)
-HOST_FILES_DIR?=$(FILES_DIR)
 
-ifeq ($(MAKECMDGOALS),refresh)
+ifneq ($(filter host-refresh refresh,$(MAKECMDGOALS)),)
   override QUILT=1
   override HOST_QUILT=1
 endif
 
+ifneq ($(PKG_BUILD_DIR),)
+  QUILT?=$(if $(wildcard $(PKG_BUILD_DIR)/.quilt_used),y)
+  ifneq ($(QUILT),)
+    STAMP_CHECKED:=$(PKG_BUILD_DIR)/.quilt_checked
+    override CONFIG_AUTOREBUILD=
+    override CONFIG_AUTOREMOVE=
+    quilt-check: $(STAMP_CHECKED)
+  endif
+endif
+
+ifneq ($(HOST_BUILD_DIR),)
+  HOST_QUILT?=$(if $(findstring command,$(origin QUILT)),$(QUILT),$(if $(wildcard $(HOST_BUILD_DIR)/.quilt_used),y))
+  ifneq ($(HOST_QUILT),)
+    HOST_STAMP_CHECKED:=$(HOST_BUILD_DIR)/.quilt_checked
+    override CONFIG_AUTOREBUILD=
+    override CONFIG_AUTOREMOVE=
+    host-quilt-check: $(HOST_STAMP_CHECKED)
+  endif
+endif
+
+ifneq ($(if $(DUMP),1,$(__quilt_inc)),1)
+__quilt_inc:=1
+
+PATCH_DIR?=./patches
+FILES_DIR?=./files
+HOST_PATCH_DIR?=$(PATCH_DIR)
+HOST_FILES_DIR?=$(FILES_DIR)
+
 QUILT_CMD:=quilt --quiltrc=-
 
 define filter_series
@@ -59,24 +80,6 @@ define HostPatchDir
 $(call PatchDir/$(if $(strip $(HOST_QUILT)),Quilt,Default),$(strip $(1)),$(strip $(2)),$(strip $(3)))
 endef
 
-ifneq ($(PKG_BUILD_DIR),)
-  QUILT?=$(if $(wildcard $(PKG_BUILD_DIR)/.quilt_used),y)
-  ifneq ($(QUILT),)
-    STAMP_CHECKED:=$(PKG_BUILD_DIR)/.quilt_checked
-    override CONFIG_AUTOREBUILD=
-    quilt-check: $(STAMP_CHECKED)
-  endif
-endif
-
-ifneq ($(HOST_BUILD_DIR),)
-  HOST_QUILT?=$(if $(findstring command,$(origin QUILT)),$(QUILT),$(if $(wildcard $(HOST_BUILD_DIR)/.quilt_used),y))
-  ifneq ($(HOST_QUILT),)
-    HOST_STAMP_CHECKED:=$(HOST_BUILD_DIR)/.quilt_checked
-    override CONFIG_AUTOREBUILD=
-    host-quilt-check: $(HOST_STAMP_CHECKED)
-  endif
-endif
-
 define Host/Patch/Default
 	$(if $(HOST_QUILT),rm -rf $(HOST_BUILD_DIR)/patches; mkdir -p $(HOST_BUILD_DIR)/patches)
 	$(call HostPatchDir,$(HOST_BUILD_DIR),$(HOST_PATCH_DIR),)
@@ -91,11 +94,17 @@ endef
 
 kernel_files=$(foreach fdir,$(GENERIC_FILES_DIR) $(FILES_DIR),$(fdir)/.)
 define Kernel/Patch/Default
-	$(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches)
+	$(if $(QUILT),rm -rf $(LINUX_DIR)/patches; mkdir -p $(LINUX_DIR)/patches)
 	$(if $(kernel_files),$(CP) $(kernel_files) $(LINUX_DIR)/)
 	find $(LINUX_DIR)/ -name \*.rej -or -name \*.orig | $(XARGS) rm -f
-	$(call PatchDir,$(PKG_BUILD_DIR),$(GENERIC_PATCH_DIR),generic/)
-	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR),platform/)
+	if [ -d $(GENERIC_PLATFORM_DIR)/patches$(if $(wildcard $(GENERIC_PLATFORM_DIR)/patches-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) ]; then \
+		echo "generic patches directory is present. please move your patches to the pending directory" ; \
+		exit 1; \
+	fi
+	$(call PatchDir,$(LINUX_DIR),$(GENERIC_BACKPORT_DIR),generic-backport/)
+	$(call PatchDir,$(LINUX_DIR),$(GENERIC_PATCH_DIR),generic/)
+	$(call PatchDir,$(LINUX_DIR),$(GENERIC_HACK_DIR),generic-hack/)
+	$(call PatchDir,$(LINUX_DIR),$(PATCH_DIR),platform/)
 endef
 
 define Quilt/RefreshDir
@@ -121,7 +130,9 @@ define Quilt/Refresh/Kernel
 		echo "All kernel patches must start with either generic/ or platform/"; \
 		false; \
 	}
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_BACKPORT_DIR),generic-backport/)
 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_PATCH_DIR),generic/)
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_HACK_DIR),generic-hack/)
 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR),platform/)
 endef
 

+ 22 - 8
include/rootfs.mk

@@ -1,5 +1,3 @@
-include $(INCLUDE_DIR)/feeds.mk
-
 ifdef CONFIG_USE_MKLIBS
   define mklibs
 	rm -rf $(TMP_DIR)/mklibs-progs $(TMP_DIR)/mklibs-out
@@ -49,17 +47,25 @@ TARGET_DIR_ORIG := $(TARGET_ROOTFS_DIR)/root.orig-$(BOARD)
 
 ifdef CONFIG_CLEAN_IPKG
   define clean_ipkg
-	-find $(1)/usr/lib/opkg -type f -and -not -name '*.control' | $(XARGS) rm -rf
+	-find $(1)/usr/lib/opkg/info -type f -and -not -name '*.control' | $(XARGS) rm -rf
 	-sed -i -ne '/^Require-User: /p' $(1)/usr/lib/opkg/info/*.control
+	awk ' \
+		BEGIN { conffiles = 0; print "Conffiles:" } \
+		/^Conffiles:/ { conffiles = 1; next } \
+		!/^ / { conffiles = 0; next } \
+		conffiles == 1 { print } \
+	' $(1)/usr/lib/opkg/status >$(1)/usr/lib/opkg/status.new
+	mv $(1)/usr/lib/opkg/status.new $(1)/usr/lib/opkg/status
 	-find $(1)/usr/lib/opkg -empty | $(XARGS) rm -rf
   endef
 endif
 
 define prepare_rootfs
-	@if [ -d $(TOPDIR)/files ]; then \
-		$(call file_copy,$(TOPDIR)/files/.,$(1)); \
-	fi
+	$(if $(2),@if [ -d '$(2)' ]; then \
+		$(call file_copy,$(2)/.,$(1)); \
+	fi)
 	@mkdir -p $(1)/etc/rc.d
+	@mkdir -p $(1)/var/lock
 	@( \
 		cd $(1); \
 		for script in ./usr/lib/opkg/info/*.postinst; do \
@@ -72,7 +78,13 @@ define prepare_rootfs
 		done; \
 		for script in ./etc/init.d/*; do \
 			grep '#!/bin/sh /etc/rc.common' $$script >/dev/null || continue; \
-			IPKG_INSTROOT=$(1) $$(which bash) ./etc/rc.common $$script enable; \
+			if ! echo " $(3) " | grep -q " $$(basename $$script) "; then \
+				IPKG_INSTROOT=$(1) $$(which bash) ./etc/rc.common $$script enable; \
+				echo "Enabling" $$(basename $$script); \
+			else \
+				IPKG_INSTROOT=$(1) $$(which bash) ./etc/rc.common $$script disable; \
+				echo "Disabling" $$(basename $$script); \
+			fi; \
 		done || true \
 	)
 	$(if $(SOURCE_DATE_EPOCH),sed -i "s/Installed-Time: .*/Installed-Time: $(SOURCE_DATE_EPOCH)/" $(1)/usr/lib/opkg/status)
@@ -80,9 +92,11 @@ define prepare_rootfs
 	@-find $(1) -name .svn  | $(XARGS) rm -rf
 	@-find $(1) -name .git  | $(XARGS) rm -rf
 	@-find $(1) -name '.#*' | $(XARGS) rm -f
+	rm -rf $(1)/tmp/*
 	rm -f $(1)/usr/lib/opkg/lists/*
 	rm -f $(1)/usr/lib/opkg/info/*.postinst*
-	rm -f $(1)/usr/lib/opkg/info/*.prerm*
+	rm -f $(1)/var/lock/*.lock
+	rm -rf $(1)/boot
 	$(call clean_ipkg,$(1))
 	$(call mklibs,$(1))
 endef

+ 1 - 1
include/scan.awk

@@ -2,7 +2,7 @@ BEGIN { FS="/" }
 $1 ~ /^feeds/ { FEEDS[$NF]=$0 }
 $1 !~ /^feeds/ { PKGS[$NF]=$0 }
 END {
-	# Filter-out OpenWrt packages which have a feeds equivalent
+	# Filter-out libreCMC packages which have a feeds equivalent
 	for (pkg in PKGS)
 		if (pkg in FEEDS) {
 			print PKGS[pkg] > of

+ 17 - 5
include/scan.mk

@@ -3,8 +3,6 @@ TMP_DIR:=$(TOPDIR)/tmp
 
 all: $(TMP_DIR)/.$(SCAN_TARGET)
 
-include $(TOPDIR)/include/host.mk
-
 SCAN_TARGET ?= packageinfo
 SCAN_NAME ?= package
 SCAN_DIR ?= package
@@ -12,10 +10,24 @@ TARGET_STAMP:=$(TMP_DIR)/info/.files-$(SCAN_TARGET).stamp
 FILELIST:=$(TMP_DIR)/info/.files-$(SCAN_TARGET)-$(SCAN_COOKIE)
 OVERRIDELIST:=$(TMP_DIR)/info/.overrides-$(SCAN_TARGET)-$(SCAN_COOKIE)
 
+export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
+
+ifeq ($(SCAN_NAME),target)
+  SCAN_DEPS=image/Makefile profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk image/*.mk
+else
+  SCAN_DEPS=$(TOPDIR)/include/package*.mk
+endif
+
 ifeq ($(IS_TTY),1)
-  define progress
+  ifneq ($(strip $(NO_COLOR)),1)
+    define progress
 	printf "\033[M\r$(1)" >&2;
-  endef
+    endef
+  else
+    define progress
+	printf "\r$(1)" >&2;
+    endef
+  endif
 else
   define progress
 	:;
@@ -56,7 +68,7 @@ endif
 
 $(FILELIST): $(OVERRIDELIST)
 	rm -f $(TMP_DIR)/info/.files-$(SCAN_TARGET)-*
-	$(call FIND_L, $(SCAN_DIR)) $(SCAN_EXTRA) -mindepth 1 $(if $(SCAN_DEPTH),-maxdepth $(SCAN_DEPTH)) -name Makefile | xargs grep -aHE 'call $(GREP_STRING)' | sed -e 's#^$(SCAN_DIR)/##' -e 's#/Makefile:.*##' | uniq | awk -v of=$(OVERRIDELIST) -f include/scan.awk > $@
+	find -L $(SCAN_DIR) $(SCAN_EXTRA) -mindepth 1 $(if $(SCAN_DEPTH),-maxdepth $(SCAN_DEPTH)) -name Makefile | xargs grep -aHE 'call $(GREP_STRING)' | sed -e 's#^$(SCAN_DIR)/##' -e 's#/Makefile:.*##' | uniq | awk -v of=$(OVERRIDELIST) -f include/scan.awk > $@
 
 $(TMP_DIR)/info/.files-$(SCAN_TARGET).mk: $(FILELIST)
 	( \

+ 26 - 0
include/site/powerpc64

@@ -0,0 +1,26 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof_char=1
+ac_cv_sizeof_char_p=8
+ac_cv_sizeof_double=8
+ac_cv_sizeof_float=4
+ac_cv_sizeof_int=4
+ac_cv_sizeof_long=8
+ac_cv_sizeof_long_double=16
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long_long_int=8
+ac_cv_sizeof_short=2
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_signed_char=1
+ac_cv_sizeof_unsigned_char=1
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_int=8
+ac_cv_sizeof_unsigned_long_long_int=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_unsigned_short_int=2
+ac_cv_sizeof_void_p=8

+ 23 - 8
include/subdir.mk

@@ -9,7 +9,7 @@ ifeq ($(MAKECMDGOALS),prereq)
   SUBTARGETS:=prereq
   PREREQ_ONLY:=1
 else
-  SUBTARGETS:=clean download prepare compile install update refresh prereq dist distcheck configure check
+  SUBTARGETS:=$(DEFAULT_SUBDIR_TARGETS)
 endif
 
 subtarget-default = $(filter-out ., \
@@ -29,6 +29,11 @@ endef
 lastdir=$(word $(words $(subst /, ,$(1))),$(subst /, ,$(1)))
 diralias=$(if $(findstring $(1),$(call lastdir,$(1))),,$(call lastdir,$(1)))
 
+subdir_make_opts = \
+	-r -C $(1) \
+		BUILD_SUBDIR="$(1)" \
+		BUILD_VARIANT="$(4)"
+
 # 1: subdir
 # 2: target
 # 3: build type
@@ -38,26 +43,36 @@ log_make = \
 	 $(if $(BUILD_LOG), \
 		set -o pipefail; \
 		mkdir -p $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4));) \
-	$$(SUBMAKE) -r -C $(1) $(if $(3),$(3)-)$(2) \
-		BUILD_SUBDIR="$(1)" \
-		BUILD_VARIANT="$(4)" \
+	$(SCRIPT_DIR)/time.pl "time: $(1)$(if $(4),/$(4))/$(if $(3),$(3)-)$(2)" \
+	$$(SUBMAKE) $(subdir_make_opts) $(if $(3),$(3)-)$(2) \
 		$(if $(BUILD_LOG),SILENT= 2>&1 | tee $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4))/$(if $(3),$(3)-)$(2).txt)
 
+ifdef CONFIG_AUTOREMOVE
+rebuild_check = \
+	@-$$(NO_TRACE_MAKE) $(subdir_make_opts) check-depends >/dev/null 2>/dev/null; \
+		$(if $(BUILD_LOG),mkdir -p $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4));) \
+		$$(NO_TRACE_MAKE) $(if $(BUILD_LOG),-d) -q $(subdir_make_opts) .$(if $(3),$(3)-)$(2) \
+			> $(if $(BUILD_LOG),$(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4))/check-$(if $(3),$(3)-)$(2).txt,/dev/null) 2>&1 || \
+			$$(SUBMAKE) $(subdir_make_opts) clean-build >/dev/null 2>/dev/null
+
+endif
+
 # Parameters: <subdir>
 define subdir
   $(call warn,$(1),d,D $(1))
   $(foreach bd,$($(1)/builddirs),
     $(call warn,$(1),d,BD $(1)/$(bd))
-    $(foreach target,$(SUBTARGETS),
+    $(foreach target,$(SUBTARGETS) $($(1)/subtargets),
       $(foreach btype,$(buildtypes-$(bd)),
-        $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(btype)/$(target)) $(call $(1)//$(btype)/$(target),$(1)/$(bd)/$(btype))))
+        $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(NO_DEPS)$(QUILT),,$($(1)/$(bd)/$(btype)/$(target)) $(call $(1)//$(btype)/$(target),$(1)/$(bd)/$(btype))))
 		  $(call log_make,$(1)/$(bd),$(target),$(btype),$(filter-out __default,$(variant))) \
 			$(if $(findstring $(bd),$($(1)/builddirs-ignore-$(btype)-$(target))), || $(call ERROR,$(1),   ERROR: $(1)/$(bd) [$(btype)] failed to build.))
         $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(btype)/$(target): $(1)/$(bd)/$(btype)/$(target)))
       )
-      $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(target)) $(call $(1)//$(target),$(1)/$(bd))))
+      $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(NO_DEPS)$(QUILT),,$($(1)/$(bd)/$(target)) $(call $(1)//$(target),$(1)/$(bd))))
         $(foreach variant,$(if $(BUILD_VARIANT),$(BUILD_VARIANT),$(if $(strip $($(1)/$(bd)/variants)),$($(1)/$(bd)/variants),$(if $($(1)/$(bd)/default-variant),$($(1)/$(bd)/default-variant),__default))),
 			$(if $(BUILD_LOG),@mkdir -p $(BUILD_LOG_DIR)/$(1)/$(bd)/$(filter-out __default,$(variant)))
+			$(if $($(1)/autoremove),$(call rebuild_check,$(1)/$(bd),$(target),,$(filter-out __default,$(variant))))
 			$(call log_make,$(1)/$(bd),$(target),,$(filter-out __default,$(variant))) \
 				$(if $(findstring $(bd),$($(1)/builddirs-ignore-$(target))), || $(call ERROR,$(1),   ERROR: $(1)/$(bd) failed to build$(if $(filter-out __default,$(variant)), (build variant: $(variant))).))
         )
@@ -67,7 +82,7 @@ define subdir
 	  )
 	)
   )
-  $(foreach target,$(SUBTARGETS),$(call subtarget,$(1),$(target)))
+  $(foreach target,$(SUBTARGETS) $($(1)/subtargets),$(call subtarget,$(1),$(target)))
 endef
 
 ifndef DUMP_TARGET_DB

+ 29 - 28
include/target.mk

@@ -13,11 +13,11 @@ __target_inc=1
 DEVICE_TYPE?=router
 
 # Default packages - the really basic set
-DEFAULT_PACKAGES:=base-files ca-bundle libmbedtls libustream-mbedtls libc libgcc busybox dropbear mtd uci opkg netifd fstools uclient-fetch logd
+DEFAULT_PACKAGES:=base-files ca-bundle libmbedtls libustream-mbedtls libc libgcc busybox dropbear mtd uci opkg netifd fstools uclient-fetch logd urandom-seed urngd
 # For nas targets
 DEFAULT_PACKAGES.nas:=block-mount fdisk lsblk mdadm
 # For router targets
-DEFAULT_PACKAGES.router:=dnsmasq iptables ip6tables ppp ppp-mod-pppoe ppp-mod-pppoa firewall odhcpd odhcp6c
+DEFAULT_PACKAGES.router:=dnsmasq iptables ip6tables ppp ppp-mod-pppoe firewall odhcpd-ipv6only odhcp6c kmod-ipt-offload
 DEFAULT_PACKAGES.bootloader:=
 
 ifneq ($(DUMP),)
@@ -51,11 +51,15 @@ else
   endif
 endif
 
+ifneq ($(filter 4.9,$(KERNEL_PATCHVER)),)
+  DEFAULT_PACKAGES.router:=$(filter-out kmod-ipt-offload,$(DEFAULT_PACKAGES.router))
+endif
+
 # Add device specific packages (here below to allow device type set from subtarget)
 DEFAULT_PACKAGES += $(DEFAULT_PACKAGES.$(DEVICE_TYPE))
 
 filter_packages = $(filter-out -% $(patsubst -%,%,$(filter -%,$(1))),$(1))
-extra_packages = $(if $(filter wpad-mini wpad nas,$(1)),iwinfo)
+extra_packages = $(if $(filter wpad-mini wpad-basic wpad nas,$(1)),iwinfo)
 
 define ProfileDefault
   NAME:=
@@ -68,6 +72,7 @@ define Profile
   $(eval $(call ProfileDefault))
   $(eval $(call Profile/$(1)))
   dumpinfo : $(call shexport,Profile/$(1)/Description)
+  PACKAGES := $(filter-out -%,$(PACKAGES))
   DUMPINFO += \
 	echo "Target-Profile: $(1)"; \
 	$(if $(PRIORITY), echo "Target-Profile-Priority: $(PRIORITY)"; ) \
@@ -104,7 +109,9 @@ ifneq ($(TARGET_BUILD)$(if $(DUMP),,1),)
 endif
 
 GENERIC_PLATFORM_DIR := $(TOPDIR)/target/linux/generic
-GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/patches$(if $(wildcard $(GENERIC_PLATFORM_DIR)/patches-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+GENERIC_BACKPORT_DIR := $(GENERIC_PLATFORM_DIR)/backport$(if $(wildcard $(GENERIC_PLATFORM_DIR)/backport-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/pending$(if $(wildcard $(GENERIC_PLATFORM_DIR)/pending-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+GENERIC_HACK_DIR := $(GENERIC_PLATFORM_DIR)/hack$(if $(wildcard $(GENERIC_PLATFORM_DIR)/hack-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
 GENERIC_FILES_DIR := $(foreach dir,$(wildcard $(GENERIC_PLATFORM_DIR)/files $(GENERIC_PLATFORM_DIR)/files-$(KERNEL_PATCHVER)),"$(dir)")
 
 __config_name_list = $(1)/config-$(KERNEL_PATCHVER) $(1)/config-default
@@ -167,7 +174,7 @@ ifeq ($(DUMP),1)
     CPU_CFLAGS_mips64 = -mips64 -mtune=mips64 -mabi=64
     CPU_CFLAGS_24kc = -mips32r2 -mtune=24kc
     CPU_CFLAGS_74kc = -mips32r2 -mtune=74kc
-    CPU_CFLAGS_octeon = -march=octeon -mabi=64
+    CPU_CFLAGS_octeonplus = -march=octeon+ -mabi=64
   endif
   ifeq ($(ARCH),i386)
     CPU_TYPE ?= pentium
@@ -176,25 +183,6 @@ ifeq ($(DUMP),1)
   endif
   ifneq ($(findstring arm,$(ARCH)),)
     CPU_TYPE ?= xscale
-    CPU_CFLAGS_arm920t = -mcpu=arm920t
-    CPU_CFLAGS_arm926ej-s = -mcpu=arm926ej-s
-    CPU_CFLAGS_arm1136j-s = -mcpu=arm1136j-s
-    CPU_CFLAGS_arm1176jzf-s = -mcpu=arm1176jzf-s
-    CPU_CFLAGS_cortex-a5 = -mcpu=cortex-a5
-    CPU_CFLAGS_cortex-a7 = -mcpu=cortex-a7
-    CPU_CFLAGS_cortex-a8 = -mcpu=cortex-a8
-    CPU_CFLAGS_cortex-a9 = -mcpu=cortex-a9
-    CPU_CFLAGS_cortex-a15 = -mcpu=cortex-a15
-    CPU_CFLAGS_cortex-a53 = -mcpu=cortex-a53
-    CPU_CFLAGS_fa526 = -mcpu=fa526
-    CPU_CFLAGS_mpcore = -mcpu=mpcore
-    CPU_CFLAGS_xscale = -mcpu=xscale
-    ifeq ($(CONFIG_SOFT_FLOAT),)
-      CPU_CFLAGS_neon = -mfpu=neon
-      CPU_CFLAGS_vfp = -mfpu=vfp
-      CPU_CFLAGS_vfpv3 = -mfpu=vfpv3-d16
-      CPU_CFLAGS_neon-vfpv4 = -mfpu=neon-vfpv4
-    endif
   endif
   ifeq ($(ARCH),powerpc)
     CPU_CFLAGS_603e:=-mcpu=603e
@@ -203,20 +191,29 @@ ifeq ($(DUMP),1)
     CPU_CFLAGS_440:=-mcpu=440
     CPU_CFLAGS_464fp:=-mcpu=464fp
   endif
+  ifeq ($(ARCH),powerpc64)
+    CPU_TYPE ?= powerpc64
+    CPU_CFLAGS_powerpc64:=-mcpu=powerpc64
+  endif
   ifeq ($(ARCH),sparc)
     CPU_TYPE = sparc
     CPU_CFLAGS_ultrasparc = -mcpu=ultrasparc
   endif
   ifeq ($(ARCH),aarch64)
-    CPU_TYPE ?= armv8-a
-    CPU_CFLAGS_armv8-a = -mcpu=armv8-a
+    CPU_TYPE ?= generic
+    CPU_CFLAGS_generic = -mcpu=generic
     CPU_CFLAGS_cortex-a53 = -mcpu=cortex-a53
   endif
   ifeq ($(ARCH),arc)
     CPU_TYPE ?= arc700
     CPU_CFLAGS += -matomic
-    CPU_CFLAGS_arc700 = -marc700
-    CPU_CFLAGS_archs = -marchs
+    CPU_CFLAGS_arc700 = -mcpu=arc700
+    CPU_CFLAGS_archs = -mcpu=archs
+  endif
+  ifneq ($(CPU_TYPE),)
+    ifndef CPU_CFLAGS_$(CPU_TYPE)
+      $(warning CPU_TYPE "$(CPU_TYPE)" doesn't correspond to a known type)
+    endif
   endif
   DEFAULT_CFLAGS=$(strip $(CPU_CFLAGS) $(CPU_CFLAGS_$(CPU_TYPE)) $(CPU_CFLAGS_$(CPU_SUBTYPE)))
 
@@ -228,6 +225,9 @@ ifeq ($(DUMP),1)
     .SILENT: $(TMP_CONFIG)
     .PRECIOUS: $(TMP_CONFIG)
 
+    ifdef KERNEL_TESTING_PATCHVER
+      FEATURES += testing-kernel
+    endif
     ifneq ($(CONFIG_OF),)
       FEATURES += dt
     endif
@@ -286,6 +286,7 @@ define BuildTargets/DumpCurrent
 	 echo 'Target-Optimization: $(if $(CFLAGS),$(CFLAGS),$(DEFAULT_CFLAGS))'; \
 	 echo 'CPU-Type: $(CPU_TYPE)$(if $(CPU_SUBTYPE),+$(CPU_SUBTYPE))'; \
 	 echo 'Linux-Version: $(LINUX_VERSION)'; \
+	$(if $(LINUX_TESTING_VERSION),echo 'Linux-Testing-Version: $(LINUX_TESTING_VERSION)';) \
 	 echo 'Linux-Release: $(LINUX_RELEASE)'; \
 	 echo 'Linux-Kernel-Arch: $(LINUX_KARCH)'; \
 	$(if $(SUBTARGET),,$(if $(DEFAULT_SUBTARGET), echo 'Default-Subtarget: $(DEFAULT_SUBTARGET)'; )) \

+ 3 - 2
include/toolchain-build.mk

@@ -6,12 +6,13 @@
 #
 
 override CONFIG_AUTOREBUILD=
+override CONFIG_AUTOREMOVE=
 
-REAL_STAGING_DIR_HOST:=$(STAGING_DIR_HOST)
-STAGING_DIR_HOST:=$(TOOLCHAIN_DIR)
+HOST_BUILD_PREFIX:=$(TOOLCHAIN_DIR)
 BUILD_DIR_HOST:=$(BUILD_DIR_TOOLCHAIN)
 
 include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/hardening.mk
 
 HOST_STAMP_PREPARED=$(HOST_BUILD_DIR)/.prepared
 

+ 45 - 18
include/toplevel.mk

@@ -1,4 +1,4 @@
-# Makefile for OpenWrt
+# Makefile for libreCMC
 #
 # Copyright (C) 2007-2012 OpenWrt.org
 #
@@ -6,7 +6,7 @@
 # See /LICENSE for more information.
 #
 
-PREP_MK= OPENWRT_BUILD= QUIET=0
+PREP_MK= LIBRECMC_BUILD= QUIET=0
 
 export IS_TTY=$(shell tty -s && echo 1 || echo 0)
 
@@ -25,6 +25,9 @@ export SOURCE_DATE_EPOCH
 export GIT_CONFIG_PARAMETERS='core.autocrlf=false'
 export GIT_ASKPASS:=/bin/true
 export MAKE_JOBSERVER=$(filter --jobserver%,$(MAKEFLAGS))
+export GNU_HOST_NAME:=$(shell $(TOPDIR)/scripts/config.guess)
+export HOST_OS:=$(shell uname)
+export HOST_ARCH:=$(shell uname -m)
 
 # prevent perforce from messing with the patch utility
 unexport P4PORT P4USER P4CONFIG P4CLIENT
@@ -79,41 +82,51 @@ _ignore = $(foreach p,$(IGNORE_PACKAGES),--ignore $(p))
 prepare-tmpinfo: FORCE
 	@+$(MAKE) -r -s staging_dir/host/.prereq-build $(PREP_MK)
 	mkdir -p tmp/info
-	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/include/package*.mk $(TOPDIR)/overlay/*/*.mk" SCAN_DEPTH=5 SCAN_EXTRA=""
-	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPS="image/Makefile profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
+	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPTH=5 SCAN_EXTRA=""
+	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
 	for type in package target; do \
 		f=tmp/.$${type}info; t=tmp/.config-$${type}.in; \
 		[ "$$t" -nt "$$f" ] || ./scripts/$${type}-metadata.pl $(_ignore) config "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \
 	done
-	[ tmp/.config-feeds.in -nt tmp/.packagesubdirs ] || ./scripts/feeds feed_config > tmp/.config-feeds.in
+	[ tmp/.config-feeds.in -nt tmp/.packageauxvars ] || ./scripts/feeds feed_config > tmp/.config-feeds.in
 	./scripts/package-metadata.pl mk tmp/.packageinfo > tmp/.packagedeps || { rm -f tmp/.packagedeps; false; }
-	./scripts/package-metadata.pl subdirs tmp/.packageinfo > tmp/.packagesubdirs || { rm -f tmp/.packagesubdirs; false; }
+	./scripts/package-metadata.pl pkgaux tmp/.packageinfo > tmp/.packageauxvars || { rm -f tmp/.packageauxvars; false; }
 	touch $(TOPDIR)/tmp/.build
 
 .config: ./scripts/config/conf $(if $(CONFIG_HAVE_DOT_CONFIG),,prepare-tmpinfo)
 	@+if [ \! -e .config ] || ! grep CONFIG_HAVE_DOT_CONFIG .config >/dev/null; then \
-		[ -e $(HOME)/.openwrt/defconfig ] && cp $(HOME)/.openwrt/defconfig .config; \
+		[ -e $(HOME)/.librecmc/defconfig ] && cp $(HOME)/.librecmc/defconfig .config; \
 		$(_SINGLE)$(NO_TRACE_MAKE) menuconfig $(PREP_MK); \
 	fi
 
+ifneq ($(DISTRO_PKG_CONFIG),)
+scripts/config/mconf: export PATH:=$(dir $(DISTRO_PKG_CONFIG)):$(PATH)
+endif
 scripts/config/mconf:
 	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config all CC="$(HOSTCC_WRAPPER)"
 
 $(eval $(call rdep,scripts/config,scripts/config/mconf))
 
+scripts/config/qconf:
+	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config qconf \
+		CC="$(HOSTCC_WRAPPER)" \
+		DISTRO-PKG-CONFIG="$(DISTRO_PKG_CONFIG)"
+
 scripts/config/conf:
 	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config conf CC="$(HOSTCC_WRAPPER)"
 
 config: scripts/config/conf prepare-tmpinfo FORCE
-	$< Config.in
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< Config.in
 
 config-clean: FORCE
 	$(_SINGLE)$(NO_TRACE_MAKE) -C scripts/config clean
 
 defconfig: scripts/config/conf prepare-tmpinfo FORCE
 	touch .config
-	@if [ ! -s .config -a -e $(HOME)/.openwrt/defconfig ]; then cp $(HOME)/.openwrt/defconfig .config; fi
-	$< --defconfig=.config Config.in
+	@if [ ! -s .config -a -e $(HOME)/.librecmc/defconfig ]; then cp $(HOME)/.librecmc/defconfig .config; fi
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< --defconfig=.config Config.in
 
 confdefault-y=allyes
 confdefault-m=allmod
@@ -121,19 +134,27 @@ confdefault-n=allno
 confdefault:=$(confdefault-$(CONFDEFAULT))
 
 oldconfig: scripts/config/conf prepare-tmpinfo FORCE
-	$< --$(if $(confdefault),$(confdefault),old)config Config.in
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< --$(if $(confdefault),$(confdefault),old)config Config.in
 
 menuconfig: scripts/config/mconf prepare-tmpinfo FORCE
-	if [ \! -e .config -a -e $(HOME)/.openwrt/defconfig ]; then \
-		cp $(HOME)/.openwrt/defconfig .config; \
+	if [ \! -e .config -a -e $(HOME)/.librecmc/defconfig ]; then \
+		cp $(HOME)/.librecmc/defconfig .config; \
 	fi
-	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; $< Config.in
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< Config.in
+
+xconfig: scripts/config/qconf prepare-tmpinfo FORCE
+	if [ \! -e .config -a -e $(HOME)/.librecmc/defconfig ]; then \
+		cp $(HOME)/.librecmc/defconfig .config; \
+	fi
+	$< Config.in
 
 prepare_kernel_conf: .config FORCE
 
 ifeq ($(wildcard staging_dir/host/bin/quilt),)
   prepare_kernel_conf:
-	@+$(SUBMAKE) -r tools/quilt/install
+	@+$(SUBMAKE) -r tools/quilt/compile
 else
   prepare_kernel_conf: ;
 endif
@@ -141,6 +162,10 @@ endif
 kernel_oldconfig: prepare_kernel_conf
 	$(_SINGLE)$(NO_TRACE_MAKE) -C target/linux oldconfig
 
+ifneq ($(DISTRO_PKG_CONFIG),)
+kernel_menuconfig: export PATH:=$(dir $(DISTRO_PKG_CONFIG)):$(PATH)
+kernel_nconfig: export PATH:=$(dir $(DISTRO_PKG_CONFIG)):$(PATH)
+endif
 kernel_menuconfig: prepare_kernel_conf
 	$(_SINGLE)$(NO_TRACE_MAKE) -C target/linux menuconfig
 
@@ -149,7 +174,6 @@ kernel_nconfig: prepare_kernel_conf
 
 staging_dir/host/.prereq-build: include/prereq-build.mk
 	mkdir -p tmp
-	rm -f tmp/.host.mk
 	@$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f $(TOPDIR)/include/prereq-build.mk prereq 2>/dev/null || { \
 		echo "Prerequisite check failed. Use FORCE=1 to override."; \
 		false; \
@@ -183,7 +207,10 @@ prereq:: prepare-tmpinfo .config
 check: .config FORCE
 	@+$(NO_TRACE_MAKE) -r -s $@ QUIET= V=s
 
-WARN_PARALLEL_ERROR = $(if $(BUILD_LOG),,$(and $(filter -j,$(MAKEFLAGS)),$(findstring s,$(OPENWRT_VERBOSE))))
+val.%: FORCE
+	@+$(NO_TRACE_MAKE) -r -s $@ QUIET= V=s
+
+WARN_PARALLEL_ERROR = $(if $(BUILD_LOG),,$(and $(filter -j,$(MAKEFLAGS)),$(findstring s,$(LIBRECMC_VERBOSE))))
 
 ifeq ($(SDK),1)
 
@@ -228,7 +255,7 @@ help:
 	cat README
 
 distclean:
-	rm -rf bin build_dir .config* dl feeds key-build* logs package/feeds package/openwrt-packages staging_dir tmp
+	rm -rf bin build_dir .config* dl feeds key-build* logs package/feeds package/librecmc-packages staging_dir tmp
 	@$(_SINGLE)$(SUBMAKE) -C scripts/config clean
 
 ifeq ($(findstring v,$(DEBUG)),)

+ 104 - 0
include/u-boot.mk

@@ -0,0 +1,104 @@
+PKG_NAME ?= u-boot
+
+ifndef PKG_SOURCE_PROTO
+PKG_SOURCE = $(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL = \
+	http://sources.lede-project.org \
+	ftp://ftp.denx.de/pub/u-boot
+endif
+
+PKG_BUILD_DIR = $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_TARGETS := bin
+PKG_FLAGS:=nonshared
+
+PKG_LICENSE:=GPL-2.0 GPL-2.0+
+PKG_LICENSE_FILES:=Licenses/README
+
+PKG_BUILD_PARALLEL:=1
+
+export GCC_HONOUR_COPTS=s
+
+define Package/u-boot/install/default
+	$(CP) $(patsubst %,$(PKG_BUILD_DIR)/%,$(UBOOT_IMAGE)) $(1)/
+endef
+
+Package/u-boot/install = $(Package/u-boot/install/default)
+
+define U-Boot/Init
+  BUILD_TARGET:=
+  BUILD_SUBTARGET:=
+  BUILD_DEVICES:=
+  NAME:=
+  DEPENDS:=
+  HIDDEN:=
+  DEFAULT:=
+  VARIANT:=$(1)
+  UBOOT_CONFIG:=$(1)
+  UBOOT_IMAGE:=u-boot.bin
+endef
+
+TARGET_DEP = TARGET_$(BUILD_TARGET)$(if $(BUILD_SUBTARGET),_$(BUILD_SUBTARGET))
+
+UBOOT_MAKE_FLAGS = \
+	HOSTCC="$(HOSTCC)" \
+	HOSTCFLAGS="$(HOST_CFLAGS) $(HOST_CPPFLAGS) -std=gnu11" \
+	HOSTLDFLAGS="$(HOST_LDFLAGS)"
+
+define Build/U-Boot/Target
+  $(eval $(call U-Boot/Init,$(1)))
+  $(eval $(call U-Boot/Default,$(1)))
+  $(eval $(call U-Boot/$(1),$(1)))
+
+ define Package/u-boot-$(1)
+    SECTION:=boot
+    CATEGORY:=Boot Loaders
+    TITLE:=U-Boot for $(NAME)
+    VARIANT:=$(VARIANT)
+    DEPENDS:=@!IN_SDK $(DEPENDS)
+    HIDDEN:=$(HIDDEN)
+    ifneq ($(BUILD_TARGET),)
+      DEPENDS += @$(TARGET_DEP)
+      ifneq ($(BUILD_DEVICES),)
+        DEFAULT := y if ($(TARGET_DEP)_Default \
+		$(patsubst %,|| $(TARGET_DEP)_DEVICE_%,$(BUILD_DEVICES)) \
+		$(patsubst %,|| $(patsubst TARGET_%,TARGET_DEVICE_%,$(TARGET_DEP))_DEVICE_%,$(BUILD_DEVICES)))
+      endif
+    endif
+    $(if $(DEFAULT),DEFAULT:=$(DEFAULT))
+    URL:=http://www.denx.de/wiki/U-Boot
+  endef
+
+  define Package/u-boot-$(1)/install
+	$$(Package/u-boot/install)
+  endef
+endef
+
+define Build/Configure/U-Boot
+	+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) $(UBOOT_CONFIG)_config
+endef
+
+DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc)
+
+define Build/Compile/U-Boot
+	+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+		CROSS_COMPILE=$(TARGET_CROSS) \
+		$(if $(DTC),DTC="$(DTC)") \
+		$(UBOOT_MAKE_FLAGS)
+endef
+
+define BuildPackage/U-Boot/Defaults
+  Build/Configure/Default = $$$$(Build/Configure/U-Boot)
+  Build/Compile/Default = $$$$(Build/Compile/U-Boot)
+endef
+
+define BuildPackage/U-Boot
+  $(eval $(call BuildPackage/U-Boot/Defaults))
+  $(foreach type,$(if $(DUMP),$(UBOOT_TARGETS),$(BUILD_VARIANT)), \
+    $(eval $(call Build/U-Boot/Target,$(type)))
+  )
+  $(eval $(call Build/DefaultTargets))
+  $(foreach type,$(if $(DUMP),$(UBOOT_TARGETS),$(BUILD_VARIANT)), \
+    $(call BuildPackage,u-boot-$(type))
+  )
+endef

+ 2 - 7
include/unpack.mk

@@ -58,18 +58,13 @@ ifeq ($(strip $(UNPACK_CMD)),)
       UNPACK_CMD=gzip -dc $(DL_DIR)/$(PKG_SOURCE) | $(TAR_CMD)
     endif
   endif
-  ifneq ($(strip $(CRLF_WORKAROUND)),)
-    CRLF_CMD := && find $(PKG_BUILD_DIR) -type f -print0 | xargs -0 perl -pi -e 's!\r$$$$!!g'
-  else
-    CRLF_CMD :=
-  endif
 endif
 
 ifdef PKG_BUILD_DIR
-  PKG_UNPACK ?= $(SH_FUNC) $(call UNPACK_CMD,$(PKG_BUILD_DIR)) $(call CRLF_CMD,$(PKG_BUILD_DIR))
+  PKG_UNPACK ?= $(SH_FUNC) $(call UNPACK_CMD,$(PKG_BUILD_DIR))
 endif
 ifdef HOST_BUILD_DIR
-  HOST_UNPACK ?= $(SH_FUNC) $(call UNPACK_CMD,$(HOST_BUILD_DIR)) $(call CRLF_CMD,$(HOST_BUILD_DIR))
+  HOST_UNPACK ?= $(SH_FUNC) $(call UNPACK_CMD,$(HOST_BUILD_DIR))
 endif
 
 endif # PKG_SOURCE

+ 11 - 11
include/verbose.mk

@@ -5,22 +5,22 @@
 # See /LICENSE for more information.
 #
 
-ifndef OPENWRT_VERBOSE
-  OPENWRT_VERBOSE:=
+ifndef LIBRECMC_VERBOSE
+  LIBRECMC_VERBOSE:=
 endif
 ifeq ("$(origin V)", "command line")
-  OPENWRT_VERBOSE:=$(V)
+  LIBRECMC_VERBOSE:=$(V)
 endif
 
-ifeq ($(OPENWRT_VERBOSE),1)
-  OPENWRT_VERBOSE:=w
+ifeq ($(LIBRECMC_VERBOSE),1)
+  LIBRECMC_VERBOSE:=w
 endif
-ifeq ($(OPENWRT_VERBOSE),99)
-  OPENWRT_VERBOSE:=s
+ifeq ($(LIBRECMC_VERBOSE),99)
+  LIBRECMC_VERBOSE:=s
 endif
 
 ifeq ($(NO_TRACE_MAKE),)
-NO_TRACE_MAKE := $(MAKE) V=s$(OPENWRT_VERBOSE)
+NO_TRACE_MAKE := $(MAKE) V=s$(LIBRECMC_VERBOSE)
 export NO_TRACE_MAKE
 endif
 
@@ -32,7 +32,7 @@ ifeq ($(IS_TTY),1)
   endif
 endif
 
-ifeq ($(findstring s,$(OPENWRT_VERBOSE)),)
+ifeq ($(findstring s,$(LIBRECMC_VERBOSE)),)
   define MESSAGE
 	printf "$(_Y)%s$(_N)\n" "$(1)" >&8
   endef
@@ -52,9 +52,9 @@ ifeq ($(findstring s,$(OPENWRT_VERBOSE)),)
     ))
     SUBMAKE=$(MAKE)
   else
-    SILENT:=>/dev/null $(if $(findstring w,$(OPENWRT_VERBOSE)),,2>&1)
+    SILENT:=>/dev/null $(if $(findstring w,$(LIBRECMC_VERBOSE)),,2>&1)
     export QUIET:=1
-    SUBMAKE=cmd() { $(SILENT) $(MAKE) -s $$* < /dev/null || { echo "make $$*: build failed. Please re-run make with -j1 V=s to see what's going on"; false; } } 8>&1 9>&2; cmd
+    SUBMAKE=cmd() { $(SILENT) $(MAKE) -s "$$@" < /dev/null || { echo "make $$*: build failed. Please re-run make with -j1 V=s or V=sc for a higher verbosity level to see what's going on"; false; } } 8>&1 9>&2; cmd
   endif
 
   .SILENT: $(MAKECMDGOALS)

+ 42 - 43
include/version.mk

@@ -10,13 +10,11 @@
 # REVISION:=x
 # SOURCE_DATE_EPOCH:=x
 
-RELEASE:=Frivolous Fred
-
 PKG_CONFIG_DEPENDS += \
+	CONFIG_VERSION_HOME_URL \
 	CONFIG_VERSION_BUG_URL \
 	CONFIG_VERSION_NUMBER \
 	CONFIG_VERSION_CODE \
-	CONFIG_VERSION_NICK \
 	CONFIG_VERSION_REPO \
 	CONFIG_VERSION_DIST \
 	CONFIG_VERSION_MANUFACTURER \
@@ -25,43 +23,40 @@ PKG_CONFIG_DEPENDS += \
 	CONFIG_VERSION_SUPPORT_URL \
 	CONFIG_VERSION_HWREV \
 
-qstrip_escape=$(subst ','\'',$(call qstrip,$(1)))
-#'
-
 sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1))))
 
-VERSION_NUMBER:=$(call qstrip_escape,$(CONFIG_VERSION_NUMBER))
-VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),v1.4.9)
+VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER))
+VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),v1.5.0)
 
-VERSION_CODE:=$(call qstrip_escape,$(CONFIG_VERSION_CODE))
+VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE))
 VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION))
 
-VERSION_NICK:=$(call qstrip_escape,$(CONFIG_VERSION_NICK))
-VERSION_NICK:=$(if $(VERSION_NICK),$(VERSION_NICK),$(RELEASE))
-
-VERSION_REPO:=$(call qstrip_escape,$(CONFIG_VERSION_REPO))
+VERSION_REPO:=$(call qstrip,$(CONFIG_VERSION_REPO))
 VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://librecmc.org/librecmc/downloads/snapshots/%v)
 
-VERSION_DIST:=$(call qstrip_escape,$(CONFIG_VERSION_DIST))
+VERSION_DIST:=$(call qstrip,$(CONFIG_VERSION_DIST))
 VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),libreCMC)
 VERSION_DIST_SANITIZED:=$(call sanitize,$(VERSION_DIST))
 
-VERSION_MANUFACTURER:=$(call qstrip_escape,$(CONFIG_VERSION_MANUFACTURER))
+VERSION_MANUFACTURER:=$(call qstrip,$(CONFIG_VERSION_MANUFACTURER))
 VERSION_MANUFACTURER:=$(if $(VERSION_MANUFACTURER),$(VERSION_MANUFACTURER),libreCMC)
 
-VERSION_MANUFACTURER_URL:=$(call qstrip_escape,$(CONFIG_VERSION_MANUFACTURER_URL))
-VERSION_MANUFACTURER_URL:=$(if $(VERSION_MANUFACTURER_URL),$(VERSION_MANUFACTURER_URL),https://librecmc.org)
+VERSION_MANUFACTURER_URL:=$(call qstrip,$(CONFIG_VERSION_MANUFACTURER_URL))
+VERSION_MANUFACTURER_URL:=$(if $(VERSION_MANUFACTURER_URL),$(VERSION_MANUFACTURER_URL),https://librecmc.org/)
 
-VERSION_BUG_URL:=$(call qstrip_escape,$(CONFIG_VERSION_BUG_URL))
+VERSION_BUG_URL:=$(call qstrip,$(CONFIG_VERSION_BUG_URL))
 VERSION_BUG_URL:=$(if $(VERSION_BUG_URL),$(VERSION_BUG_URL),https://gogs.librecmc.org/libreCMC/libreCMC/issues)
 
-VERSION_SUPPORT_URL:=$(call qstrip_escape,$(CONFIG_VERSION_SUPPORT_URL))
+VERSION_HOME_URL:=$(call qstrip,$(CONFIG_VERSION_HOME_URL))
+VERSION_HOME_URL:=$(if $(VERSION_HOME_URL),$(VERSION_HOME_URL),https://librecmc.org/)
+
+VERSION_SUPPORT_URL:=$(call qstrip,$(CONFIG_VERSION_SUPPORT_URL))
 VERSION_SUPPORT_URL:=$(if $(VERSION_SUPPORT_URL),$(VERSION_SUPPORT_URL))
 
-VERSION_PRODUCT:=$(call qstrip_escape,$(CONFIG_VERSION_PRODUCT))
+VERSION_PRODUCT:=$(call qstrip,$(CONFIG_VERSION_PRODUCT))
 VERSION_PRODUCT:=$(if $(VERSION_PRODUCT),$(VERSION_PRODUCT),Generic)
 
-VERSION_HWREV:=$(call qstrip_escape,$(CONFIG_VERSION_HWREV))
+VERSION_HWREV:=$(call qstrip,$(CONFIG_VERSION_HWREV))
 VERSION_HWREV:=$(if $(VERSION_HWREV),$(VERSION_HWREV),v0)
 
 define taint2sym
@@ -88,25 +83,29 @@ VERSION_TAINTS := $(strip $(foreach taint,$(VERSION_TAINT_SPECS), \
 
 PKG_CONFIG_DEPENDS += $(foreach taint,$(VERSION_TAINT_SPECS),$(call taint2sym,$(taint)))
 
-VERSION_SED:=$(SED) 's,%U,$(VERSION_REPO),g' \
-	-e 's,%V,$(VERSION_NUMBER),g' \
-	-e 's,%v,\L$(subst $(space),_,$(VERSION_NUMBER)),g' \
-	-e 's,%C,$(VERSION_CODE),g' \
-	-e 's,%c,\L$(subst $(space),_,$(VERSION_CODE)),g' \
-	-e 's,%N,$(VERSION_NICK),g' \
-	-e 's,%n,\L$(subst $(space),_,$(VERSION_NICK)),g' \
-	-e 's,%D,$(VERSION_DIST),g' \
-	-e 's,%d,\L$(subst $(space),_,$(VERSION_DIST)),g' \
-	-e 's,%R,$(REVISION),g' \
-	-e 's,%T,$(BOARD),g' \
-	-e 's,%S,$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic),g' \
-	-e 's,%A,$(ARCH_PACKAGES),g' \
-	-e 's,%t,$(VERSION_TAINTS),g' \
-	-e 's,%M,$(VERSION_MANUFACTURER),g' \
-	-e 's,%m,$(VERSION_MANUFACTURER_URL),g' \
-	-e 's,%b,$(VERSION_BUG_URL),g' \
-	-e 's,%s,$(VERSION_SUPPORT_URL),g' \
-	-e 's,%P,$(VERSION_PRODUCT),g' \
-	-e 's,%h,$(VERSION_HWREV),g'
-
-VERSION_SED_SCRIPT:=$(subst '\'','\'\\\\\'\'',$(VERSION_SED))
+# escape commas, backslashes, squotes, and ampersands for sed
+define sed_escape
+$(subst &,\&,$(subst $(comma),\$(comma),$(subst ','\'',$(subst \,\\,$(1)))))
+endef
+#'
+
+VERSION_SED_SCRIPT:=$(SED) 's,%U,$(call sed_escape,$(VERSION_REPO)),g' \
+	-e 's,%V,$(call sed_escape,$(VERSION_NUMBER)),g' \
+	-e 's,%v,\L$(call sed_escape,$(subst $(space),_,$(VERSION_NUMBER))),g' \
+	-e 's,%C,$(call sed_escape,$(VERSION_CODE)),g' \
+	-e 's,%c,\L$(call sed_escape,$(subst $(space),_,$(VERSION_CODE))),g' \
+	-e 's,%D,$(call sed_escape,$(VERSION_DIST)),g' \
+	-e 's,%d,\L$(call sed_escape,$(subst $(space),_,$(VERSION_DIST))),g' \
+	-e 's,%R,$(call sed_escape,$(REVISION)),g' \
+	-e 's,%T,$(call sed_escape,$(BOARD)),g' \
+	-e 's,%S,$(call sed_escape,$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic)),g' \
+	-e 's,%A,$(call sed_escape,$(ARCH_PACKAGES)),g' \
+	-e 's,%t,$(call sed_escape,$(VERSION_TAINTS)),g' \
+	-e 's,%M,$(call sed_escape,$(VERSION_MANUFACTURER)),g' \
+	-e 's,%m,$(call sed_escape,$(VERSION_MANUFACTURER_URL)),g' \
+	-e 's,%b,$(call sed_escape,$(VERSION_BUG_URL)),g' \
+	-e 's,%u,$(call sed_escape,$(VERSION_HOME_URL)),g' \
+	-e 's,%s,$(call sed_escape,$(VERSION_SUPPORT_URL)),g' \
+	-e 's,%P,$(call sed_escape,$(VERSION_PRODUCT)),g' \
+	-e 's,%h,$(call sed_escape,$(VERSION_HWREV)),g'
+

+ 16 - 10
package/Makefile

@@ -7,11 +7,12 @@
 
 curdir:=package
 
+include $(INCLUDE_DIR)/feeds.mk
 include $(INCLUDE_DIR)/rootfs.mk
 
 -include $(TMP_DIR)/.packagedeps
+$(curdir)/autoremove:=1
 $(curdir)/builddirs:=$(sort $(package-) $(package-y) $(package-m))
-$(curdir)/builddirs-install:=.
 $(curdir)/builddirs-default:=. $(sort $(package-y) $(package-m))
 $(curdir)/builddirs-prereq:=. $(sort $(prereq-y) $(prereq-m))
 ifdef CHECK_ALL
@@ -56,23 +57,26 @@ $(curdir)/merge:
 $(curdir)/merge-index: $(curdir)/merge
 	(cd $(PACKAGE_DIR_ALL) && $(SCRIPT_DIR)/ipkg-make-index.sh . 2>&1 > Packages; )
 
-$(curdir)/install: $(TMP_DIR)/.build $(curdir)/system/opkg/host/compile $(curdir)/merge $(if $(CONFIG_TARGET_PER_DEVICE_ROOTFS),$(curdir)/merge-index)
+ifndef SDK
+  $(curdir)/compile: $(curdir)/system/opkg/host/compile
+endif
+
+$(curdir)/install: $(TMP_DIR)/.build $(curdir)/merge $(if $(CONFIG_TARGET_PER_DEVICE_ROOTFS),$(curdir)/merge-index)
 	- find $(STAGING_DIR_ROOT) -type d | $(XARGS) chmod 0755
 	rm -rf $(TARGET_DIR) $(TARGET_DIR_ORIG)
-	[ -d $(TARGET_DIR)/tmp ] || mkdir -p $(TARGET_DIR)/tmp
+	mkdir -p $(TARGET_DIR)/tmp
 	$(call opkg,$(TARGET_DIR)) install \
-		$(call opkg_package_files,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null))
+		$(call opkg_package_files,$(foreach pkg,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null),$(pkg)$(call GetABISuffix,$(pkg))))
 	@for file in $(PACKAGE_INSTALL_FILES); do \
 		[ -s $$file.flags ] || continue; \
 		for flag in `cat $$file.flags`; do \
 			$(call opkg,$(TARGET_DIR)) flag $$flag `cat $$file`; \
 		done; \
 	done || true
-	@-$(MAKE) package/preconfig
 
 	$(CP) $(TARGET_DIR) $(TARGET_DIR_ORIG)
 
-	$(call prepare_rootfs,$(TARGET_DIR))
+	$(call prepare_rootfs,$(TARGET_DIR),$(TOPDIR)/files)
 
 $(curdir)/index: FORCE
 	@echo Generating package index...
@@ -80,8 +84,12 @@ $(curdir)/index: FORCE
 		mkdir -p $$d; \
 		cd $$d || continue; \
 		$(SCRIPT_DIR)/ipkg-make-index.sh . 2>&1 > Packages.manifest; \
-		grep -vE '^(Maintainer|LicenseFiles|Source|Require)' Packages.manifest > Packages && \
-			gzip -9nc Packages > Packages.gz; \
+		grep -vE '^(Maintainer|LicenseFiles|Source|SourceName|Require)' Packages.manifest > Packages; \
+		case "$$(((64 + $$(stat -L -c%s Packages)) % 128))" in 110|111) \
+			$(call ERROR_MESSAGE,WARNING: Applying padding in $$d/Packages to workaround usign SHA-512 bug!); \
+			{ echo ""; echo ""; } >> Packages;; \
+		esac; \
+		gzip -9nc Packages > Packages.gz; \
 	); done
 ifdef CONFIG_SIGNED_PACKAGES
 	@echo Signing package index...
@@ -92,8 +100,6 @@ ifdef CONFIG_SIGNED_PACKAGES
 	); done
 endif
 
-$(curdir)/preconfig:
-
 $(curdir)/flags-install:= -j1
 
 $(eval $(call stampfile,$(curdir),package,prereq,.config))

+ 54 - 18
package/base-files/Makefile

@@ -9,17 +9,23 @@
 include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 include $(INCLUDE_DIR)/version.mk
+include $(INCLUDE_DIR)/feeds.mk
 
 PKG_NAME:=base-files
-PKG_RELEASE:=173.1
+PKG_RELEASE:=204.2
 PKG_FLAGS:=nonshared
 
 PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
-PKG_BUILD_DEPENDS:=usign/host
+PKG_BUILD_DEPENDS:=usign/host ucert/host
 PKG_LICENSE:=GPL-2.0
 
 # Extend depends from version.mk
-PKG_CONFIG_DEPENDS += CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE
+PKG_CONFIG_DEPENDS += \
+	CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE \
+	CONFIG_NAND_SUPPORT \
+	CONFIG_CLEAN_IPKG \
+	CONFIG_PER_FEED_REPO \
+	$(foreach feed,$(FEEDS_AVAILABLE),CONFIG_FEED_$(feed))
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -31,39 +37,48 @@ endif
 define Package/base-files
   SECTION:=base
   CATEGORY:=Base system
-  DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:librecmc-keyring +fstools +fwtool
-  TITLE:=Base filesystem for Lede
+  DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:librecmc-keyring +NAND_SUPPORT:ubi-utils +fstools +fwtool
+  TITLE:=Base filesystem for libreCMC
+  URL:=http://openwrt.org/
+  VERSION:=$(PKG_RELEASE)-$(REVISION)
+endef
+
+define Package/urandom-seed
+  SECTION:=base
+  CATEGORY:=Base system
+  DEPENDS:=+libc +ubox-getrandom
+  TITLE:=/etc/urandom.seed handling for libreCMC
   URL:=http://openwrt.org/
   VERSION:=$(PKG_RELEASE)-$(REVISION)
 endef
 
 define Package/base-files/conffiles
+/etc/config/
 /etc/config/network
 /etc/config/system
+/etc/crontabs/
+/etc/dropbear/
+/etc/ethers
+/etc/group
 /etc/hosts
 /etc/inittab
-/etc/group
+/etc/iproute2/rt_protos
+/etc/iproute2/rt_tables
 /etc/passwd
-/etc/shadow
 /etc/profile
+/etc/profile.d
 /etc/protocols
+/etc/rc.local
 /etc/services
+/etc/shadow
 /etc/shells
 /etc/sysctl.conf
-/etc/rc.local
 /etc/sysupgrade.conf
-/etc/config/
-/etc/dropbear/
-/etc/crontabs/
-/etc/sysctl.d/local.conf
-/etc/sysctl.d/
-/etc/iproute2/rt_tables
-/etc/iproute2/rt_protos
 $(call $(TARGET)/conffiles)
 endef
 
 define Package/base-files/description
- This package contains a base filesystem and system scripts for OpenWrt.
+ This package contains a base filesystem and system scripts for libreCMC.
 endef
 
 define ImageConfigOptions
@@ -97,6 +112,9 @@ ifdef CONFIG_SIGNED_PACKAGES
 	[ -s $(BUILD_KEY) -a -s $(BUILD_KEY).pub ] || \
 		$(STAGING_DIR_HOST)/bin/usign -G -s $(BUILD_KEY) -p $(BUILD_KEY).pub -c "Local build key"
 
+	[ -s $(BUILD_KEY).ucert ] || \
+		$(STAGING_DIR_HOST)/bin/ucert -I -c $(BUILD_KEY).ucert -p $(BUILD_KEY).pub -s $(BUILD_KEY)
+
   endef
 
   define Package/base-files/install-key
@@ -106,9 +124,16 @@ ifdef CONFIG_SIGNED_PACKAGES
   endef
 endif
 
+ifeq ($(CONFIG_NAND_SUPPORT),)
+  define Package/base-files/nand-support
+	rm -f $(1)/lib/upgrade/nand.sh
+  endef
+endif
+
 define Package/base-files/install
 	$(CP) ./files/* $(1)/
 	$(Package/base-files/install-key)
+	$(Package/base-files/nand-support)
 	if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \
 		$(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \
 	fi
@@ -121,7 +146,7 @@ define Package/base-files/install
 		fi; \
 	)
 
-	$(VERSION_SED) \
+	$(VERSION_SED_SCRIPT) \
 		$(1)/etc/banner \
 		$(1)/etc/openwrt_version \
 		$(1)/usr/lib/os-release
@@ -155,7 +180,7 @@ define Package/base-files/install
 	mkdir -p $(1)/root
 	$(LN) /proc/mounts $(1)/etc/mtab
 	rm -f $(1)/var
-	$(LN) /tmp $(1)/var
+	$(LN) tmp $(1)/var
 	mkdir -p $(1)/etc
 	$(LN) /tmp/resolv.conf /tmp/TZ /tmp/localtime $(1)/etc/
 
@@ -170,6 +195,17 @@ define Package/base-files/install
 				echo "$$$${conffile##$(1)}" >> $(1)/CONTROL/conffiles; \
 		fi \
 	done
+
+	$(if $(CONFIG_INCLUDE_CONFIG), \
+		echo -e "# Build configuration for board $(BOARD)/$(SUBTARGET)/$(PROFILE)\n" >$(1)/etc/build.config; \
+		cat $(BIN_DIR)/config.buildinfo >>$(1)/etc/build.config)
+
+	$(if $(CONFIG_CLEAN_IPKG),, \
+		mkdir -p $(1)/etc/opkg; \
+		$(call FeedSourcesAppend,$(1)/etc/opkg/distfeeds.conf); \
+		$(VERSION_SED_SCRIPT) $(1)/etc/opkg/distfeeds.conf)
+	$(if $(CONFIG_IPK_FILES_CHECKSUMS), \
+		rm -f $(1)/sbin/pkg_check,)
 endef
 
 ifneq ($(DUMP),1)

+ 50 - 31
package/base-files/files/bin/config_generate

@@ -15,17 +15,21 @@ generate_static_network() {
 		set network.loopback.proto='static'
 		set network.loopback.ipaddr='127.0.0.1'
 		set network.loopback.netmask='255.0.0.0'
-		delete network.globals
-		set network.globals='globals'
-		set network.globals.ula_prefix='auto'
 	EOF
+		[ -e /proc/sys/net/ipv6 ] && {
+			uci -q batch <<-EOF
+				delete network.globals
+				set network.globals='globals'
+				set network.globals.ula_prefix='auto'
+			EOF
+		}
 
 	if json_is_a dsl object; then
 		json_select dsl
 			if json_is_a atmbridge object; then
 				json_select atmbridge
-					local vpi vci encaps payload
-					json_get_vars vpi vci encaps payload
+					local vpi vci encaps payload nameprefix
+					json_get_vars vpi vci encaps payload nameprefix
 					uci -q batch <<-EOF
 						delete network.atm
 						set network.atm='atm-bridge'
@@ -33,6 +37,7 @@ generate_static_network() {
 						set network.atm.vci='$vci'
 						set network.atm.encaps='$encaps'
 						set network.atm.payload='$payload'
+						set network.atm.nameprefix='$nameprefix'
 					EOF
 				json_select ..
 			fi
@@ -80,12 +85,16 @@ generate_network() {
 		set network.$1.proto='none'
 	EOF
 
-	[ -n "$macaddr" ] && uci -q batch <<-EOF
-		delete network.$1_dev
-		set network.$1_dev='device'
-		set network.$1_dev.name='$ifname'
-		set network.$1_dev.macaddr='$macaddr'
-	EOF
+	if [ -n "$macaddr" ]; then
+		for name in $ifname; do
+			uci -q batch <<-EOF
+				delete network.$1_${name/./_}_dev
+				set network.$1_${name/./_}_dev='device'
+				set network.$1_${name/./_}_dev.name='$name'
+				set network.$1_${name/./_}_dev.macaddr='$macaddr'
+			EOF
+		done
+	fi
 
 	case "$protocol" in
 		static)
@@ -101,21 +110,23 @@ generate_network() {
 				set network.$1.proto='static'
 				set network.$1.ipaddr='$ipad'
 				set network.$1.netmask='$netm'
-				set network.$1.ip6assign='60'
 			EOF
+			[ -e /proc/sys/net/ipv6 ] && uci set network.$1.ip6assign='60'
 		;;
 
 		dhcp)
 			# fixup IPv6 slave interface if parent is a bridge
 			[ "$type" = "bridge" ] && ifname="br-$1"
 
-			uci -q batch <<-EOF
-				set network.$1.proto='dhcp'
-				delete network.${1}6
-				set network.${1}6='interface'
-				set network.${1}6.ifname='$ifname'
-				set network.${1}6.proto='dhcpv6'
-			EOF
+			uci set network.$1.proto='dhcp'
+			[ -e /proc/sys/net/ipv6 ] && {
+				uci -q batch <<-EOF
+					delete network.${1}6
+					set network.${1}6='interface'
+					set network.${1}6.ifname='$ifname'
+					set network.${1}6.proto='dhcpv6'
+				EOF
+			}
 		;;
 
 		pppoe)
@@ -123,12 +134,16 @@ generate_network() {
 				set network.$1.proto='pppoe'
 				set network.$1.username='username'
 				set network.$1.password='password'
-				set network.$1.ipv6='1'
-				delete network.${1}6
-				set network.${1}6='interface'
-				set network.${1}6.ifname='@${1}'
-				set network.${1}6.proto='dhcpv6'
 			EOF
+			[ -e /proc/sys/net/ipv6 ] && {
+				uci -q batch <<-EOF
+					set network.$1.ipv6='1'
+					delete network.${1}6
+					set network.${1}6='interface'
+					set network.${1}6.ifname='@${1}'
+					set network.${1}6.proto='dhcpv6'
+				EOF
+			}
 		;;
 	esac
 }
@@ -202,7 +217,8 @@ generate_switch() {
 
 	json_select switch
 	json_select "$key"
-	json_get_vars enable reset blinkrate cpu_port
+	json_get_vars enable reset blinkrate cpu_port \
+		ar8xxx_mib_type ar8xxx_mib_poll_interval
 
 	uci -q batch <<-EOF
 		add network switch
@@ -210,6 +226,8 @@ generate_switch() {
 		set network.@switch[-1].reset='$reset'
 		set network.@switch[-1].enable_vlan='$enable'
 		set network.@switch[-1].blinkrate='$blinkrate'
+		set network.@switch[-1].ar8xxx_mib_type='$ar8xxx_mib_type'
+		set network.@switch[-1].ar8xxx_mib_poll_interval='$ar8xxx_mib_poll_interval'
 	EOF
 
 	generate_switch_vlans_ports "$1"
@@ -233,10 +251,10 @@ generate_static_system() {
 		set system.ntp='timeserver'
 		set system.ntp.enabled='1'
 		set system.ntp.enable_server='0'
-		add_list system.ntp.server='0.lede.pool.ntp.org'
-		add_list system.ntp.server='1.lede.pool.ntp.org'
-		add_list system.ntp.server='2.lede.pool.ntp.org'
-		add_list system.ntp.server='3.lede.pool.ntp.org'
+		add_list system.ntp.server='0.openwrt.pool.ntp.org'
+		add_list system.ntp.server='1.openwrt.pool.ntp.org'
+		add_list system.ntp.server='2.openwrt.pool.ntp.org'
+		add_list system.ntp.server='3.openwrt.pool.ntp.org'
 	EOF
 
 	if json_is_a system object; then
@@ -355,11 +373,12 @@ generate_led() {
 		;;
 
 		switch)
-			local port_mask speed_mask
-			json_get_vars port_mask speed_mask
+			local port_mask speed_mask mode
+			json_get_vars port_mask speed_mask mode
 			uci -q batch <<-EOF
 				set system.$cfg.port_mask='$port_mask'
 				set system.$cfg.speed_mask='$speed_mask'
+				set system.$cfg.mode='$mode'
 			EOF
 		;;
 

+ 3 - 1
package/base-files/files/etc/banner.failsafe

@@ -8,6 +8,8 @@ after mount_root:
 * /etc/config		    directory with config files
 
 for more help see:
-http://wiki.openwrt.org/doc/howto/generic.failsafe
+https://openwrt.org/docs/guide-user/troubleshooting/
+- failsafe_and_factory_reset
+- root_password_reset
 =======================================================
 

+ 48 - 2
package/base-files/files/etc/diag.sh

@@ -1,4 +1,50 @@
 #!/bin/sh
-# Copyright (C) 2006-2009 OpenWrt.org
+# Copyright (C) 2006-2019 OpenWrt.org
 
-set_state() { :; }
+. /lib/functions/leds.sh
+
+boot="$(get_dt_led boot)"
+failsafe="$(get_dt_led failsafe)"
+running="$(get_dt_led running)"
+upgrade="$(get_dt_led upgrade)"
+
+set_led_state() {
+	status_led="$boot"
+
+	case "$1" in
+	preinit)
+		status_led_blink_preinit
+		;;
+	failsafe)
+		status_led_off
+		[ -n "$running" ] && {
+			status_led="$running"
+			status_led_off
+		}
+		status_led="$failsafe"
+		status_led_blink_failsafe
+		;;
+	preinit_regular)
+		status_led_blink_preinit_regular
+		;;
+	upgrade)
+		[ -n "$running" ] && {
+			status_led="$running"
+			status_led_off
+		}
+		status_led="$upgrade"
+		status_led_blink_preinit_regular
+		;;
+	done)
+		status_led_off
+		[ -n "$running" ] && {
+			status_led="$running"
+			status_led_on
+		}
+		;;
+	esac
+}
+
+set_state() {
+	[ -n "$boot" -o -n "$failsafe" -o -n "$running" -o -n "$upgrade" ] && set_led_state "$1"
+}

+ 6 - 0
package/base-files/files/etc/ethers

@@ -0,0 +1,6 @@
+#
+#  Lookup man 5 ethers for syntax documentation
+#
+#  Examples :
+#	02:00:11:22:33:44	libreCMC.lan
+#	02:00:11:22:33:44	192.168.10.1

+ 1 - 0
package/base-files/files/etc/group

@@ -2,6 +2,7 @@ root:x:0:
 daemon:x:1:
 adm:x:4:
 mail:x:8:
+dialout:x:20:
 audio:x:29:
 www-data:x:33:
 ftp:x:55:

+ 1 - 1
package/base-files/files/etc/hotplug.d/net/00-sysctl

@@ -1,7 +1,7 @@
 #!/bin/sh
 
 if [ "$ACTION" = add ]; then
-	for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
+	for CONF in /etc/sysctl.d/*.conf /etc/sysctl.conf; do
 		[ ! -f "$CONF" ] && continue;
 		sed -ne "/^[[:space:]]*net\..*\.$DEVICENAME\./p" "$CONF" | \
 			sysctl -e -p - | logger -t sysctl

+ 1 - 1
package/base-files/files/etc/init.d/boot

@@ -2,7 +2,7 @@
 # Copyright (C) 2006-2011 OpenWrt.org
 
 START=10
-STOP=98
+STOP=90
 
 uci_apply_defaults() {
 	. /lib/functions/system.sh

+ 10 - 4
package/base-files/files/etc/init.d/gpio_switch

@@ -1,7 +1,7 @@
 #!/bin/sh /etc/rc.common
 # Copyright (C) 2015 OpenWrt.org
 
-START=98
+START=94
 STOP=10
 USE_PROCD=1
 
@@ -22,10 +22,16 @@ load_gpio_switch()
 		echo "$gpio_pin" >/sys/class/gpio/export
 		# we need to wait a bit until the GPIO appears
 		[ -d "$gpio_path" ] || sleep 1
-		echo out >"$gpio_path/direction"
 	}
-	# write 0 or 1 to the "value" field
-	{ [ "$value" = "0" ] && echo "0" || echo "1"; } >"$gpio_path/value"
+
+	# direction attribute only exists if the kernel supports changing the
+	# direction of a GPIO
+	if [ -e "${gpio_path}/direction" ]; then
+		# set the pin to output with high or low pin value
+		{ [ "$value" = "0" ] && echo "low" || echo "high"; } >"$gpio_path/direction"
+	else
+		{ [ "$value" = "0" ] && echo "0" || echo "1"; } >"$gpio_path/value"
+	fi
 }
 
 service_triggers()

+ 8 - 2
package/base-files/files/etc/init.d/led

@@ -20,7 +20,7 @@ load_led() {
 	config_get trigger $1 trigger "none"
 	config_get dev $1 dev
 	config_get ports $1 port
-	config_get mode $1 mode "link"
+	config_get mode $1 mode
 	config_get_bool default $1 default "nil"
 	config_get delayon $1 delayon
 	config_get delayoff $1 delayoff
@@ -71,7 +71,11 @@ load_led() {
 		"netdev")
 			[ -n "$dev" ] && {
 				echo $dev > /sys/class/leds/${sysfs}/device_name
-				echo $mode > /sys/class/leds/${sysfs}/mode
+				for m in $mode; do
+					[ -e "/sys/class/leds/${sysfs}/$m" ] && \
+						echo 1 > /sys/class/leds/${sysfs}/$m
+				done
+				echo $interval > /sys/class/leds/${sysfs}/interval
 			}
 			;;
 
@@ -109,6 +113,8 @@ load_led() {
 			config_get speed_mask $1 speed_mask
 			[ -n "$speed_mask" ] && \
 				echo $speed_mask > /sys/class/leds/${sysfs}/speed_mask
+			[ -n "$mode" ] && \
+				echo "$mode" > /sys/class/leds/${sysfs}/mode
 			;;
 		esac
 	}

+ 30 - 11
package/base-files/files/etc/init.d/sysctl

@@ -3,23 +3,42 @@
 
 START=11
 
-set_vm_min_free() {
-	mem="$(grep MemTotal /proc/meminfo  | awk '{print $2}')"
+apply_defaults() {
+	local mem="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)"
+	local min_free frag_low_thresh frag_high_thresh
+
 	if [ "$mem" -gt 65536 ]; then # 128M
-		val=16384
+		min_free=16384
 	elif [ "$mem" -gt 32768 ]; then # 64M
-		val=8192
-	elif [ "$mem" -gt 16384 ]; then # 32M
-		val=1024
+		min_free=8192
 	else
-		return
+		min_free=1024
+		frag_low_thresh=393216
+		frag_high_thresh=524288
+	fi
+
+	sysctl -qw vm.min_free_kbytes="$min_free"
+
+	[ "$frag_low_thresh" ] && sysctl -qw \
+		net.ipv4.ipfrag_low_thresh="$frag_low_thresh" \
+		net.ipv4.ipfrag_high_thresh="$frag_high_thresh" \
+		net.ipv6.ip6frag_low_thresh="$frag_low_thresh" \
+		net.ipv6.ip6frag_high_thresh="$frag_high_thresh" \
+		net.netfilter.nf_conntrack_frag6_low_thresh="$frag_low_thresh" \
+		net.netfilter.nf_conntrack_frag6_high_thresh="$frag_high_thresh"
+
+	# first set default, then all interfaces to avoid races with appearing interfaces
+	if [ -d /proc/sys/net/ipv6/conf ]; then
+		echo 0 > /proc/sys/net/ipv6/conf/default/accept_ra
+		for iface in /proc/sys/net/ipv6/conf/*/accept_ra; do
+			echo 0 > "$iface"
+		done
 	fi
-	sysctl -qw vm.min_free_kbytes="$val"
 }
 
 start() {
-	set_vm_min_free
-	for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
-		[ -f "$CONF" ] && sysctl -p "$CONF" -e >&-
+	apply_defaults
+	for CONF in /etc/sysctl.d/*.conf /etc/sysctl.conf; do
+		[ -f "$CONF" ] && sysctl -e -p "$CONF" >&-
 	done
 }

+ 4 - 8
package/base-files/files/etc/init.d/system

@@ -6,8 +6,8 @@ USE_PROCD=1
 
 validate_system_section()
 {
-	uci_validate_section system system "${1}" \
-		'hostname:string:librecmc' \
+	uci_load_validate system system "$1" "$2" \
+		'hostname:string:libreCMC' \
 		'conloglevel:uinteger' \
 		'buffersize:uinteger' \
 		'timezone:string:UTC' \
@@ -15,11 +15,7 @@ validate_system_section()
 }
 
 system_config() {
-	local cfg="$1"
-
-	local hostname conloglevel buffersize timezone zonename
-
-	validate_system_section "${1}" || {
+	[ "$2" = 0 ] || {
 		echo "validation failed"
 		return 1
 	}
@@ -36,7 +32,7 @@ system_config() {
 
 reload_service() {
 	config_load system
-	config_foreach system_config system
+	config_foreach validate_system_section system system_config
 }
 
 service_triggers()

+ 6 - 1
package/base-files/files/etc/init.d/umount

@@ -1,7 +1,12 @@
 #!/bin/sh /etc/rc.common
 # Copyright (C) 2006 OpenWrt.org
 
-STOP=99
+STOP=90
+
+restart() {
+	:
+}
+
 stop() {
 	sync
 	/bin/umount -a -d -r

+ 8 - 0
package/base-files/files/etc/iproute2/ematch_map

@@ -0,0 +1,8 @@
+# lookup table for ematch kinds
+1	cmp
+2	nbyte
+3	u32
+4	meta
+7	canid
+8	ipset
+9	ipt

+ 1 - 2
package/base-files/files/etc/openwrt_release

@@ -1,8 +1,7 @@
 DISTRIB_ID='%D'
 DISTRIB_RELEASE='%V'
 DISTRIB_REVISION='%R'
-DISTRIB_CODENAME='%n'
 DISTRIB_TARGET='%S'
 DISTRIB_ARCH='%A'
-DISTRIB_DESCRIPTION='%D %N %V %C'
+DISTRIB_DESCRIPTION='%D %V %C'
 DISTRIB_TAINTS='%t'

+ 9 - 2
package/base-files/files/etc/profile

@@ -1,6 +1,9 @@
 #!/bin/sh
+[ -e /tmp/.failsafe ] && export FAILSAFE=1
+
 [ -f /etc/banner ] && cat /etc/banner
-[ -e /tmp/.failsafe ] && cat /etc/banner.failsafe
+[ -n "$FAILSAFE" ] && cat /etc/banner.failsafe
+
 fgrep -sq '/ overlay ro,' /proc/mounts && {
 	echo 'Your JFFS2-partition seems full and overlayfs is mounted read-only.'
 	echo 'Please try to remove files from /overlay/upper/... and reboot!'
@@ -11,7 +14,11 @@ export HOME=$(grep -e "^${USER:-root}:" /etc/passwd | cut -d ":" -f 6)
 export HOME=${HOME:-/root}
 export PS1='\u@\h:\w\$ '
 
-[ "$TERM" = "xterm" ] && export PS1='\[\e]0;\u@\h: \w\a\]'$PS1
+case "$TERM" in
+	xterm*|rxvt*)
+		export PS1='\[\e]0;\u@\h: \w\a\]'$PS1
+		;;
+esac
 
 [ -x /bin/more ] || alias more=less
 [ -x /usr/bin/vim ] && alias vi=vim || alias vim=vi

+ 12 - 0
package/base-files/files/etc/rc.button/reboot

@@ -0,0 +1,12 @@
+#!/bin/sh
+
+[ "${ACTION}" = "released" ] || exit 0
+
+if [ "$SEEN" -ge 5 ]
+then
+	echo "REBOOT" > /dev/console
+	sync
+	reboot
+fi
+
+return 0

+ 1 - 1
package/base-files/files/etc/rc.button/reset

@@ -20,7 +20,7 @@ released)
 		echo "REBOOT" > /dev/console
 		sync
 		reboot
-	elif [ "$SEEN" -gt 5 -a -n "$OVERLAY" ]
+	elif [ "$SEEN" -ge 5 -a -n "$OVERLAY" ]
 	then
 		echo "FACTORY RESET" > /dev/console
 		jffs2reset -y && reboot &

+ 20 - 10
package/base-files/files/etc/rc.common

@@ -17,12 +17,13 @@ stop() {
 }
 
 reload() {
-	return 1
+	restart
 }
 
 restart() {
 	trap '' TERM
 	stop "$@"
+	trap - TERM
 	start "$@"
 }
 
@@ -41,14 +42,15 @@ disable() {
 }
 
 enable() {
+	err=1
 	name="$(basename "${initscript}")"
-	disable
-	[ -n "$START" -o -n "$STOP" ] || {
-		echo "/etc/init.d/$name does not have a START or STOP value"
-		return 1
-	}
-	[ "$START" ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}"
-	[ "$STOP"  ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/K${STOP}${name##K[0-9][0-9]}"
+	[ "$START" ] && \
+		ln -sf "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}" && \
+		err=0
+	[ "$STOP" ] && \
+		ln -sf "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/K${STOP}${name##K[0-9][0-9]}" && \
+		err=0
+	return $err
 }
 
 enabled() {
@@ -68,7 +70,7 @@ Available commands:
 	start	Start the service
 	stop	Stop the service
 	restart	Restart the service
-	reload	Reload configuration files (or restart if that fails)
+	reload	Reload configuration files (or restart if service does not implement reload)
 	enable	Enable service autostart
 	disable	Disable service autostart
 $EXTRA_HELP
@@ -88,6 +90,10 @@ service_triggers() {
 	return 0
 }
 
+service_data() {
+	return 0
+}
+
 service_running() {
 	return 0
 }
@@ -122,12 +128,17 @@ ${INIT_TRACE:+set -x}
 	}
 
 	stop() {
+		procd_lock
 		stop_service "$@"
 		procd_kill "$(basename ${basescript:-$initscript})" "$1"
+		if eval "type service_stopped" 2>/dev/null >/dev/null; then
+			service_stopped
+		fi
 	}
 
 	reload() {
 		if eval "type reload_service" 2>/dev/null >/dev/null; then
+			procd_lock
 			reload_service "$@"
 		else
 			start
@@ -141,5 +152,4 @@ ${INIT_TRACE:+set -x}
 
 ALL_COMMANDS="start stop reload restart boot shutdown enable disable enabled depends ${EXTRA_COMMANDS}"
 list_contains ALL_COMMANDS "$action" || action=help
-[ "$action" = "reload" ] && action='eval reload "$@" || restart "$@" && :'
 $action "$@"

+ 4 - 2
package/base-files/files/etc/services

@@ -29,8 +29,8 @@ kerberos	88/tcp		kerberos5 krb5 kerberos-sec
 kerberos	88/udp		kerberos5 krb5 kerberos-sec
 pop3		110/tcp
 pop3		110/udp
-sunrpc		111/tcp
-sunrpc		111/udp
+sunrpc		111/tcp		rpcbind
+sunrpc		111/udp		rpcbind
 auth		113/tcp		ident
 sftp		115/tcp
 nntp		119/tcp
@@ -76,6 +76,8 @@ afpovertcp	548/tcp
 afpovertcp	548/udp
 nntps		563/tcp		snntp
 nntps		563/udp		snntp
+submission	587/tcp
+submission	587/udp
 ldaps		636/tcp
 ldaps		636/udp
 tinc		655/tcp

+ 1 - 30
package/base-files/files/etc/sysctl.conf

@@ -1,30 +1 @@
-kernel.panic=3
-kernel.core_pattern=/tmp/%e.%t.%p.%s.core
-
-net.ipv4.conf.default.arp_ignore=1
-net.ipv4.conf.all.arp_ignore=1
-net.ipv4.ip_forward=1
-net.ipv4.icmp_echo_ignore_broadcasts=1
-net.ipv4.icmp_ignore_bogus_error_responses=1
-net.ipv4.igmp_max_memberships=100
-net.ipv4.tcp_fin_timeout=30
-net.ipv4.tcp_keepalive_time=120
-net.ipv4.tcp_syncookies=1
-net.ipv4.tcp_timestamps=1
-net.ipv4.tcp_sack=1
-net.ipv4.tcp_dsack=1
-
-net.ipv6.conf.default.forwarding=1
-net.ipv6.conf.all.forwarding=1
-
-net.netfilter.nf_conntrack_acct=1
-net.netfilter.nf_conntrack_checksum=0
-net.netfilter.nf_conntrack_max=16384
-net.netfilter.nf_conntrack_tcp_timeout_established=7440
-net.netfilter.nf_conntrack_udp_timeout=60
-net.netfilter.nf_conntrack_udp_timeout_stream=180
-
-# disable bridge firewalling by default
-net.bridge.bridge-nf-call-arptables=0
-net.bridge.bridge-nf-call-ip6tables=0
-net.bridge.bridge-nf-call-iptables=0
+# Defaults are configured in /etc/sysctl.d/* and can be customized in this file

+ 27 - 0
package/base-files/files/etc/sysctl.d/10-default.conf

@@ -0,0 +1,27 @@
+# Do not edit, changes to this file will be lost on upgrades
+# /etc/sysctl.conf can be used to customize sysctl settings
+
+kernel.panic=3
+kernel.core_pattern=/tmp/%e.%t.%p.%s.core
+fs.suid_dumpable=2
+
+fs.protected_hardlinks=1
+fs.protected_symlinks=1
+
+net.core.bpf_jit_enable=1
+
+net.ipv4.conf.default.arp_ignore=1
+net.ipv4.conf.all.arp_ignore=1
+net.ipv4.ip_forward=1
+net.ipv4.icmp_echo_ignore_broadcasts=1
+net.ipv4.icmp_ignore_bogus_error_responses=1
+net.ipv4.igmp_max_memberships=100
+net.ipv4.tcp_fin_timeout=30
+net.ipv4.tcp_keepalive_time=120
+net.ipv4.tcp_syncookies=1
+net.ipv4.tcp_timestamps=1
+net.ipv4.tcp_sack=1
+net.ipv4.tcp_dsack=1
+
+net.ipv6.conf.default.forwarding=1
+net.ipv6.conf.all.forwarding=1

+ 0 - 16
package/base-files/files/etc/uci-defaults/11_migrate-sysctl

@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if [ ! -f "/rom/etc/sysctl.conf" ] || cmp -s "/rom/etc/sysctl.conf" "/etc/sysctl.conf"; then
-	exit 0
-fi
-
-fingerprint="$(md5sum /etc/sysctl.conf)"
-fingerprint="${fingerprint%% *}"
-
-if [ "$fingerprint" = "1b05ebb41f72cb84e5510573cd4aca26" ] || \
-   [ "$fingerprint" = "62deb895be1a7f496040187b7c930e4e" ]; then
-	logger -t migrate-sysctl "Updating sysctl.conf to use current defaults"
-	cp "/rom/etc/sysctl.conf" "/etc/sysctl.conf"
-fi
-
-exit 0

+ 51 - 46
package/base-files/files/lib/functions.sh

@@ -57,16 +57,16 @@ config () {
 	export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=$(($CONFIG_NUM_SECTIONS + 1))
 	name="${name:-cfg$CONFIG_NUM_SECTIONS}"
 	append CONFIG_SECTIONS "$name"
-	[ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"
 	export ${NO_EXPORT:+-n} CONFIG_SECTION="$name"
-	export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_TYPE=$cfgtype"
+	config_set "$CONFIG_SECTION" "TYPE" "${cfgtype}"
+	[ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"
 }
 
 option () {
 	local varname="$1"; shift
 	local value="$*"
 
-	export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_${varname}=$value"
+	config_set "$CONFIG_SECTION" "${varname}" "${value}"
 	[ -n "$NO_CALLBACK" ] || option_cb "$varname" "$*"
 }
 
@@ -81,7 +81,7 @@ list() {
 	config_set "$CONFIG_SECTION" "${varname}_ITEM$len" "$value"
 	config_set "$CONFIG_SECTION" "${varname}_LENGTH" "$len"
 	append "CONFIG_${CONFIG_SECTION}_${varname}" "$value" "$LIST_SEP"
-	list_cb "$varname" "$*"
+	[ -n "$NO_CALLBACK" ] || list_cb "$varname" "$*"
 }
 
 config_unset() {
@@ -92,7 +92,7 @@ config_unset() {
 # config_get <section> <option>
 config_get() {
 	case "$3" in
-		"") eval echo "\${CONFIG_${1}_${2}:-\${4}}";;
+		"") eval echo "\"\${CONFIG_${1}_${2}:-\${4}}\"";;
 		*)  eval export ${NO_EXPORT:+-n} -- "${1}=\${CONFIG_${2}_${3}:-\${4}}";;
 	esac
 }
@@ -113,11 +113,8 @@ config_set() {
 	local section="$1"
 	local option="$2"
 	local value="$3"
-	local old_section="$CONFIG_SECTION"
 
-	CONFIG_SECTION="$section"
-	option "$option" "$value"
-	CONFIG_SECTION="$old_section"
+	export ${NO_EXPORT:+-n} "CONFIG_${section}_${option}=${value}"
 }
 
 config_foreach() {
@@ -153,34 +150,29 @@ config_list_foreach() {
 	done
 }
 
-insert_modules() {
-	for m in $*; do
-		if [ -f /etc/modules.d/$m ]; then
-			sed 's/^[^#]/insmod &/' /etc/modules.d/$m | ash 2>&- || :
-		else
-			modprobe $m
-		fi
-	done
-}
-
 default_prerm() {
 	local root="${IPKG_INSTROOT}"
-	local name
+	local pkgname="$(basename ${1%.*})"
+	local ret=0
 
-	name=$(basename ${1%.*})
-	[ -f "$root/usr/lib/opkg/info/${name}.prerm-pkg" ] && . "$root/usr/lib/opkg/info/${name}.prerm-pkg"
+	if [ -f "$root/usr/lib/opkg/info/${pkgname}.prerm-pkg" ]; then
+		( . "$root/usr/lib/opkg/info/${pkgname}.prerm-pkg" )
+		ret=$?
+	fi
 
 	local shell="$(which bash)"
-	for i in `cat "$root/usr/lib/opkg/info/${name}.list" | grep "^/etc/init.d/"`; do
+	for i in $(grep -s "^/etc/init.d/" "$root/usr/lib/opkg/info/${pkgname}.list"); do
 		if [ -n "$root" ]; then
 			${shell:-/bin/sh} "$root/etc/rc.common" "$root$i" disable
 		else
 			if [ "$PKG_UPGRADE" != "1" ]; then
 				"$i" disable
 			fi
-			"$i" stop || /bin/true
+			"$i" stop
 		fi
 	done
+
+	return $ret
 }
 
 add_group_and_user() {
@@ -202,7 +194,7 @@ add_group_and_user() {
 			if [ -n "$gname" ] && [ -n "$gid" ]; then
 				group_exists "$gname" || group_add "$gname" "$gid"
 			elif [ -n "$gname" ]; then
-				group_add_next "$gname"; gid=$?
+				gid="$(group_add_next "$gname")"
 			fi
 
 			if [ -n "$uname" ]; then
@@ -221,6 +213,7 @@ add_group_and_user() {
 default_postinst() {
 	local root="${IPKG_INSTROOT}"
 	local pkgname="$(basename ${1%.*})"
+	local filelist="/usr/lib/opkg/info/${pkgname}.list"
 	local ret=0
 
 	add_group_and_user "${pkgname}"
@@ -235,20 +228,29 @@ default_postinst() {
 		rm -fR $root/rootfs-overlay/
 	fi
 
-	if [ -z "$root" ] && grep -q -s "^/etc/uci-defaults/" "/usr/lib/opkg/info/${pkgname}.list"; then
-		. /lib/functions/system.sh
-		[ -d /tmp/.uci ] || mkdir -p /tmp/.uci
-		for i in $(sed -ne 's!^/etc/uci-defaults/!!p' "/usr/lib/opkg/info/${pkgname}.list"); do (
-			cd /etc/uci-defaults
-			[ -f "$i" ] && . ./"$i" && rm -f "$i"
-		) done
-		uci commit
-	fi
+	if [ -z "$root" ]; then
+		if grep -m1 -q -s "^/etc/modules.d/" "$filelist"; then
+			kmodloader
+		fi
+
+		if grep -m1 -q -s "^/etc/sysctl.d/" "$filelist"; then
+			/etc/init.d/sysctl restart
+		fi
+
+		if grep -m1 -q -s "^/etc/uci-defaults/" "$filelist"; then
+			. /lib/functions/system.sh
+			[ -d /tmp/.uci ] || mkdir -p /tmp/.uci
+			for i in $(grep -s "^/etc/uci-defaults/" "$filelist"); do
+				( [ -f "$i" ] && cd "$(dirname $i)" && . "$i" ) && rm -f "$i"
+			done
+			uci commit
+		fi
 
-	[ -n "$root" ] || rm -f /tmp/luci-indexcache 2>/dev/null
+		rm -f /tmp/luci-indexcache
+	fi
 
 	local shell="$(which bash)"
-	for i in $(grep -s "^/etc/init.d/" "$root/usr/lib/opkg/info/${pkgname}.list"); do
+	for i in $(grep -s "^/etc/init.d/" "$root$filelist"); do
 		if [ -n "$root" ]; then
 			${shell:-/bin/sh} "$root/etc/rc.common" "$root$i" enable
 		else
@@ -292,9 +294,7 @@ group_add() {
 	[ -f "${IPKG_INSTROOT}/etc/group" ] || return 1
 	[ -n "$IPKG_INSTROOT" ] || lock /var/lock/group
 	echo "${name}:x:${gid}:" >> ${IPKG_INSTROOT}/etc/group
-	rc=$?
 	[ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/group
-	return $rc
 }
 
 group_exists() {
@@ -304,14 +304,17 @@ group_exists() {
 group_add_next() {
 	local gid gids
 	gid=$(grep -s "^${1}:" ${IPKG_INSTROOT}/etc/group | cut -d: -f3)
-	[ -n "$gid" ] && return $gid
+	if [ -n "$gid" ]; then
+		echo $gid
+		return
+	fi
 	gids=$(cat ${IPKG_INSTROOT}/etc/group | cut -d: -f3)
-	gid=100
-	while [ -n "$(echo $gids | grep $gid)" ] ; do
+	gid=65536
+	while [ -n "$(echo "$gids" | grep "^$gid$")" ] ; do
 	        gid=$((gid + 1))
 	done
 	group_add $1 $gid
-	return $gid
+	echo $gid
 }
 
 group_add_user() {
@@ -334,8 +337,8 @@ user_add() {
 	local rc
 	[ -z "$uid" ] && {
 		uids=$(cat ${IPKG_INSTROOT}/etc/passwd | cut -d: -f3)
-		uid=100
-		while [ -n "$(echo $uids | grep $uid)" ] ; do
+		uid=65536
+		while [ -n "$(echo "$uids" | grep "^$uid$")" ] ; do
 		        uid=$((uid + 1))
 		done
 	}
@@ -344,13 +347,15 @@ user_add() {
 	[ -n "$IPKG_INSTROOT" ] || lock /var/lock/passwd
 	echo "${name}:x:${uid}:${gid}:${desc}:${home}:${shell}" >> ${IPKG_INSTROOT}/etc/passwd
 	echo "${name}:x:0:0:99999:7:::" >> ${IPKG_INSTROOT}/etc/shadow
-	rc=$?
 	[ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/passwd
-	return $rc
 }
 
 user_exists() {
 	grep -qs "^${1}:" ${IPKG_INSTROOT}/etc/passwd
 }
 
+board_name() {
+	[ -e /tmp/sysinfo/board_name ] && cat /tmp/sysinfo/board_name || echo "generic"
+}
+
 [ -z "$IPKG_INSTROOT" -a -f /lib/config/uci.sh ] && . /lib/config/uci.sh

+ 14 - 0
package/base-files/files/lib/functions/leds.sh

@@ -1,6 +1,20 @@
 #!/bin/sh
 # Copyright (C) 2013 OpenWrt.org
 
+get_dt_led() {
+	local label
+	local ledpath
+	local basepath="/proc/device-tree"
+	local nodepath="$basepath/aliases/led-$1"
+
+	[ -f "$nodepath" ] && ledpath=$(cat "$nodepath")
+	[ -n "$ledpath" ] && \
+		label=$(cat "$basepath$ledpath/label" 2>/dev/null) || \
+		label=$(cat "$basepath$ledpath/chan-name" 2>/dev/null)
+
+	echo "$label"
+}
+
 led_set_attr() {
 	[ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2"
 }

+ 39 - 0
package/base-files/files/lib/functions/migrations.sh

@@ -0,0 +1,39 @@
+#!/bin/sh
+
+. /lib/functions.sh
+
+migrate_led_sysfs() {
+	local cfg="$1"; shift
+	local tuples="$@"
+	local sysfs
+	local name
+
+	config_get sysfs ${cfg} sysfs
+	config_get name ${cfg} name
+
+	[ -z "${sysfs}" ] && return
+
+	for tuple in ${tuples}; do
+		local old=${tuple%=*}
+		local new=${tuple#*=}
+		local new_sysfs
+
+		new_sysfs=$(echo ${sysfs} | sed "s/${old}/${new}/")
+
+		[ "${new_sysfs}" = "${sysfs}" ] && continue
+
+		uci set system.${cfg}.sysfs="${new_sysfs}"
+
+		logger -t led-migration "sysfs option of LED \"${name}\" updated to ${new_sysfs}"
+	done;
+}
+
+migrate_leds() {
+	config_load system
+	config_foreach migrate_led_sysfs led "$@"
+}
+
+migrations_apply() {
+	local realm="$1"
+	[ -n "$(uci changes ${realm})" ] && uci -q commit ${realm}
+}

+ 19 - 3
package/base-files/files/lib/functions/network.sh

@@ -6,10 +6,16 @@
 __network_ifstatus() {
 	local __tmp
 
-	[ -z "$__NETWORK_CACHE" ] && \
-		export __NETWORK_CACHE="$(ubus call network.interface dump)"
+	[ -z "$__NETWORK_CACHE" ] && {
+		__tmp="$(ubus call network.interface dump 2>&1)"
+		case "$?" in
+			4) : ;;
+			0) export __NETWORK_CACHE="$__tmp" ;;
+			*) echo "$__tmp" >&2 ;;
+		esac
+	}
 
-	__tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "$__NETWORK_CACHE" -e "$1=@.interface${2:+[@.interface='$2']}$3")"
+	__tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "${__NETWORK_CACHE:-{}}" -e "$1=@.interface${2:+[@.interface='$2']}$3")"
 
 	[ -z "$__tmp" ] && \
 		unset "$1" && \
@@ -265,6 +271,16 @@ network_is_up()
 # 2: interface
 network_get_protocol() { __network_ifstatus "$1" "$2" ".proto"; }
 
+# determine the uptime of the given logical interface
+# 1: destination variable
+# 2: interface
+network_get_uptime() { __network_ifstatus "$1" "$2" ".uptime"; }
+
+# determine the metric of the given logical interface
+# 1: destination variable
+# 2: interface
+network_get_metric() { __network_ifstatus "$1" "$2" ".metric"; }
+
 # determine the layer 3 linux network device of the given logical interface
 # 1: destination variable
 # 2: interface

+ 40 - 19
package/base-files/files/lib/functions/system.sh

@@ -1,5 +1,17 @@
 # Copyright (C) 2006-2013 OpenWrt.org
 
+get_mac_binary() {
+	local path="$1"
+	local offset="$2"
+
+	if ! [ -e "$path" ]; then
+		echo "get_mac_binary: file $path not found!" >&2
+		return
+	fi
+
+	hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' $path 2>/dev/null
+}
+
 find_mtd_chardev() {
 	local INDEX=$(find_mtd_index "$1")
 	local PREFIX=/dev/mtd
@@ -8,8 +20,7 @@ find_mtd_chardev() {
 	echo "${INDEX:+$PREFIX$INDEX}"
 }
 
-mtd_get_mac_ascii()
-{
+mtd_get_mac_ascii() {
 	local mtdname="$1"
 	local key="$2"
 	local part
@@ -27,18 +38,36 @@ mtd_get_mac_ascii()
 	[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
 }
 
-mtd_get_mac_binary() {
-	local mtdname="$1"
-	local offset="$2"
+mtd_get_mac_text() {
+	local mtdname=$1
+	local offset=$2
 	local part
+	local mac_dirty
 
 	part=$(find_mtd_part "$mtdname")
 	if [ -z "$part" ]; then
-		echo "mtd_get_mac_binary: partition $mtdname not found!" >&2
+		echo "mtd_get_mac_text: partition $mtdname not found!" >&2
 		return
 	fi
 
-	hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' $part 2>/dev/null
+	if [ -z "$offset" ]; then
+		echo "mtd_get_mac_text: offset missing!" >&2
+		return
+	fi
+
+	mac_dirty=$(dd if="$part" bs=1 skip="$offset" count=17 2>/dev/null)
+
+	# "canonicalize" mac
+	[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
+}
+
+mtd_get_mac_binary() {
+	local mtdname="$1"
+	local offset="$2"
+	local part
+
+	part=$(find_mtd_part "$mtdname")
+	get_mac_binary "$part" "$offset"
 }
 
 mtd_get_mac_binary_ubi() {
@@ -50,12 +79,7 @@ mtd_get_mac_binary_ubi() {
 	local ubidev=$(nand_find_ubi $CI_UBIPART)
 	local part=$(nand_find_volume $ubidev $1)
 
-	if [ -z "$part" ]; then
-		echo "mtd_get_mac_binary: ubi volume $mtdname not found!" >&2
-		return
-	fi
-
-	hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' /dev/$part 2>/dev/null
+	get_mac_binary "/dev/$part" "$offset"
 }
 
 mtd_get_part_size() {
@@ -80,22 +104,19 @@ macaddr_add() {
 	echo $oui:$nic
 }
 
-macaddr_setbit_la()
-{
+macaddr_setbit_la() {
 	local mac=$1
 
 	printf "%02x:%s" $((0x${mac%%:*} | 0x02)) ${mac#*:}
 }
 
-macaddr_2bin()
-{
+macaddr_2bin() {
 	local mac=$1
 
 	echo -ne \\x${mac//:/\\x}
 }
 
-macaddr_canonicalize()
-{
+macaddr_canonicalize() {
 	local mac="$1"
 	local canon=""
 

+ 145 - 193
package/base-files/files/lib/functions/uci-defaults.sh

@@ -27,30 +27,33 @@ json_select_object() {
 	json_select "$1"
 }
 
-_ucidef_set_interface() {
-	local name="$1"
-	local iface="$2"
-	local proto="$3"
+ucidef_set_interface() {
+	local network=$1; shift
 
-	json_select_object "$name"
-	json_add_string ifname "$iface"
-
-	if ! json_is_a protocol string || [ -n "$proto" ]; then
-		case "$proto" in
-			static|dhcp|none|pppoe) : ;;
-			*)
-				case "$name" in
-					lan) proto="static" ;;
-					wan) proto="dhcp" ;;
-					*) proto="none" ;;
-				esac
-			;;
-		esac
+	[ -z "$network" ] && return
+
+	json_select_object network
+	json_select_object "$network"
+
+	while [ -n "$1" ]; do
+		local opt=$1; shift
+		local val=$1; shift
+
+		[ -n "$opt" -a -n "$val" ] || break
 
-		json_add_string protocol "$proto"
+		json_add_string "$opt" "$val"
+	done
+
+	if ! json_is_a protocol string; then
+		case "$network" in
+			lan) json_add_string protocol static ;;
+			wan) json_add_string protocol dhcp ;;
+			*) json_add_string protocol none ;;
+		esac
 	fi
 
 	json_select ..
+	json_select ..
 }
 
 ucidef_set_board_id() {
@@ -66,31 +69,19 @@ ucidef_set_model_name() {
 }
 
 ucidef_set_interface_lan() {
-	json_select_object network
-	_ucidef_set_interface lan "$@"
-	json_select ..
+	ucidef_set_interface "lan" ifname "$1" protocol "${2:-static}"
 }
 
 ucidef_set_interface_wan() {
-	json_select_object network
-	_ucidef_set_interface wan "$@"
-	json_select ..
+	ucidef_set_interface "wan" ifname "$1" protocol "${2:-dhcp}"
 }
 
 ucidef_set_interfaces_lan_wan() {
 	local lan_if="$1"
 	local wan_if="$2"
 
-	json_select_object network
-	_ucidef_set_interface lan "$lan_if"
-	_ucidef_set_interface wan "$wan_if"
-	json_select ..
-}
-
-ucidef_set_interface_raw() {
-	json_select_object network
-	_ucidef_set_interface "$@"
-	json_select ..
+	ucidef_set_interface_lan "$lan_if"
+	ucidef_set_interface_wan "$wan_if"
 }
 
 _ucidef_add_switch_port() {
@@ -160,7 +151,7 @@ _ucidef_finish_switch_roles() {
 					json_select ..
 				json_select ..
 
-				if [ $n_vlan -gt $n_cpu -o ${need_tag:-0} -eq 1 ]; then
+				if [ ${need_tag:-0} -eq 1 -o ${want_untag:-0} -ne 1 ]; then
 					num="${num}t"
 					device="${device}.${index}"
 				fi
@@ -185,12 +176,25 @@ _ucidef_finish_switch_roles() {
 					devices="${devices:+$devices }$device"
 				fi
 			json_select ..
-
-			_ucidef_set_interface "$role" "$devices"
 		json_select ..
+
+		ucidef_set_interface "$role" ifname "$devices"
 	done
 }
 
+ucidef_set_ar8xxx_switch_mib() {
+	local name="$1"
+	local type="$2"
+	local interval="$3"
+
+	json_select_object switch
+		json_select_object "$name"
+			json_add_int ar8xxx_mib_type $type
+			json_add_int ar8xxx_mib_poll_interval $interval
+		json_select ..
+	json_select ..
+}
+
 ucidef_add_switch() {
 	local name="$1"; shift
 	local port num role device index need_tag prev_role
@@ -300,18 +304,7 @@ ucidef_set_interface_macaddr() {
 	local network="$1"
 	local macaddr="$2"
 
-	json_select_object network
-
-	json_select "$network"
-	[ $? -eq 0 ] || {
-		json_select ..
-		return
-	}
-
-	json_add_string macaddr "$macaddr"
-	json_select ..
-
-	json_select ..
+	ucidef_set_interface "$network" macaddr "$macaddr"
 }
 
 ucidef_add_atm_bridge() {
@@ -319,6 +312,7 @@ ucidef_add_atm_bridge() {
 	local vci="$2"
 	local encaps="$3"
 	local payload="$4"
+	local nameprefix="$5"
 
 	json_select_object dsl
 		json_select_object atmbridge
@@ -326,6 +320,7 @@ ucidef_add_atm_bridge() {
 			json_add_int vci "$vci"
 			json_add_string encaps "$encaps"
 			json_add_string payload "$payload"
+			json_add_string nameprefix "$nameprefix"
 		json_select ..
 	json_select ..
 }
@@ -358,236 +353,194 @@ ucidef_add_vdsl_modem() {
 	json_select ..
 }
 
-ucidef_set_led_netdev() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local dev="$4"
-	local mode="${5:-link tx rx}"
-
-	json_select_object led
-
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type netdev
-	json_add_string sysfs "$sysfs"
-	json_add_string device "$dev"
-	json_add_string mode "$mode"
-	json_select ..
-
-	json_select ..
+ucidef_set_led_ataport() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" ata"$4"
 }
 
-ucidef_set_led_usbdev() {
+_ucidef_set_led_common() {
 	local cfg="led_$1"
 	local name="$2"
 	local sysfs="$3"
-	local dev="$4"
 
 	json_select_object led
 
 	json_select_object "$1"
 	json_add_string name "$name"
-	json_add_string type usb
 	json_add_string sysfs "$sysfs"
-	json_add_string device "$dev"
-	json_select ..
-
-	json_select ..
 }
 
-ucidef_set_led_usbport() {
-	local obj="$1"
-	local name="$2"
-	local sysfs="$3"
-	shift
-	shift
-	shift
+ucidef_set_led_default() {
+	local default="$4"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$obj"
-	json_add_string name "$name"
-	json_add_string type usbport
-	json_add_string sysfs "$sysfs"
-	json_select_array ports
-		for port in "$@"; do
-			json_add_string port "$port"
-		done
-	json_select ..
+	json_add_string default "$default"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_wlan() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local trigger="$4"
+ucidef_set_led_gpio() {
+	local gpio="$4"
+	local inverted="$5"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type trigger
-	json_add_string sysfs "$sysfs"
 	json_add_string trigger "$trigger"
+	json_add_string type gpio
+	json_add_int gpio "$gpio"
+	json_add_boolean inverted "$inverted"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_switch() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local trigger="$4"
-	local port_mask="$5"
-	local speed_mask="$6"
+ucidef_set_led_ide() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" ide-disk
+}
 
-	json_select_object led
+ucidef_set_led_netdev() {
+	local dev="$4"
+	local mode="${5:-link tx rx}"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type switch
-	json_add_string sysfs "$sysfs"
-	json_add_string trigger "$trigger"
-	json_add_string port_mask "$port_mask"
-	json_add_string speed_mask "$speed_mask"
+	_ucidef_set_led_common "$1" "$2" "$3"
+
+	json_add_string type netdev
+	json_add_string device "$dev"
+	json_add_string mode "$mode"
 	json_select ..
 
 	json_select ..
 }
 
+ucidef_set_led_oneshot() {
+	_ucidef_set_led_timer $1 $2 $3 "oneshot" $4 $5
+}
+
 ucidef_set_led_portstate() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
 	local port_state="$4"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type portstate
-	json_add_string sysfs "$sysfs"
 	json_add_string trigger port_state
+	json_add_string type portstate
 	json_add_string port_state "$port_state"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_default() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local default="$4"
+ucidef_set_led_rssi() {
+	local iface="$4"
+	local minq="$5"
+	local maxq="$6"
+	local offset="${7:-0}"
+	local factor="${8:-1}"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
+	json_add_string type rssi
 	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_string default "$default"
+	json_add_string iface "$iface"
+	json_add_string minq "$minq"
+	json_add_string maxq "$maxq"
+	json_add_string offset "$offset"
+	json_add_string factor "$factor"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_gpio() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local gpio="$4"
-	local inverted="$5"
+ucidef_set_led_switch() {
+	local trigger_name="$4"
+	local port_mask="$5"
+	local speed_mask="$6"
+	local mode="$7"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string type gpio
-	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_string trigger "$trigger"
-	json_add_int gpio "$gpio"
-	json_add_boolean inverted "$inverted"
+	json_add_string trigger "$trigger_name"
+	json_add_string type switch
+	json_add_string mode "$mode"
+	json_add_string port_mask "$port_mask"
+	json_add_string speed_mask "$speed_mask"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_ide() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
+_ucidef_set_led_timer() {
+	local trigger_name="$4"
+	local delayon="$5"
+	local delayoff="$6"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_string trigger ide-disk
+	json_add_string type "$trigger_name"
+	json_add_string trigger "$trigger_name"
+	json_add_int delayon "$delayon"
+	json_add_int delayoff "$delayoff"
 	json_select ..
 
 	json_select ..
 }
 
-__ucidef_set_led_timer() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local trigger="$4"
-	local delayon="$5"
-	local delayoff="$6"
+ucidef_set_led_timer() {
+	_ucidef_set_led_timer $1 $2 $3 "timer" $4 $5
+}
 
-	json_select_object led
+_ucidef_set_led_trigger() {
+	local trigger_name="$4"
 
-	json_select_object "$1"
-	json_add_string type "$trigger"
-	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_int delayon "$delayon"
-	json_add_int delayoff "$delayoff"
+	_ucidef_set_led_common "$1" "$2" "$3"
+
+	json_add_string trigger "$trigger_name"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_oneshot() {
-	__ucidef_set_led_timer $1 $2 $3 "oneshot" $4 $5
+ucidef_set_led_usbdev() {
+	local dev="$4"
+
+	_ucidef_set_led_common "$1" "$2" "$3"
+
+	json_add_string type usb
+	json_add_string device "$dev"
+	json_select ..
+
+	json_select ..
 }
 
-ucidef_set_led_timer() {
-	__ucidef_set_led_timer $1 $2 $3 "timer" $4 $5
+ucidef_set_led_usbhost() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" usb-host
 }
 
-ucidef_set_led_rssi() {
-	local cfg="led_$1"
+ucidef_set_led_usbport() {
+	local obj="$1"
 	local name="$2"
 	local sysfs="$3"
-	local iface="$4"
-	local minq="$5"
-	local maxq="$6"
-	local offset="$7"
-	local factor="$8"
+	shift
+	shift
+	shift
 
-	json_select_object led
+	_ucidef_set_led_common "$obj" "$name" "$sysfs"
 
-	json_select_object "$1"
-	json_add_string type rssi
-	json_add_string name "$name"
-	json_add_string iface "$iface"
-	json_add_string sysfs "$sysfs"
-	json_add_string minq "$minq"
-	json_add_string maxq "$maxq"
-	json_add_string offset "$offset"
-	json_add_string factor "$factor"
+	json_add_string type usbport
+	json_select_array ports
+		for port in "$@"; do
+			json_add_string port "$port"
+		done
+	json_select ..
 	json_select ..
 
 	json_select ..
 }
 
+ucidef_set_led_wlan() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" "$4"
+}
+
 ucidef_set_rssimon() {
 	local dev="$1"
 	local refresh="$2"
@@ -601,7 +554,6 @@ ucidef_set_rssimon() {
 	json_select ..
 
 	json_select ..
-
 }
 
 ucidef_add_gpio_switch() {

+ 0 - 0
package/base-files/files/lib/preinit/10_sysinfo → package/base-files/files/lib/preinit/02_sysinfo


+ 5 - 7
package/base-files/files/lib/preinit/10_indicate_preinit

@@ -43,7 +43,10 @@ preinit_config_switch() {
 			json_select ..
 
 			if [ "$device" = "$lan_if" ]; then
-				swconfig dev $name set reset $reset
+				if [ "$reset" -eq "1" ]; then
+					swconfig dev $name set reset
+				fi
+
 				swconfig dev $name set enable_vlan $enable
 				swconfig dev $name vlan $role set ports "$ports"
 				swconfig dev $name set apply
@@ -110,7 +113,7 @@ preinit_ip() {
 		preinit_config_board
 	fi
 
-	preinit_net_echo "Doing Lede Preinit\n"
+	preinit_net_echo "Doing libreCMC Preinit\n"
 }
 
 preinit_ip_deconfig() {
@@ -144,11 +147,6 @@ preinit_net_echo() {
 	}
 }
 
-preinit_echo() {
-	preinit_net_echo $1
-	echo $1
-}
-
 pi_indicate_preinit() {
 	set_state preinit
 }

+ 1 - 1
package/base-files/files/lib/preinit/30_failsafe_wait

@@ -82,7 +82,7 @@ fs_wait_for_key () {
 
 failsafe_wait() {
 	FAILSAFE=
-	[ "$pi_preinit_no_failsafe" == "y" ] && {
+	[ "$pi_preinit_no_failsafe" = "y" ] && {
 		fs_wait_for_key "" "" $fs_failsafe_wait_timeout
 		return
 	}

+ 5 - 1
package/base-files/files/lib/preinit/40_run_failsafe_hook

@@ -5,8 +5,12 @@
 run_failsafe_hook() {
     [ "$pi_preinit_no_failsafe" = "y" ] && return
     if [ "$FAILSAFE" = "true" ]; then
+	lock /tmp/.failsafe
 	boot_run_hook failsafe
-	lock -w /tmp/.failsafe
+	while [ ! -e /tmp/sysupgrade ]; do
+	    lock -w /tmp/.failsafe
+	done
+	exit
     fi
 }
 

+ 0 - 24
package/base-files/files/lib/preinit/81_urandom_seed

@@ -1,24 +0,0 @@
-#!/bin/sh
-
-log_urandom_seed() {
-    echo "urandom-seed: $1" > /dev/kmsg
-}
-
-_do_urandom_seed() {
-    [ -f "$1" ] || { log_urandom_seed "Seed file not found ($1)"; return; }
-    [ -O "$1" -a -G "$1" -a ! -x "$1" ] || { log_urandom_seed "Wrong owner / permissions for $1"; return; }
-
-    log_urandom_seed "Seeding with $1"
-    cat "$1" > /dev/urandom
-}
-
-do_urandom_seed() {
-    [ -c /dev/urandom ] || { log_urandom_seed "Something is wrong with /dev/urandom"; return; }
-
-    _do_urandom_seed "/etc/urandom.seed"
-
-    SEED="$(uci -q get system.@system[0].urandom_seed)"
-    [ "${SEED:0:1}" == "/" -a "$SEED" != "/etc/urandom.seed" ] && _do_urandom_seed "$SEED"
-}
-
-boot_hook_add preinit_main do_urandom_seed

+ 7 - 4
package/base-files/files/lib/preinit/99_10_failsafe_login

@@ -8,10 +8,13 @@ failsafe_netlogin () {
 }
 
 failsafe_shell() {
-	lock /tmp/.failsafe
-	ash --login
-	echo "Please reboot system when done with failsafe network logins"
-	while true; do sleep 1; done
+	local console="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | head -1 | sed -e 's/^console=//' -e 's/,.*//')"
+	[ -n "$console" ] || console=console
+	[ -c "/dev/$console" ] || return 0
+	while true; do
+		ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console"
+		sleep 1
+	done &
 }
 
 boot_hook_add failsafe failsafe_netlogin

+ 79 - 194
package/base-files/files/lib/upgrade/common.sh

@@ -2,147 +2,39 @@
 
 RAM_ROOT=/tmp/root
 
+export BACKUP_FILE=sysupgrade.tgz	# file extracted by preinit
+
 [ -x /usr/bin/ldd ] || ldd() { LD_TRACE_LOADED_OBJECTS=1 $*; }
 libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; }
 
 install_file() { # <file> [ <file> ... ]
+	local target dest dir
 	for file in "$@"; do
+		if [ -L "$file" ]; then
+			target="$(readlink -f "$file")"
+			dest="$RAM_ROOT/$file"
+			[ ! -f "$dest" ] && {
+				dir="$(dirname "$dest")"
+				mkdir -p "$dir"
+				ln -s "$target" "$dest"
+			}
+			file="$target"
+		fi
 		dest="$RAM_ROOT/$file"
-		[ -f $file -a ! -f $dest ] && {
-			dir="$(dirname $dest)"
+		[ -f "$file" -a ! -f "$dest" ] && {
+			dir="$(dirname "$dest")"
 			mkdir -p "$dir"
-			cp $file $dest
+			cp "$file" "$dest"
 		}
 	done
 }
 
-install_bin() { # <file> [ <symlink> ... ]
+install_bin() {
+	local src files
 	src=$1
 	files=$1
 	[ -x "$src" ] && files="$src $(libs $src)"
 	install_file $files
-	shift
-	for link in "$@"; do {
-		dest="$RAM_ROOT/$link"
-		dir="$(dirname $dest)"
-		mkdir -p "$dir"
-		[ -f "$dest" ] || ln -s $src $dest
-	}; done
-}
-
-supivot() { # <new_root> <old_root>
-	/bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
-	mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
-	/bin/mount -o noatime,move /proc $1/proc && \
-	pivot_root $1 $1$2 || {
-		/bin/umount -l $1 $1
-		return 1
-	}
-
-	/bin/mount -o noatime,move $2/sys /sys
-	/bin/mount -o noatime,move $2/dev /dev
-	/bin/mount -o noatime,move $2/tmp /tmp
-	/bin/mount -o noatime,move $2/overlay /overlay 2>&-
-	return 0
-}
-
-run_ramfs() { # <command> [...]
-	install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount	\
-		/sbin/pivot_root /sbin/reboot /bin/sync /bin/dd	/bin/grep       \
-		/bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" /bin/dd	\
-		/bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump		\
-		/bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \
-		/bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir	\
-		/bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \
-		/bin/mknod
-
-	install_bin /bin/uclient-fetch /bin/wget
-	install_bin /sbin/mtd
-	install_bin /sbin/mount_root
-	install_bin /sbin/snapshot
-	install_bin /sbin/snapshot_tool
-	install_bin /usr/sbin/ubiupdatevol
-	install_bin /usr/sbin/ubiattach
-	install_bin /usr/sbin/ubiblock
-	install_bin /usr/sbin/ubiformat
-	install_bin /usr/sbin/ubidetach
-	install_bin /usr/sbin/ubirsvol
-	install_bin /usr/sbin/ubirmvol
-	install_bin /usr/sbin/ubimkvol
-	install_bin /usr/sbin/partx
-	install_bin /usr/sbin/losetup
-	install_bin /usr/sbin/mkfs.ext4
-	for file in $RAMFS_COPY_BIN; do
-		install_bin ${file//:/ }
-	done
-	install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA
-
-	[ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
-
-	supivot $RAM_ROOT /mnt || {
-		echo "Failed to switch over to ramfs. Please reboot."
-		exit 1
-	}
-
-	/bin/mount -o remount,ro /mnt
-	/bin/umount -l /mnt
-
-	grep /overlay /proc/mounts > /dev/null && {
-		/bin/mount -o noatime,remount,ro /overlay
-		/bin/umount -l /overlay
-	}
-
-	# spawn a new shell from ramdisk to reduce the probability of cache issues
-	exec /bin/busybox ash -c "$*"
-}
-
-kill_remaining() { # [ <signal> ]
-	local sig="${1:-TERM}"
-	echo -n "Sending $sig to remaining processes ... "
-
-	local my_pid=$$
-	local my_ppid=$(cut -d' ' -f4  /proc/$my_pid/stat)
-	local my_ppisupgraded=
-	grep -q upgraded /proc/$my_ppid/cmdline >/dev/null && {
-		local my_ppisupgraded=1
-	}
-	
-	local stat
-	for stat in /proc/[0-9]*/stat; do
-		[ -f "$stat" ] || continue
-
-		local pid name state ppid rest
-		read pid name state ppid rest < $stat
-		name="${name#(}"; name="${name%)}"
-
-		local cmdline
-		read cmdline < /proc/$pid/cmdline
-
-		# Skip kernel threads
-		[ -n "$cmdline" ] || continue
-
-		if [ $$ -eq 1 ] || [ $my_ppid -eq 1 ] && [ -n "$my_ppisupgraded" ]; then
-			# Running as init process, kill everything except me
-			if [ $pid -ne $$ ] && [ $pid -ne $my_ppid ]; then
-				echo -n "$name "
-				kill -$sig $pid 2>/dev/null
-			fi
-		else 
-			case "$name" in
-				# Skip essential services
-				*procd*|*ash*|*init*|*watchdog*|*ssh*|*dropbear*|*telnet*|*login*|*hostapd*|*wpa_supplicant*|*nas*|*relayd*) : ;;
-
-				# Killable process
-				*)
-					if [ $pid -ne $$ ] && [ $ppid -ne $$ ]; then
-						echo -n "$name "
-						kill -$sig $pid 2>/dev/null
-					fi
-				;;
-			esac
-		fi
-	done
-	echo ""
 }
 
 run_hooks() {
@@ -175,28 +67,31 @@ v() {
 	[ "$VERBOSE" -ge 1 ] && echo "$@"
 }
 
+json_string() {
+	local v="$1"
+	v="${v//\\/\\\\}"
+	v="${v//\"/\\\"}"
+	echo "\"$v\""
+}
+
 rootfs_type() {
 	/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
 }
 
 get_image() { # <source> [ <command> ]
 	local from="$1"
-	local conc="$2"
-	local cmd
-
-	case "$from" in
-		http://*|ftp://*) cmd="wget -O- -q";;
-		*) cmd="cat";;
-	esac
-	if [ -z "$conc" ]; then
-		local magic="$(eval $cmd \"$from\" 2>/dev/null | dd bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
+	local cmd="$2"
+
+	if [ -z "$cmd" ]; then
+		local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
 		case "$magic" in
-			1f8b) conc="zcat";;
-			425a) conc="bzcat";;
+			1f8b) cmd="zcat";;
+			425a) cmd="bzcat";;
+			*) cmd="cat";;
 		esac
 	fi
 
-	eval "$cmd \"$from\" 2>/dev/null ${conc:+| $conc}"
+	cat "$from" 2>/dev/null | $cmd
 }
 
 get_magic_word() {
@@ -208,41 +103,48 @@ get_magic_long() {
 }
 
 export_bootdevice() {
-	local cmdline uuid disk uevent
+	local cmdline bootdisk rootpart uuid blockdev uevent line
 	local MAJOR MINOR DEVNAME DEVTYPE
 
 	if read cmdline < /proc/cmdline; then
 		case "$cmdline" in
 			*block2mtd=*)
-				disk="${cmdline##*block2mtd=}"
-				disk="${disk%%,*}"
+				bootdisk="${cmdline##*block2mtd=}"
+				bootdisk="${bootdisk%%,*}"
 			;;
 			*root=*)
-				disk="${cmdline##*root=}"
-				disk="${disk%% *}"
+				rootpart="${cmdline##*root=}"
+				rootpart="${rootpart%% *}"
 			;;
 		esac
 
-		case "$disk" in
-			PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02)
-				uuid="${disk#PARTUUID=}"
-				uuid="${uuid%-02}"
-				for disk in $(find /dev -type b); do
-					set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "')
+		case "$bootdisk" in
+			/dev/*)
+				uevent="/sys/class/block/${bootdisk##*/}/uevent"
+			;;
+		esac
+
+		case "$rootpart" in
+			PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-[a-f0-9][a-f0-9])
+				uuid="${rootpart#PARTUUID=}"
+				uuid="${uuid%-[a-f0-9][a-f0-9]}"
+				for blockdev in $(find /dev -type b); do
+					set -- $(dd if=$blockdev bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "')
 					if [ "$4$3$2$1" = "$uuid" ]; then
-						uevent="/sys/class/block/${disk##*/}/uevent"
+						uevent="/sys/class/block/${blockdev##*/}/uevent"
 						break
 					fi
 				done
 			;;
 			/dev/*)
-				uevent="/sys/class/block/${disk##*/}/uevent"
+				uevent="/sys/class/block/${rootpart##*/}/../uevent"
 			;;
 		esac
 
 		if [ -e "$uevent" ]; then
-			. "$uevent"
-
+			while read line; do
+				export -n "$line"
+			done < "$uevent"
 			export BOOTDEV_MAJOR=$MAJOR
 			export BOOTDEV_MINOR=$MINOR
 			return 0
@@ -254,10 +156,12 @@ export_bootdevice() {
 
 export_partdevice() {
 	local var="$1" offset="$2"
-	local uevent MAJOR MINOR DEVNAME DEVTYPE
+	local uevent line MAJOR MINOR DEVNAME DEVTYPE
 
 	for uevent in /sys/class/block/*/uevent; do
-		. "$uevent"
+		while read line; do
+			export -n "$line"
+		done < "$uevent"
 		if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
 			export "$var=$DEVNAME"
 			return 0
@@ -267,6 +171,14 @@ export_partdevice() {
 	return 1
 }
 
+hex_le32_to_cpu() {
+	[ "$(echo 01 | hexdump -v -n 2 -e '/2 "%x"')" = "3031" ] && {
+		echo "${1:0:2}${1:8:2}${1:6:2}${1:4:2}${1:2:2}"
+		return
+	}
+	echo "$@"
+}
+
 get_partitions() { # <device> <filename>
 	local disk="$1"
 	local filename="$2"
@@ -274,8 +186,8 @@ get_partitions() { # <device> <filename>
 	if [ -b "$disk" -o -f "$disk" ]; then
 		v "Reading partition table from $filename..."
 
-		local magic="$(hexdump -v -n 2 -s 0x1FE -e '1/2 "0x%04X"' "$disk")"
-		if [ "$magic" != 0xAA55 ]; then
+		local magic=$(dd if="$disk" bs=2 count=1 skip=255 2>/dev/null)
+		if [ "$magic" != $'\x55\xAA' ]; then
 			v "Invalid partition table on $disk"
 			exit
 		fi
@@ -286,9 +198,9 @@ get_partitions() { # <device> <filename>
 		for part in 1 2 3 4; do
 			set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
 
-			local type="$(($1 % 256))"
-			local lba="$(($2))"
-			local num="$(($3))"
+			local type="$(( $(hex_le32_to_cpu $1) % 256))"
+			local lba="$(( $(hex_le32_to_cpu $2) ))"
+			local num="$(( $(hex_le32_to_cpu $3) ))"
 
 			[ $type -gt 0 ] || continue
 
@@ -297,14 +209,9 @@ get_partitions() { # <device> <filename>
 	fi
 }
 
-jffs2_copy_config() {
-	if grep rootfs_data /proc/mtd >/dev/null; then
-		# squashfs+jffs2
-		mtd -e rootfs_data jffs2write "$CONF_TAR" rootfs_data
-	else
-		# jffs2
-		mtd jffs2write "$CONF_TAR" rootfs
-	fi
+indicate_upgrade() {
+	. /etc/diag.sh
+	set_state upgrade
 }
 
 # Flash firmware to MTD partition
@@ -313,32 +220,10 @@ jffs2_copy_config() {
 # $(2): (optional) pipe command to extract firmware, e.g. dd bs=n skip=m
 default_do_upgrade() {
 	sync
-	if [ "$SAVE_CONFIG" -eq 1 ]; then
-		get_image "$1" "$2" | mtd $MTD_CONFIG_ARGS -j "$CONF_TAR" write - "${PART_NAME:-image}"
+	if [ -n "$UPGRADE_BACKUP" ]; then
+		get_image "$1" "$2" | mtd $MTD_ARGS $MTD_CONFIG_ARGS -j "$UPGRADE_BACKUP" write - "${PART_NAME:-image}"
 	else
-		get_image "$1" "$2" | mtd write - "${PART_NAME:-image}"
+		get_image "$1" "$2" | mtd $MTD_ARGS write - "${PART_NAME:-image}"
 	fi
-}
-
-do_upgrade() {
-	v "Performing system upgrade..."
-	if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
-		platform_do_upgrade "$ARGV"
-	else
-		default_do_upgrade "$ARGV"
-	fi
-
-	if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
-		platform_copy_config
-	fi
-
-	v "Upgrade completed"
-	[ -n "$DELAY" ] && sleep "$DELAY"
-	ask_bool 1 "Reboot" && {
-		v "Rebooting system..."
-		umount -a
-		reboot -f
-		sleep 5
-		echo b 2>/dev/null >/proc/sysrq-trigger
-	}
+	[ $? -ne 0 ] && exit 1
 }

+ 25 - 0
package/base-files/files/lib/upgrade/do_stage2

@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. /lib/functions.sh
+
+include /lib/upgrade
+
+v "Performing system upgrade..."
+if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
+	platform_do_upgrade "$IMAGE"
+else
+	default_do_upgrade "$IMAGE"
+fi
+
+if [ -n "$UPGRADE_BACKUP" ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
+	platform_copy_config
+fi
+
+v "Upgrade completed"
+sleep 1
+
+v "Rebooting system..."
+umount -a
+reboot -f
+sleep 5
+echo b 2>/dev/null >/proc/sysrq-trigger

+ 24 - 2
package/base-files/files/lib/upgrade/fwtool.sh

@@ -1,5 +1,27 @@
-fwtool_pre_upgrade() {
-	fwtool -q -i /dev/null "$1"
+fwtool_check_signature() {
+	[ $# -gt 1 ] && return 1
+
+	[ ! -x /usr/bin/ucert ] && {
+		if [ "$REQUIRE_IMAGE_SIGNATURE" = 1 ]; then
+			return 1
+		else
+			return 0
+		fi
+	}
+
+	if ! fwtool -q -s /tmp/sysupgrade.ucert "$1"; then
+		echo "Image signature not found"
+		[ "$REQUIRE_IMAGE_SIGNATURE" = 1 -a "$FORCE" != 1 ] && {
+			echo "Use sysupgrade -F to override this check when downgrading or flashing to vendor firmware"
+		}
+		[ "$REQUIRE_IMAGE_SIGNATURE" = 1 ] && return 1
+		return 0
+	fi
+
+	fwtool -q -T -s /dev/null "$1" | \
+		ucert -V -m - -c "/tmp/sysupgrade.ucert" -P /etc/opkg/keys
+
+	return $?
 }
 
 fwtool_check_image() {

+ 323 - 0
package/base-files/files/lib/upgrade/nand.sh

@@ -0,0 +1,323 @@
+#!/bin/sh
+# Copyright (C) 2014 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+# 'kernel' partition on NAND contains the kernel
+CI_KERNPART="${CI_KERNPART:-kernel}"
+
+# 'ubi' partition on NAND contains UBI
+CI_UBIPART="${CI_UBIPART:-ubi}"
+
+# 'rootfs' partition on NAND contains the rootfs
+CI_ROOTPART="${CI_ROOTPART:-rootfs}"
+
+ubi_mknod() {
+	local dir="$1"
+	local dev="/dev/$(basename $dir)"
+
+	[ -e "$dev" ] && return 0
+
+	local devid="$(cat $dir/dev)"
+	local major="${devid%%:*}"
+	local minor="${devid##*:}"
+	mknod "$dev" c $major $minor
+}
+
+nand_find_volume() {
+	local ubidevdir ubivoldir
+	ubidevdir="/sys/devices/virtual/ubi/$1"
+	[ ! -d "$ubidevdir" ] && return 1
+	for ubivoldir in $ubidevdir/${1}_*; do
+		[ ! -d "$ubivoldir" ] && continue
+		if [ "$( cat $ubivoldir/name )" = "$2" ]; then
+			basename $ubivoldir
+			ubi_mknod "$ubivoldir"
+			return 0
+		fi
+	done
+}
+
+nand_find_ubi() {
+	local ubidevdir ubidev mtdnum
+	mtdnum="$( find_mtd_index $1 )"
+	[ ! "$mtdnum" ] && return 1
+	for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
+		[ ! -d "$ubidevdir" ] && continue
+		cmtdnum="$( cat $ubidevdir/mtd_num )"
+		[ ! "$mtdnum" ] && continue
+		if [ "$mtdnum" = "$cmtdnum" ]; then
+			ubidev=$( basename $ubidevdir )
+			ubi_mknod "$ubidevdir"
+			echo $ubidev
+			return 0
+		fi
+	done
+}
+
+nand_get_magic_long() {
+	dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
+}
+
+get_magic_long_tar() {
+	( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
+}
+
+identify_magic() {
+	local magic=$1
+	case "$magic" in
+		"55424923")
+			echo "ubi"
+			;;
+		"31181006")
+			echo "ubifs"
+			;;
+		"68737173")
+			echo "squashfs"
+			;;
+		"d00dfeed")
+			echo "fit"
+			;;
+		"4349"*)
+			echo "combined"
+			;;
+		*)
+			echo "unknown $magic"
+			;;
+	esac
+}
+
+
+identify() {
+	identify_magic $(nand_get_magic_long "$1" "${2:-0}")
+}
+
+identify_tar() {
+	identify_magic $(get_magic_long_tar "$1" "$2")
+}
+
+nand_restore_config() {
+	sync
+	local ubidev=$( nand_find_ubi $CI_UBIPART )
+	local ubivol="$( nand_find_volume $ubidev rootfs_data )"
+	[ ! "$ubivol" ] &&
+		ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
+	mkdir /tmp/new_root
+	if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
+		echo "mounting ubifs $ubivol failed"
+		rmdir /tmp/new_root
+		return 1
+	fi
+	mv "$1" "/tmp/new_root/$BACKUP_FILE"
+	umount /tmp/new_root
+	sync
+	rmdir /tmp/new_root
+}
+
+nand_upgrade_prepare_ubi() {
+	local rootfs_length="$1"
+	local rootfs_type="$2"
+	local has_kernel="${3:-0}"
+	local has_env="${4:-0}"
+
+	local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+	if [ ! "$mtdnum" ]; then
+		echo "cannot find ubi mtd partition $CI_UBIPART"
+		return 1
+	fi
+
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	if [ ! "$ubidev" ]; then
+		ubiattach -m "$mtdnum"
+		sync
+		ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	fi
+
+	if [ ! "$ubidev" ]; then
+		ubiformat /dev/mtd$mtdnum -y
+		ubiattach -m "$mtdnum"
+		sync
+		ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+		[ "$has_env" -gt 0 ] && {
+			ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
+			ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
+		}
+	fi
+
+	local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
+	local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
+	local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
+
+	# remove ubiblock device of rootfs
+	local root_ubiblk="ubiblock${root_ubivol:3}"
+	if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then
+		echo "removing $root_ubiblk"
+		if ! ubiblock -r /dev/$root_ubivol; then
+			echo "cannot remove $root_ubiblk"
+			return 1;
+		fi
+	fi
+
+	# kill volumes
+	[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
+	[ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
+	[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
+
+	# update kernel
+	if [ "$has_kernel" = "1" ]; then
+		if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
+			echo "cannot create kernel volume"
+			return 1;
+		fi
+	fi
+
+	# update rootfs
+	local root_size_param
+	if [ "$rootfs_type" = "ubifs" ]; then
+		root_size_param="-m"
+	else
+		root_size_param="-s $rootfs_length"
+	fi
+	if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $root_size_param; then
+		echo "cannot create rootfs volume"
+		return 1;
+	fi
+
+	# create rootfs_data for non-ubifs rootfs
+	if [ "$rootfs_type" != "ubifs" ]; then
+		if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then
+			echo "cannot initialize rootfs_data volume"
+			return 1
+		fi
+	fi
+	sync
+	return 0
+}
+
+nand_do_upgrade_success() {
+	local conf_tar="/tmp/sysupgrade.tgz"
+
+	sync
+	[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
+	echo "sysupgrade successful"
+	umount -a
+	reboot -f
+}
+
+# Flash the UBI image to MTD partition
+nand_upgrade_ubinized() {
+	local ubi_file="$1"
+	local mtdnum="$(find_mtd_index "$CI_UBIPART")"
+
+	[ ! "$mtdnum" ] && {
+		CI_UBIPART="rootfs"
+		mtdnum="$(find_mtd_index "$CI_UBIPART")"
+	}
+
+	if [ ! "$mtdnum" ]; then
+		echo "cannot find mtd device $CI_UBIPART"
+		umount -a
+		reboot -f
+	fi
+
+	local mtddev="/dev/mtd${mtdnum}"
+	ubidetach -p "${mtddev}" || true
+	sync
+	ubiformat "${mtddev}" -y -f "${ubi_file}"
+	ubiattach -p "${mtddev}"
+	nand_do_upgrade_success
+}
+
+# Write the UBIFS image to UBI volume
+nand_upgrade_ubifs() {
+	local rootfs_length=`(cat $1 | wc -c) 2> /dev/null`
+
+	nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
+
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
+	ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
+
+	nand_do_upgrade_success
+}
+
+nand_upgrade_tar() {
+	local tar_file="$1"
+	local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
+
+	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
+	board_dir=${board_dir%/}
+
+	local kernel_length=`(tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null`
+	local rootfs_length=`(tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null`
+
+	local rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
+
+	local has_kernel=1
+	local has_env=0
+
+	[ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
+		tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART
+	}
+	[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0
+
+	nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env"
+
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	[ "$has_kernel" = "1" ] && {
+		local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)"
+		tar xf $tar_file ${board_dir}/kernel -O | \
+			ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
+	}
+
+	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
+	tar xf $tar_file ${board_dir}/root -O | \
+		ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
+
+	nand_do_upgrade_success
+}
+
+# Recognize type of passed file and start the upgrade process
+nand_do_upgrade() {
+	local file_type=$(identify $1)
+
+	if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
+		platform_nand_pre_upgrade "$1"
+	fi
+
+	[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
+
+	case "$file_type" in
+		"ubi")		nand_upgrade_ubinized $1;;
+		"ubifs")	nand_upgrade_ubifs $1;;
+		*)		nand_upgrade_tar $1;;
+	esac
+}
+
+# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
+# 3 types of files:
+# 1) UBI - should contain an ubinized image, header is checked for the proper
+#    MAGIC
+# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
+#    header is checked for the proper MAGIC
+# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
+#    "CONTROL" file (at this point its content isn't verified)
+#
+# You usually want to call this function in platform_check_image.
+#
+# $(1): board name, used in case of passing TAR file
+# $(2): file to be checked
+nand_do_platform_check() {
+	local board_name="$1"
+	local tar_file="$2"
+	local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null`
+	local file_type="$(identify $2)"
+
+	[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && {
+		echo "Invalid sysupgrade file."
+		return 1
+	}
+
+	return 0
+}

+ 137 - 0
package/base-files/files/lib/upgrade/stage2

@@ -0,0 +1,137 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+export IMAGE="$1"
+COMMAND="$2"
+
+export INTERACTIVE=0
+export VERBOSE=1
+export CONFFILES=/tmp/sysupgrade.conffiles
+
+RAMFS_COPY_BIN=		# extra programs for temporary ramfs root
+RAMFS_COPY_DATA=	# extra data files
+
+include /lib/upgrade
+
+
+supivot() { # <new_root> <old_root>
+	/bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
+	mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
+	/bin/mount -o noatime,move /proc $1/proc && \
+	pivot_root $1 $1$2 || {
+		/bin/umount -l $1 $1
+		return 1
+	}
+
+	/bin/mount -o noatime,move $2/sys /sys
+	/bin/mount -o noatime,move $2/dev /dev
+	/bin/mount -o noatime,move $2/tmp /tmp
+	/bin/mount -o noatime,move $2/overlay /overlay 2>&-
+	return 0
+}
+
+switch_to_ramfs() {
+	for binary in \
+		/bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount	\
+		pivot_root mount_root reboot sync kill sleep		\
+		md5sum hexdump cat zcat bzcat dd tar			\
+		ls basename find cp mv rm mkdir rmdir mknod touch chmod \
+		'[' printf wc grep awk sed cut				\
+		mtd partx losetup mkfs.ext4				\
+		ubiupdatevol ubiattach ubiblock ubiformat		\
+		ubidetach ubirsvol ubirmvol ubimkvol			\
+		snapshot snapshot_tool					\
+		$RAMFS_COPY_BIN
+	do
+		local file="$(which "$binary" 2>/dev/null)"
+		[ -n "$file" ] && install_bin "$file"
+	done
+	install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh /lib/upgrade/do_stage2 /usr/share/libubox/jshn.sh $RAMFS_COPY_DATA
+
+	[ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
+
+	supivot $RAM_ROOT /mnt || {
+		echo "Failed to switch over to ramfs. Please reboot."
+		exit 1
+	}
+
+	/bin/mount -o remount,ro /mnt
+	/bin/umount -l /mnt
+
+	grep /overlay /proc/mounts > /dev/null && {
+		/bin/mount -o noatime,remount,ro /overlay
+		/bin/umount -l /overlay
+	}
+}
+
+kill_remaining() { # [ <signal> [ <loop> ] ]
+	local loop_limit=10
+
+	local sig="${1:-TERM}"
+	local loop="${2:-0}"
+	local run=true
+	local stat
+	local proc_ppid=$(cut -d' ' -f4  /proc/$$/stat)
+
+	echo -n "Sending $sig to remaining processes ... "
+
+	while $run; do
+		run=false
+		for stat in /proc/[0-9]*/stat; do
+			[ -f "$stat" ] || continue
+
+			local pid name state ppid rest
+			read pid name state ppid rest < $stat
+			name="${name#(}"; name="${name%)}"
+
+			# Skip PID1, our parent, ourself and our children
+			[ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue
+
+			local cmdline
+			read cmdline < /proc/$pid/cmdline
+
+			# Skip kernel threads
+			[ -n "$cmdline" ] || continue
+
+			echo -n "$name "
+			kill -$sig $pid 2>/dev/null
+
+			[ $loop -eq 1 ] && run=true
+		done
+
+		let loop_limit--
+		[ $loop_limit -eq 0 ] && {
+			echo
+			echo "Failed to kill all processes."
+			exit 1
+		}
+	done
+	echo
+}
+
+indicate_upgrade
+
+killall -9 telnetd
+killall -9 dropbear
+killall -9 ash
+
+kill_remaining TERM
+sleep 3
+kill_remaining KILL 1
+
+sleep 1
+
+
+if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
+	platform_pre_upgrade "$IMAGE"
+fi
+
+if [ -n "$(rootfs_type)" ]; then
+	echo "Switching to ramdisk..."
+	switch_to_ramfs
+fi
+
+# Exec new shell from ramfs
+exec /bin/busybox ash -c "$COMMAND"

+ 130 - 0
package/base-files/files/sbin/pkg_check

@@ -0,0 +1,130 @@
+#!/bin/sh
+#
+# Package checksums checking script
+# (C) 2018 CZ.NIC, z.s.p.o.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+ERRFATAL="no"
+QUIET="yes"
+MISSING=""
+SUMMARY=""
+NL="
+"
+
+# Arguments parsing
+while expr "x$1" : "x-" > /dev/null; do
+	if [ "x$1" = "x-s" ]; then
+		ERRFATAL="yes"
+		shift
+	elif [ "x$1" = "x-v" ]; then
+		QUIET="	no"
+		shift
+	else
+		echo "Usage: $(basename $0) [-s] [-v] [pkg1 pkg2 ...]"
+		echo
+		echo "   -s   Stop on first change"
+		echo "   -v   Verbose"
+		if [ "x$1" = "x-h" ]; then
+			exit 0
+		else
+			echo
+			echo "ERROR: Unknown option '$1'"
+			exit 1
+		fi
+	fi
+done
+
+# Check all packages by default
+if [ -z "$1" ]; then
+	set $(cd /usr/lib/opkg/info/; for i in *.files-sha256sum; do basename $i .files-sha256sum; done)
+fi
+
+# Iterate over packages
+while [ "$1" ]; do
+	if [ \! -f "/usr/lib/opkg/info/$1.files-sha256sum" ]; then
+		if [ "$ERRFATAL" = no ]; then
+			echo " * No checksums for $1 - skipping"
+			echo
+		else
+			echo " * No checksums for $1 - exiting"
+			exit 1
+		fi
+		if [ -z "$MISSING" ]; then
+			MISSING="$1"
+		else
+			MISSING="$MISSING, $1"
+		fi
+		shift
+		continue
+	fi
+	[ $QUIET = yes ] || echo " * Checking package $1:"
+	ERR=""
+	CHECK="`sha256sum -c /usr/lib/opkg/info/$1.files-sha256sum 2> /dev/null`"
+
+	# Are the changed files config files?
+	if [ $? -ne 0 ] && [ "`cat "/usr/lib/opkg/info/$1.files-sha256sum"`" ]; then
+		NEWCHECK="`echo "$CHECK" | grep '^.*: OK$'`"
+		for i in `echo "$CHECK" | sed -n 's|^\(.*\): FAILED$|\1|p'`; do
+			if [ "`grep "^$i\$" "/usr/lib/opkg/info/$1.conffiles" 2> /dev/null`" ] || \
+			   [ "`echo "$i" | grep "^/etc/uci-defaults/"`" ]; then
+				NEWCHECK="${NEWCHECK}${NL}${i}: CONFIGURED"
+			else
+				NEWCHECK="${NEWCHECK}${NL}${i}: FAILED"
+				ERR="y"
+			fi
+		done
+		CHECK="$NEWCHECK"
+	fi
+
+	# Do we have changed files or not?
+	if [ -z "$ERR" ]; then
+		[ $QUIET = yes ] || [ -z "`cat "/usr/lib/opkg/info/$1.files-sha256sum"`" ] || echo "$CHECK" | sed 's|^|   - |'
+		[ $QUIET = yes ] || echo " * Package $1 is ok"
+		[ $QUIET = yes ] || echo
+	else
+		if [ $QUIET = yes ]; then
+			echo " * Changes found in package $1:"
+			echo "$CHECK" | sed -n 's|^\(.*:[[:blank:]]*FAILED\)$|   - \1|p'
+		else
+			echo "$CHECK" | sed 's|^|   - |'
+			echo " * Changes found in package $1!"
+		fi
+		if [ "$ERRFATAL" = yes ]; then
+			echo
+			echo "Exiting on first change found!"
+			exit 1
+		fi
+		for i in `echo "$CHECK" | sed -n 's|^\(.*\): FAILED$|\1|p'`; do
+			SUMMARY="${SUMMARY}${NL} - $1: $i"
+		done
+		echo
+	fi
+	shift
+done
+
+# If there are changed files, report them
+if [ "$SUMMARY" ]; then
+	echo "Some packages contain changed files!"
+	echo "Maybe something worth looking into?"
+	echo "Here is the list of packages and changed files:"
+	echo "$SUMMARY"
+fi
+if [ "$MISSING" ]; then
+	echo "Following packages are missing checksums: $MISSING"
+fi
+if [ "$MISSING" ] || [ "$SUMMARY" ]; then
+	exit 1
+fi

+ 204 - 72
package/base-files/files/sbin/sysupgrade

@@ -1,17 +1,20 @@
 #!/bin/sh
+
 . /lib/functions.sh
 . /lib/functions/system.sh
+. /usr/share/libubox/jshn.sh
 
 # initialize defaults
-RAMFS_COPY_BIN=""	# extra programs for temporary ramfs root
-RAMFS_COPY_DATA=""	# extra data files
+export MTD_ARGS=""
 export MTD_CONFIG_ARGS=""
 export INTERACTIVE=0
 export VERBOSE=1
 export SAVE_CONFIG=1
 export SAVE_OVERLAY=0
+export SAVE_OVERLAY_PATH=
 export SAVE_PARTITIONS=1
-export DELAY=
+export SAVE_INSTALLED_PKGS=0
+export SKIP_UNCHANGED=0
 export CONF_IMAGE=
 export CONF_BACKUP_LIST=0
 export CONF_BACKUP=
@@ -20,26 +23,29 @@ export NEED_IMAGE=
 export HELP=0
 export FORCE=0
 export TEST=0
+export UMOUNT_ETCBACKUP_DIR=0
 
 # parse options
 while [ -n "$1" ]; do
 	case "$1" in
 		-i) export INTERACTIVE=1;;
-		-d) export DELAY="$2"; shift;;
 		-v) export VERBOSE="$(($VERBOSE + 1))";;
 		-q) export VERBOSE="$(($VERBOSE - 1))";;
 		-n) export SAVE_CONFIG=0;;
-		-c) export SAVE_OVERLAY=1;;
+		-c) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;;
+		-o) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;;
 		-p) export SAVE_PARTITIONS=0;;
+		-k) export SAVE_INSTALLED_PKGS=1;;
+		-u) export SKIP_UNCHANGED=1;;
 		-b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
 		-r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;;
-		-l|--list-backup) export CONF_BACKUP_LIST=1; break;;
+		-l|--list-backup) export CONF_BACKUP_LIST=1;;
 		-f) export CONF_IMAGE="$2"; shift;;
 		-F|--force) export FORCE=1;;
 		-T|--test) export TEST=1;;
 		-h|--help) export HELP=1; break;;
 		-*)
-			echo "Invalid option: $1"
+			echo "Invalid option: $1" >&2
 			exit 1
 		;;
 		*) break;;
@@ -49,22 +55,27 @@ done
 
 export CONFFILES=/tmp/sysupgrade.conffiles
 export CONF_TAR=/tmp/sysupgrade.tgz
+export ETCBACKUP_DIR=/etc/backup
+export INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt
 
-export ARGV="$*"
-export ARGC="$#"
+IMAGE="$1"
 
-[ -z "$ARGV" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && {
+[ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 -o $HELP -gt 0 ] && {
 	cat <<EOF
 Usage: $0 [<upgrade-option>...] <image file or URL>
-       $0 [-q] [-i] <backup-command> <file>
+       $0 [-q] [-i] [-c] [-u] [-o] [-k] <backup-command> <file>
 
 upgrade-option:
-	-d <delay>   add a delay before rebooting
 	-f <config>  restore configuration from .tar.gz (file or url)
 	-i           interactive mode
 	-c           attempt to preserve all changed files in /etc/
+	-o           attempt to preserve all changed files in /, except those
+	             from packages but including changed confs.
+	-u           skip from backup files that are equal to those in /rom
 	-n           do not save configuration over reflash
 	-p           do not attempt to restore the partition table after flash.
+	-k           include in backup a list of current installed packages at
+	             $INSTALLED_PACKAGES
 	-T | --test
 	             Verify image and config .tar.gz but do not actually flash.
 	-F | --force
@@ -90,7 +101,7 @@ EOF
 	exit 1
 }
 
-[ -n "$ARGV" -a -n "$NEED_IMAGE" ] && {
+[ -n "$IMAGE" -a -n "$NEED_IMAGE" ] && {
 	cat <<-EOF
 		-b|--create-backup and -r|--restore-backup do not perform a firmware upgrade.
 		Do not specify both -b|-r and a firmware image.
@@ -101,63 +112,159 @@ EOF
 # prevent messages from clobbering the tarball when using stdout
 [ "$CONF_BACKUP" = "-" ] && export VERBOSE=0
 
-add_uci_conffiles() {
+
+list_conffiles() {
+	awk '
+		BEGIN { conffiles = 0 }
+		/^Conffiles:/ { conffiles = 1; next }
+		!/^ / { conffiles = 0; next }
+		conffiles == 1 { print }
+	' /usr/lib/opkg/status
+}
+
+list_changed_conffiles() {
+	# Cannot handle spaces in filenames - but opkg cannot either...
+	list_conffiles | while read file csum; do
+		[ -r "$file" ] || continue
+
+		echo "${csum}  ${file}" | sha256sum -sc - || echo "$file"
+	done
+}
+
+add_conffiles() {
 	local file="$1"
 	( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \
 		/etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \
-		-type f -o -type l 2>/dev/null;
-	  opkg list-changed-conffiles ) | sort -u > "$file"
+		\( -type f -o -type l \) $find_filter 2>/dev/null;
+	  list_changed_conffiles ) | sort -u > "$file"
 	return 0
 }
 
 add_overlayfiles() {
 	local file="$1"
-	if [ -d /overlay/upper ]; then
-		local overlaydir="/overlay/upper"
-	else
-		local overlaydir="/overlay"
+
+	local packagesfiles=$1.packagesfiles
+	touch "$packagesfiles"
+
+	if [ "$SAVE_OVERLAY_PATH" = / ]; then
+		local conffiles=$1.conffiles
+		local keepfiles=$1.keepfiles
+
+		list_conffiles | cut -f2 -d ' ' | sort -u > "$conffiles"
+
+		# backup files from /etc/sysupgrade.conf and /lib/upgrade/keep.d, but
+		# ignore those aready controlled by opkg conffiles
+		find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \
+			/etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \
+			\( -type f -o -type l \) 2>/dev/null | sort -u |
+			grep -h -v -x -F -f $conffiles > "$keepfiles"
+
+		# backup conffiles, but only those changed if '-u'
+		[ $SKIP_UNCHANGED = 1 ] &&
+			list_changed_conffiles | sort -u > "$conffiles"
+
+		# do not backup files from packages, except those listed
+		# in conffiles and keep.d
+		{
+			find /usr/lib/opkg/info -type f -name "*.list" -exec cat {} \;
+			find /usr/lib/opkg/info -type f -name "*.control" -exec sed \
+				-ne '/^Alternatives/{s/^Alternatives: //;s/, /\n/g;p}' {} \; |
+				cut -f2 -d:
+		} |  grep -v -x -F -f $conffiles |
+		     grep -v -x -F -f $keepfiles | sort -u > "$packagesfiles"
+		rm -f "$keepfiles" "$conffiles"
 	fi
-	find $overlaydir/etc/ -type f -o -type l | sed \
-		-e 's,^/overlay\/upper/,/,' \
-		-e 's,^/overlay/,/,' \
-		-e '\,/META_[a-zA-Z0-9]*$,d' \
-		-e '\,/functions.sh$,d' \
+
+	# busybox grep bug when file is empty
+	[ -s "$packagesfiles" ] || echo > $packagesfiles
+
+	( cd /overlay/upper/; find .$SAVE_OVERLAY_PATH \( -type f -o -type l \) $find_filter | sed \
+		-e 's,^\.,,' \
+		-e '\,^/etc/board.json$,d' \
 		-e '\,/[^/]*-opkg$,d' \
-	> "$file"
+		-e '\,^/etc/urandom.seed$,d' \
+		-e "\,^$INSTALLED_PACKAGES$,d" \
+		-e '\,^/usr/lib/opkg/.*,d' \
+	) | grep -v -x -F -f $packagesfiles > "$file"
+
+	rm -f "$packagesfiles"
+
 	return 0
 }
 
-# hooks
-sysupgrade_image_check="fwtool_check_image platform_check_image"
-sysupgrade_pre_upgrade="fwtool_pre_upgrade"
-[ $SAVE_OVERLAY = 0 -o ! -d /overlay/etc ] && \
-	sysupgrade_init_conffiles="add_uci_conffiles" || \
+if [ $SAVE_OVERLAY = 1 ]; then
+	[ ! -d /overlay/upper/etc ] && {
+		echo "Cannot find '/overlay/upper/etc', required for '-c'" >&2
+		exit 1
+	}
 	sysupgrade_init_conffiles="add_overlayfiles"
+else
+	sysupgrade_init_conffiles="add_conffiles"
+fi
 
-include /lib/upgrade
+find_filter=""
+if [ $SKIP_UNCHANGED = 1 ]; then
+	[ ! -d /rom/ ] && {
+		echo "'/rom/' is required by '-u'"
+		exit 1
+	}
+	find_filter='( ( -exec test -e /rom/{} ; -exec cmp -s /{} /rom/{} ; ) -o -print )'
+fi
 
-[ "$1" = "nand" ] && nand_upgrade_stage2 $@
+include /lib/upgrade
 
 do_save_conffiles() {
-	local conf_tar="${1:-$CONF_TAR}"
+	local conf_tar="$1"
 
 	[ -z "$(rootfs_type)" ] && {
-		echo "Cannot save config while running from ramdisk."
+		echo "Cannot save config while running from ramdisk." >&2
 		ask_bool 0 "Abort" && exit
+		rm -f "$conf_tar"
 		return 0
 	}
 	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
 	ask_bool 0 "Edit config file list" && vi "$CONFFILES"
 
+	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
+		echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
+		mkdir -p "$ETCBACKUP_DIR"
+		# Avoid touching filesystem on each backup
+		RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)"
+		mkdir -p "$RAMFS/upper" "$RAMFS/work"
+		mount -t overlay overlay -o lowerdir=$ETCBACKUP_DIR,upperdir=$RAMFS/upper,workdir=$RAMFS/work $ETCBACKUP_DIR &&
+			UMOUNT_ETCBACKUP_DIR=1 || {
+				echo "Cannot mount '$ETCBACKUP_DIR' as tmpfs to avoid touching disk while saving the list of installed packages." >&2
+				ask_bool 0 "Abort" && exit
+			}
+
+		# Format: pkg-name<TAB>{rom,overlay,unkown}
+		# rom is used for pkgs in /rom, even if updated later
+		find /usr/lib/opkg/info -name "*.control" \( \
+			\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
+			\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
+			\( -exec echo {} unknown \; \) \
+			\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
+	fi
+
 	v "Saving config files..."
 	[ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
 	tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null
+	if [ "$?" -ne 0 ]; then
+		echo "Failed to create the configuration backup."
+		rm -f "$conf_tar"
+		exit 1
+	fi
 
+	[ "$UMOUNT_ETCBACKUP_DIR" -eq 1 ] && {
+		umount "$ETCBACKUP_DIR"
+		rm -rf "$RAMFS"
+	}
 	rm -f "$CONFFILES"
 }
 
 if [ $CONF_BACKUP_LIST -eq 1 ]; then
-	add_uci_conffiles "$CONFFILES"
+	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
+	[ "$SAVE_INSTALLED_PKGS" -eq 1 ] && echo ${INSTALLED_PACKAGES} >> "$CONFFILES"
 	cat "$CONFFILES"
 	rm -f "$CONFFILES"
 	exit 0
@@ -170,7 +277,7 @@ fi
 
 if [ -n "$CONF_RESTORE" ]; then
 	if [ "$CONF_RESTORE" != "-" ] && [ ! -f "$CONF_RESTORE" ]; then
-		echo "Backup archive '$CONF_RESTORE' not found."
+		echo "Backup archive '$CONF_RESTORE' not found." >&2
 		exit 1
 	fi
 
@@ -180,37 +287,63 @@ if [ -n "$CONF_RESTORE" ]; then
 fi
 
 type platform_check_image >/dev/null 2>/dev/null || {
-	echo "Firmware upgrade is not implemented for this platform."
+	echo "Firmware upgrade is not implemented for this platform." >&2
 	exit 1
 }
 
-for check in $sysupgrade_image_check; do
-	( eval "$check \"\$ARGV\"" ) || {
-		if [ $FORCE -eq 1 ]; then
-			echo "Image check '$check' failed but --force given - will update anyway!"
-			break
-		else
-			echo "Image check '$check' failed."
-			exit 1
-		fi
-	}
-done
+case "$IMAGE" in
+	http://*|\
+	https://*)
+		wget -O/tmp/sysupgrade.img "$IMAGE" || exit 1
+		IMAGE=/tmp/sysupgrade.img
+		;;
+esac
+
+IMAGE="$(readlink -f "$IMAGE")"
+
+case "$IMAGE" in
+	'')
+		echo "Image file not found." >&2
+		exit 1
+		;;
+	/tmp/*)	;;
+	*)
+		v "Image not in /tmp, copying..."
+		cp -f "$IMAGE" /tmp/sysupgrade.img
+		IMAGE=/tmp/sysupgrade.img
+		;;
+esac
+
+json_load "$(/usr/libexec/validate_firmware_image "$IMAGE")" || {
+	echo "Failed to check image"
+	exit 1
+}
+json_get_var valid "valid"
+[ "$valid" -eq 0 ] && {
+	if [ $FORCE -eq 1 ]; then
+		echo "Image check failed but --force given - will update anyway!" >&2
+	else
+		echo "Image check failed." >&2
+		exit 1
+	fi
+}
 
 if [ -n "$CONF_IMAGE" ]; then
 	case "$(get_magic_word $CONF_IMAGE cat)" in
 		# .gz files
 		1f8b) ;;
 		*)
-			echo "Invalid config file. Please use only .tar.gz files"
+			echo "Invalid config file. Please use only .tar.gz files" >&2
 			exit 1
 		;;
 	esac
 	get_image "$CONF_IMAGE" "cat" > "$CONF_TAR"
 	export SAVE_CONFIG=1
 elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then
-	[ $TEST -eq 1 ] || do_save_conffiles
+	[ $TEST -eq 1 ] || do_save_conffiles "$CONF_TAR"
 	export SAVE_CONFIG=1
 else
+	[ $TEST -eq 1 ] || rm -f "$CONF_TAR"
 	export SAVE_CONFIG=0
 fi
 
@@ -218,28 +351,27 @@ if [ $TEST -eq 1 ]; then
 	exit 0
 fi
 
-run_hooks "" $sysupgrade_pre_upgrade
-
-# Some platforms/devices may want different sysupgrade process, e.g. without
-# killing processes yet or calling ubus system upgrade method.
-# This is needed e.g. on NAND devices where we just want to trigger stage1 at
-# this point.
-if type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
-	platform_pre_upgrade "$ARGV"
-fi
-
-ubus call system upgrade
-touch /tmp/sysupgrade
+install_bin /sbin/upgraded
+v "Commencing upgrade. Closing all shell sessions."
 
-if [ ! -f /tmp/failsafe ] ; then
-	kill_remaining TERM
-	sleep 3
-	kill_remaining KILL
-fi
+COMMAND='/lib/upgrade/do_stage2'
 
-if [ -n "$(rootfs_type)" ]; then
-	v "Switching to ramdisk..."
-	run_ramfs '. /lib/functions.sh; include /lib/upgrade; do_upgrade'
+if [ -n "$FAILSAFE" ]; then
+	printf '%s\x00%s\x00%s' "$RAM_ROOT" "$IMAGE" "$COMMAND" >/tmp/sysupgrade
+	lock -u /tmp/.failsafe
 else
-	do_upgrade
+	force_attr=""
+	[ $FORCE -eq 1 ] && force_attr="\"force\": true,"
+	backup_attr=""
+	[ $SAVE_CONFIG -eq 1 ] && backup_attr="\"backup\": $(json_string $CONF_TAR),"
+	ubus call system sysupgrade "{
+		\"prefix\": $(json_string "$RAM_ROOT"),
+		\"path\": $(json_string "$IMAGE"),
+		$force_attr
+		$backup_attr
+		\"command\": $(json_string "$COMMAND"),
+		\"options\": {
+			\"save_partitions\": $SAVE_PARTITIONS
+		}
+	}"
 fi

+ 0 - 20
package/base-files/files/sbin/urandom_seed

@@ -1,20 +0,0 @@
-#!/bin/sh
-set -e
-
-trap '[ "$?" -eq 0 ] || echo "An error occured" >&2' EXIT
-
-save() {
-    touch "$1.tmp"
-    chown root:root "$1.tmp"
-    chmod 600 "$1.tmp"
-    getrandom 512 > "$1.tmp"
-    mv "$1.tmp" "$1"
-    echo "Seed saved ($1)"
-}
-
-SEED="$(uci -q get system.@system[0].urandom_seed || true)"
-[ "${SEED:0:1}" == "/" ] && save "$SEED"
-
-SEED=/etc/urandom.seed
-[ ! -f $SEED ] && save "$SEED"
-true

+ 3 - 2
package/base-files/files/sbin/wifi

@@ -6,7 +6,7 @@
 
 usage() {
 	cat <<EOF
-Usage: $0 [config|down|reload|status]
+Usage: $0 [config|up|down|reload|status]
 enables (default), disables or configures devices not yet configured.
 EOF
 	exit 1
@@ -241,5 +241,6 @@ case "$1" in
 	reload) wifi_reload "$2";;
 	reload_legacy) wifi_reload_legacy "$2";;
 	--help|help) usage;;
-	*) ubus call network reload; wifi_updown "enable" "$2";;
+	''|up) ubus call network reload; wifi_updown "enable" "$2";;
+	*) usage; exit 1;;
 esac

+ 12 - 12
package/base-files/files/usr/lib/os-release

@@ -1,18 +1,18 @@
 NAME="%D"
-VERSION="%V, %N"
+VERSION="%V"
 ID="%d"
-ID_LIKE="librecmc openwrt"
-PRETTY_NAME="%D %N %V"
+ID_LIKE="lede librecmc"
+PRETTY_NAME="%D %V"
 VERSION_ID="%v"
-HOME_URL="%m"
+HOME_URL="%u"
 BUG_URL="%b"
 SUPPORT_URL="%s"
 BUILD_ID="%R"
-LEDE_BOARD="%S"
-LEDE_ARCH="%A"
-LEDE_TAINTS="%t"
-LEDE_DEVICE_MANUFACTURER="%M"
-LEDE_DEVICE_MANUFACTURER_URL="%m"
-LEDE_DEVICE_PRODUCT="%P"
-LEDE_DEVICE_REVISION="%h"
-LEDE_RELEASE="%D %N %V %C"
+LIBRECMC_BOARD="%S"
+LIBRECMC_ARCH="%A"
+LIBRECMC_TAINTS="%t"
+LIBRECMC_DEVICE_MANUFACTURER="%M"
+LIBRECMC_DEVICE_MANUFACTURER_URL="%m"
+LIBRECMC_DEVICE_PRODUCT="%P"
+LIBRECMC_DEVICE_REVISION="%h"
+LIBRECMC_RELEASE="%D %V %C"

+ 1 - 1
package/base-files/files/usr/libexec/login.sh

@@ -1,5 +1,5 @@
 #!/bin/sh
 
-[ "$(uci get system.@system[0].ttylogin)" == 1 ] || exec /bin/ash --login
+[ "$(uci -q get system.@system[0].ttylogin)" = 1 ] || exec /bin/ash --login
 
 exec /bin/login

Some files were not shown because too many files changed in this diff