Merge "Update libcares to version 1.12, see CVE-2016-5180"
diff --git a/configs/gfrg200_defconfig b/configs/gfrg200_defconfig
index 391cb1f..e83b4e1 100644
--- a/configs/gfrg200_defconfig
+++ b/configs/gfrg200_defconfig
@@ -104,6 +104,7 @@
 BR2_PACKAGE_GOOGLE_PLATFORM_CACHE_WARMING=y
 BR2_PACKAGE_GOOGLE_PLATFORM_LOGUPLOAD=y
 BR2_PACKAGE_GOOGLE_PLATFORM_SYSMGR=y
+BR2_PACKAGE_GOOGLE_PLATFORM_SYSLOG=y
 BR2_PACKAGE_GOOGLE_TEST=y
 BR2_PACKAGE_GOOGLE_NETWORK_BOX=y
 BR2_PACKAGE_GOOGLE_STORAGE_BOX=y
diff --git a/configs/gfrg240_defconfig b/configs/gfrg240_defconfig
index 7545977..e9e8ff2 100644
--- a/configs/gfrg240_defconfig
+++ b/configs/gfrg240_defconfig
@@ -3,7 +3,7 @@
 BR2_JLEVEL=15
 BR2_CCACHE=y
 BR2_TOOLCHAIN_EXTERNAL=y
-BR2_TOOLCHAIN_EXTERNAL_PATH="${TOPDIR}/../toolchains/quantenna/usr"
+BR2_TOOLCHAIN_EXTERNAL_PATH="${TOPDIR}/../toolchains/quantenna"
 BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="arc-linux"
 BR2_TOOLCHAIN_EXTERNAL_LARGEFILE=y
 BR2_TOOLCHAIN_EXTERNAL_INET_IPV6=y
@@ -57,6 +57,7 @@
 BR2_PACKAGE_GOOGLE_TEST=y
 BR2_PACKAGE_GOOGLE_NETWORK_BOX=y
 BR2_PACKAGE_CATAWAMPUS=y
+BR2_PACKAGE_QUANTENNA_DRIVERS_STANDALONE=y
 BR2_PACKAGE_HOSTAPD_QUANTENNA=y
 BR2_PACKAGE_HOSTAPD_QUANTENNA_WPS=y
 BR2_PACKAGE_WPA_SUPPLICANT_QUANTENNA=y
diff --git a/fs/skeleton/bin/apman.test b/fs/skeleton/bin/apman.test
index a888b73..4990ca6 100755
--- a/fs/skeleton/bin/apman.test
+++ b/fs/skeleton/bin/apman.test
@@ -1,5 +1,12 @@
 #!/bin/sh
 # Test script for /bin/apman
+
+# b/28915040
+if [ "$(cat /etc/platform)" = "GFHD100" ]; then
+  echo "Not running apman.test on GFHD100"
+  exit 0
+fi
+
 mydir=$(dirname "$0")
 cd "$mydir"
 . ../etc/wvtest.sh
diff --git a/fs/skeleton/bin/has-ghn b/fs/skeleton/bin/has-ghn
new file mode 100755
index 0000000..217a842
--- /dev/null
+++ b/fs/skeleton/bin/has-ghn
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Returns 0 (true) if this device has a local G.hn node
+# By checking for marvell's DEK tool: configlayer
+#
+. /etc/utils.sh
+if runnable configlayer; then
+  exit 0
+else
+  exit 1
+fi
diff --git a/fs/skeleton/bin/has-tuneable-laser b/fs/skeleton/bin/has-tuneable-laser
new file mode 100755
index 0000000..3e97d37
--- /dev/null
+++ b/fs/skeleton/bin/has-tuneable-laser
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# Returns 0 (true) if this device has a tuneable laser
+#
+. /etc/utils.sh
+plat=$(cat /etc/platform)
+if startswith "$plat" "GFLT3" ; then
+  exit 0
+else
+  exit 1
+fi
diff --git a/fs/skeleton/bin/update-ntp-filters b/fs/skeleton/bin/update-ntp-filters
new file mode 100755
index 0000000..9625b78
--- /dev/null
+++ b/fs/skeleton/bin/update-ntp-filters
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. /etc/utils.sh
+
+FAILURE_DELAY="30"
+SUCCESS_DELAY="900"
+
+while :; do
+  ip46tables -F captive-portal-ntp
+
+  code="0"
+  for dst in $@; do
+    echo "Updating ntp server: $dst"
+    ip46tables -A captive-portal-ntp -p udp -d "$dst" --dport ntp -j ACCEPT
+    code=$(( $code | $? ))
+  done
+
+  if [ "$code" -eq "0" ]; then
+    echo "Success. Next update in $SUCCESS_DELAY s."
+    sleep "$SUCCESS_DELAY"
+  else
+    echo "Failure! Trying again in $FAILURE_DELAY s."
+    sleep "$FAILURE_DELAY"
+  fi
+done
diff --git a/fs/skeleton/etc/config/ifup.default.platform_gfibertv b/fs/skeleton/etc/config/ifup.default.platform_gfibertv
index 453e187..b87c6cf 100755
--- a/fs/skeleton/etc/config/ifup.default.platform_gfibertv
+++ b/fs/skeleton/etc/config/ifup.default.platform_gfibertv
@@ -15,6 +15,13 @@
   fi
 fi
 
+if is-wireless-client; then
+  if [ "${iface#wcli}" != "$iface" ]; then
+    uplink=1
+  fi
+fi
+
+
 ip link set dev "$iface" up
 
 if [ "$uplink" = 1 ]; then
diff --git a/fs/skeleton/etc/group b/fs/skeleton/etc/group
index c0aea49..1c6bfe4 100755
--- a/fs/skeleton/etc/group
+++ b/fs/skeleton/etc/group
@@ -13,6 +13,7 @@
 rpcuser:x:29:
 _ntp:x:30:
 avahi::40:
+syslog::41:
 ftp::50:
 lock::54:
 nobody::98:
diff --git a/fs/skeleton/etc/init.d/S01sysctl.platform_gfibertv b/fs/skeleton/etc/init.d/S01sysctl.platform_gfibertv
index 5cd3608..0b9a316 100755
--- a/fs/skeleton/etc/init.d/S01sysctl.platform_gfibertv
+++ b/fs/skeleton/etc/init.d/S01sysctl.platform_gfibertv
@@ -6,7 +6,7 @@
     # Avoid UDP packet loss by increasing socket buffer size.
     # rmem_max defines the maximum receive socket buffer size in bytes.
     # The actual buffer size is set in sagesrv.
-    sysctl net.core.rmem_max=4194304
+    sysctl net.core.rmem_max=5242880
     # Set the socket write buffer size large enough to hold a complete
     # blocksize from the streamer.
     # wmem_max defines the maximum send socket buffer size in bytes.
diff --git a/fs/skeleton/etc/init.d/S08volcheck.platform_gfibertv b/fs/skeleton/etc/init.d/S08volcheck.platform_gfibertv
index 10c5ab1..554a6cd 100755
--- a/fs/skeleton/etc/init.d/S08volcheck.platform_gfibertv
+++ b/fs/skeleton/etc/init.d/S08volcheck.platform_gfibertv
@@ -245,14 +245,17 @@
 
 mount_ext4fs()
 {
-  mount -t ext4 -o defaults,noatime,discard,data=writeback $1 /user || return 1
+  # Use ordered mode & disable delayed allocation to enable metadata journaling
+  # and ensure data blocks are always written before metadata. Avoids issues
+  # with power loss or crashes resulting in zero length files.
+  mount -t ext4 -o defaults,noatime,discard,nodelalloc,data=ordered $1 /user || return 1
   [ ! -d /user/config ] && mkdir -p /user/config
   mount --bind /user/config /config || return 1
 }
 
 mount_atv_ext4fs()
 {
-  mount -t ext4 -o defaults,noatime,discard,data=writeback $1 /atv_userdata || return 1
+  mount -t ext4 -o defaults,noatime,discard,nodelalloc,data=ordered $1 /atv_userdata || return 1
   mkdir -p /atv_userdata/gfiber/user
   mount --bind /atv_userdata/gfiber/user /user || return 1
   mkdir -p /user/config
diff --git a/fs/skeleton/etc/init.d/S41portal_firewall b/fs/skeleton/etc/init.d/S41portal_firewall
index eb0f706..bce1c8c 100755
--- a/fs/skeleton/etc/init.d/S41portal_firewall
+++ b/fs/skeleton/etc/init.d/S41portal_firewall
@@ -4,17 +4,17 @@
 # Servers used by CPE on the other side of the captive portal.
 IP4_DNS="8.8.8.8 8.8.4.4"
 IP6_DNS="2001:4860:4860::8888 2001:4860:4860::8844"
-# TODO(b/29131559): allow NTP servers to be dynamically updated
-NTP="216.239.32.15 216.239.34.15 216.239.36.15 216.239.38.15"
+NTP_SERVERS="time1.google.com time2.google.com time3.google.com time4.google.com"
 
 has_iptables() {
   runnable iptables && iptables -L 2>/dev/null
 }
 
 flush() {
-  ip46tables -F captive-portal-input
-  ip46tables -F captive-portal-filter
   ip46tables -F captive-portal-guests
+  ip46tables -F captive-portal-filter
+  ip46tables -F captive-portal-ntp
+  ip46tables -F captive-portal-input
 }
 
 case "$1" in
@@ -59,13 +59,12 @@
         ip6tables -A captive-portal-filter -p icmpv6 -d $dst --icmpv6-type echo-request -j ACCEPT
       done
 
-      for dst in $NTP; do
-        iptables -A captive-portal-filter -p udp -d $dst --dport ntp -j ACCEPT
-      done
+      nice babysit 60 update-ntp-filters $NTP_SERVERS 2>&1 | logos update-ntp-filters &
     fi
     ;;
   stop)
     if has_iptables && is-network-box; then
+      pkillwait -x update-ntp-filters
       flush
     fi
     ;;
diff --git a/fs/skeleton/etc/init.d/S45ghn.platform_gfiberlt b/fs/skeleton/etc/init.d/S45ghn.platform_gfiberlt
new file mode 100755
index 0000000..16ac013
--- /dev/null
+++ b/fs/skeleton/etc/init.d/S45ghn.platform_gfiberlt
@@ -0,0 +1,51 @@
+#! /bin/sh
+
+. /etc/utils.sh
+
+GHN_DIR="/tmp/ghn"
+GHN_MAC_ADDR_FILE="${GHN_DIR}/mac_addr"
+
+case "$1" in
+  start|"")
+    platform=$(cat /etc/platform)
+    if ! startswith "$platform" "GFLT4"; then
+      exit 0
+    fi
+
+    # Create Ghn directory and mac_addr file
+    mkdir -p "$GHN_DIR"
+
+    HNVRAM_MAC=$(hnvram -q -r MAC_ADDR_PON)
+    if [ -z "$HNVRAM_MAC" ]; then
+      echo "S45ghn: hnvram G.hn mac_addr is empty!"
+      exit 1
+    fi
+    echo "$HNVRAM_MAC" >"$GHN_MAC_ADDR_FILE"
+
+    # Bring up eth1 interface to ghn
+    ip link set up dev eth1
+    # ghn defaults to 10.10.1.69, we want to be on the same subnet
+    ip addr add 10.10.1.2/24 dev eth1
+
+    if ! read-ghn-local "NODE.GENERAL.ENABLE" 1>/dev/null; then
+      echo "S45ghn: Failed to read stats from G.hn: $HNVRAM_MAC"
+      exit 1
+    fi
+
+    # Periodically grab GHN stats and write to file
+    babysit 60 ghn-periodic-stats 2>&1 | logos ghn-periodic-stats &
+    ;;
+  stop)
+    pkillwait -f ghn-periodic-stats
+    ip addr del 10.10.1.2/24 dev eth1
+    ip link set down dev eth1
+    rm -rf "$GHN_DIR"
+    ;;
+  restart)
+    $0 stop; $0 start
+    ;;
+  *)
+    echo "Usage: S45ghn {start|stop|restart}" >&2
+    exit 1
+    ;;
+esac
diff --git a/fs/skeleton/etc/init.d/S74lasertune.platform_gfiberlt b/fs/skeleton/etc/init.d/S74lasertune.platform_gfiberlt
index aa4dff5..7dc8d78 100755
--- a/fs/skeleton/etc/init.d/S74lasertune.platform_gfiberlt
+++ b/fs/skeleton/etc/init.d/S74lasertune.platform_gfiberlt
@@ -1,11 +1,10 @@
 #!/bin/sh
 
 . /etc/utils.sh
-platform=$(cat /etc/platform)
 
 case "$1" in
   start)
-    if startswith "$platform" "GFLT3"; then
+    if has-tuneable-laser; then
       echo "Starting lasertune."
       babysit 5 lasertune 2>&1 | logos lasertune &
     fi
diff --git a/fs/skeleton/etc/init.d/firewall b/fs/skeleton/etc/init.d/firewall
index 6bceaad..f4d718a 100755
--- a/fs/skeleton/etc/init.d/firewall
+++ b/fs/skeleton/etc/init.d/firewall
@@ -144,26 +144,20 @@
       fi
       ip46tables -P FORWARD DROP
 
-      # multicast (fiber TV, EAS)
-      ip46tables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
-      ip46tables -A FORWARD -m pkttype --pkt-type multicast -j ACCEPT
-      iptables -t nat -A PREROUTING -m pkttype --pkt-type multicast -j ACCEPT
-
-      # Forwarding
-      ip46tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-      ip46tables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-
       # captive-portal-filter and captive-portal-input contain rules that should
       # always be applied to the br1 (captive portal) interface, regardless of
       # what services we're trying to provide with it.
       ip46tables -N captive-portal-guests
       ip46tables -N captive-portal-filter
+      ip46tables -N captive-portal-ntp
       ip46tables -N captive-portal-input
       ip46tables -N acs-captive-portal-input
       ip46tables -N sniproxy-input
       ip46tables -N acs-captive-portal-filter
       ip46tables -N acsrules-filter-forward
       ip46tables -N MINIUPNPD
+      ip46tables -N wan-input
+      ip46tables -N wan-forward
       ip46tables -N log
 
       ip46tables -t nat -N captive-portal-guests-nat
@@ -172,12 +166,20 @@
       iptables -t nat -N acsrules-nat-postrouting
       ip46tables -t nat -N sniproxy-nat
       iptables -t nat -N MINIUPNPD
+      ip46tables -t nat -N wan-nat
 
-      ip46tables -A FORWARD -i br0 -j ACCEPT
-      ip46tables -A FORWARD -i br1 -j captive-portal-guests
-      ip46tables -A FORWARD -i br1 -j captive-portal-filter
+      for ifc in "wan0+" "frob+"; do
+        ip46tables -A INPUT -i "$ifc" -j wan-input
+        ip46tables -A FORWARD -i "$ifc" -j wan-forward
+        ip46tables -t nat -A PREROUTING -i "$ifc" -j wan-nat
 
-      # I wanted to use '!wan0' here but, it doesn't work as documented.
+        ip46tables -A FORWARD -i br0 -o "$ifc" -j ACCEPT
+      done
+
+      ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-guests
+      ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-filter
+      ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-ntp
+
       for ifc in lo br0; do
         ip46tables -A INPUT -i "$ifc" -j ACCEPT
       done
@@ -186,8 +188,17 @@
       ip46tables -A INPUT -i br1 -j acs-captive-portal-input
       ip46tables -A INPUT -i br1 -j sniproxy-input
 
+      # multicast (fiber TV, EAS)
+      ip46tables -A wan-input -m pkttype --pkt-type multicast -j ACCEPT
+      ip46tables -A wan-forward -m pkttype --pkt-type multicast -j ACCEPT
+      ip46tables -t nat -A wan-nat -m pkttype --pkt-type multicast -j ACCEPT
+
+      # Forwarding
+      ip46tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
+      ip46tables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
+
       # igmp group membership control
-      ip46tables -A INPUT -p igmp -j ACCEPT
+      ip46tables -A wan-input -p igmp -j ACCEPT
 
       # ping and PMTUD
       iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT
@@ -195,14 +206,14 @@
       iptables -A INPUT -p icmp --icmp-type 11/0 -j ACCEPT
       ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
       # RFC4890 says RFC4380 requires forwarding ipv6 ping requests
-      ip6tables -A FORWARD -p icmpv6 --icmpv6-type echo-request -j ACCEPT
+      ip6tables -A wan-forward -p icmpv6 --icmpv6-type echo-request -j ACCEPT
 
       # Incoming connections
       # TODO(apenwarr): Whitelist ports here too for added safety.
       if [ -e /tmp/NFS ]; then
         # Workaround because netfilter conntracking loaded *after* the NFS
         # session was established.
-        ip46tables -A INPUT -p tcp --sport 2049 -j ACCEPT
+        ip46tables -A wan-input -p tcp --sport 2049 -j ACCEPT
       fi
 
       # Outgoing connections
@@ -211,40 +222,40 @@
 
       # TODO(apenwarr): Remove this when we have real port forwarding controls.
       if [ -e /tmp/DEBUG ]; then
-        ip46tables -A INPUT -p tcp --dport 22 -j ACCEPT    # ssh
-        ip46tables -A FORWARD -p tcp --dport 22 -j ACCEPT  # ssh for lan clients
-        ip46tables -A INPUT -p tcp --dport 5001 -j ACCEPT  # iperf
-        ip46tables -A INPUT -p udp --dport 5001 -j ACCEPT  # iperf
-        ip46tables -A INPUT -p udp --dport 4948 -j ACCEPT  # isoping
+        ip46tables -A wan-input -p tcp --dport 22 -j ACCEPT    # ssh
+        ip46tables -A wan-forward -p tcp --dport 22 -j ACCEPT  # ssh for lan clients
+        ip46tables -A wan-input -p tcp --dport 5001 -j ACCEPT  # iperf
+        ip46tables -A wan-input -p udp --dport 5001 -j ACCEPT  # iperf
+        ip46tables -A wan-input -p udp --dport 4948 -j ACCEPT  # isoping
       fi
 
       # Open incoming ports for McDoleCast
       if experiment McDoleCast; then
-        ip46tables -A INPUT -p tcp --dport 31098 -j ACCEPT  # sagesrv
-        ip46tables -A INPUT -p tcp --dport 32825 -j ACCEPT  # marjoram
+        ip46tables -A wan-input -p tcp --dport 31098 -j ACCEPT  # sagesrv
+        ip46tables -A wan-input -p tcp --dport 32825 -j ACCEPT  # marjoram
       fi
       # cwmpd ACS kick
-      ip46tables -A INPUT -p tcp --dport 7547 -j ACCEPT    # cwmpd
-      ip6tables -A FORWARD -p tcp --dport 7547 -j ACCEPT  # cwmpd
-      iptables -t nat -A PREROUTING -p tcp --dport 7547 -j ACCEPT  # cwmpd
+      ip46tables -A wan-input -p tcp --dport 7547 -j ACCEPT    # cwmpd
+      ip6tables -A wan-forward -p tcp --dport 7547 -j ACCEPT  # cwmpd
+      ip46tables -t nat -A wan-nat -p tcp --dport 7547 -j ACCEPT  # cwmpd
 
       if [ -e /tmp/factory_status ]; then
-        ip46tables -A INPUT -p tcp --dport 8883 -j ACCEPT  # factory web server
+        ip46tables -A wan-input -p tcp --dport 8883 -j ACCEPT  # factory web server
       fi
 
       # active FTP out
       ip46tables -A FORWARD -m conntrack --ctstate RELATED \
           -m helper --helper ftp -o wan0+ -p tcp --dport 1024: -j ACCEPT
-      ip46tables -A FORWARD -m conntrack --ctstate RELATED \
-          -m helper --helper ftp -i wan0+ -p tcp --dport 1024: -j ACCEPT
+      ip46tables -A wan-forward -m conntrack --ctstate RELATED \
+          -m helper --helper ftp -p tcp --dport 1024: -j ACCEPT
 
       # add ACS-configured things
       ip46tables -A FORWARD -i br1 -j acs-captive-portal-filter
-      ip46tables -A FORWARD -j acsrules-filter-forward
+      ip46tables -A FORWARD -i wan0+ -j acsrules-filter-forward
       ip46tables -t nat -A PREROUTING -i br1 -j captive-portal-guests-nat
       ip46tables -t nat -A PREROUTING -i br1 -j acs-captive-portal-nat
-      iptables -t nat -A PREROUTING -j acsrules-nat-prerouting
-      iptables -t nat -A POSTROUTING -j acsrules-nat-postrouting
+      iptables -t nat -A PREROUTING -i wan0+ -j acsrules-nat-prerouting
+      iptables -t nat -A POSTROUTING -o wan0+ -j acsrules-nat-postrouting
 
       # these are managed by sniproxy, if running
       ip46tables -t nat -A PREROUTING -j sniproxy-nat -i br1
@@ -254,7 +265,7 @@
       iptables -t nat -A PREROUTING -i wan0+ -j MINIUPNPD
 
       # nat
-      iptables -t nat -A POSTROUTING -o wan0+ -j MASQUERADE
+      ip46tables -t nat -A POSTROUTING -o wan0+ -j MASQUERADE
 
       # ipv6 addressing
       ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT
diff --git a/fs/skeleton/etc/init.d/network b/fs/skeleton/etc/init.d/network
index 2b15d8e..4edcc21 100755
--- a/fs/skeleton/etc/init.d/network
+++ b/fs/skeleton/etc/init.d/network
@@ -152,10 +152,10 @@
     # On GFRG250, the Quantenna PCIe module has not initialized by the time the
     # kernel enumerates PCIe devices. For development, also include GFRG200 and
     # GFRG210.
-    if contains "GFRG200 GFRG210 GFRG250" "$(cat /etc/platform)"; then
+    if contains ",GFRG200,GFRG210,GFRG250," ",$(cat /etc/platform),"; then
       echo 1 > /sys/bus/pci/rescan
     fi
-    if contains "GFHD254" "$(cat /etc/platform)" && ! startswith "$(uname -r)" "3"; then
+    if contains ",GFHD254," ",$(cat /etc/platform)," && ! startswith "$(uname -r)" "3"; then
       echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove
       sleep 1
       echo 1 > /sys/bus/pci/rescan
diff --git a/fs/skeleton/etc/passwd b/fs/skeleton/etc/passwd
index f592857..37b277e 100755
--- a/fs/skeleton/etc/passwd
+++ b/fs/skeleton/etc/passwd
@@ -6,9 +6,11 @@
 rpcuser:x:29:29:RPC Service User:/var/tmp:/dev/null
 _ntp:x:30:30:OpenNTP Daemon:/var/empty/ntp:/dev/null
 avahi:x:40:40:Avahi mDNS:/:/dev/null
+syslog:*:41:41:syslogd:/var/tmp:/dev/null
 nobody:*:99:99:Nobody:/:/dev/null
 dbus:x:102:105::/var/run/dbus:/dev/null
 video:x:200:200:Video User:/var/media:/dev/null
 appclient:x:201:201:Application User:/:/dev/null
 prism:$1$fufhpwhn$eAwIc7tGVHqELSV1MnPP91:300:300:Prism User:/var/prism:/usr/bin/clish
 nfsnobody:x:65534:65534:Anonymous NFS User:/var/tmp:/dev/null
+
diff --git a/fs/skeleton/etc/utils.sh b/fs/skeleton/etc/utils.sh
index e4f4b9c..5236c51 100644
--- a/fs/skeleton/etc/utils.sh
+++ b/fs/skeleton/etc/utils.sh
@@ -8,10 +8,14 @@
   local filename="$1" newval="$2"
   shift
 
-  if [ ! -e $filename ] || [ "$(cat $filename)" != "$newval" ]; then
-    rm -f $filename.new
-    echo "$@" >$filename.new
-    mv $filename.new $filename
+  if [ ! -e "$filename" ] || [ "$(cat "$filename")" != "$newval" ]; then
+    # fsync after writing the temp file to avoid the potential for ending up
+    # with a zero length file at $filename on ext4 partitions due to ext4's
+    # delayed allocation.
+    rm -f "$filename.new"
+    echo "$@" >"$filename.new"
+    fsync "$filename.new"
+    mv "$filename.new" "$filename"
   fi
 }
 
diff --git a/fs/skeleton/fiber/config b/fs/skeleton/fiber/config
new file mode 120000
index 0000000..4088526
--- /dev/null
+++ b/fs/skeleton/fiber/config
@@ -0,0 +1 @@
+../config/
\ No newline at end of file
diff --git a/fs/skeleton/sbin/hotplug b/fs/skeleton/sbin/hotplug
index dbb0da8..50e8846 100755
--- a/fs/skeleton/sbin/hotplug
+++ b/fs/skeleton/sbin/hotplug
@@ -6,6 +6,10 @@
 . /etc/utils.sh
 
 
+INTERFACE_RESET_PATH=/tmp/interface
+mkdir -p "$INTERFACE_RESET_PATH"
+
+
 get_random_mac() {
   echo -n $(get_mac_addr_for_interface "$1" | cut -c1-8)
   randomdata 0 3 | hexdump -e '3/1 ":%02x"'
@@ -32,7 +36,7 @@
   # autoconfiguration of routes.
   # TODO(rofrankel):  Find a way not to need to disable this, e.g. by making it
   # so that autoconfigured br0 routes have a lower metric than wcli* routes.
-  echo 0 >/proc/sys/net/ipv6/conf/wcli0/accept_ra
+  echo 0 >"/proc/sys/net/ipv6/conf/$client_interface/accept_ra"
 }
 
 load_firmware() {
@@ -91,6 +95,7 @@
 network_add() {
   interface="$1"
   set_mac_address "$interface"
+  touch "$INTERFACE_RESET_PATH/$interface"
   # At boot or device reset, a net add event is delivered for the primary
   # interface. Use this event to create a client interface, which is
   # created in user space unlike the primary interface.
diff --git a/fs/skeleton/usr/bin/ghn-periodic-stats.platform_gfiberlt b/fs/skeleton/usr/bin/ghn-periodic-stats.platform_gfiberlt
new file mode 100755
index 0000000..ad3ddba
--- /dev/null
+++ b/fs/skeleton/usr/bin/ghn-periodic-stats.platform_gfiberlt
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+. /etc/utils.sh
+
+GHN_DIR="/tmp/ghn"
+GHN_STATS_FILE="${GHN_DIR}/config"
+
+usage() {
+  echo "Usage:"
+  echo
+  echo "  $0"
+  echo
+  echo "  Repeatedly grabs up to date stats from G.hn chip using 'configlayer' "
+  echo "  These stats are eventually used in catawampus' periodic statistics. "
+  echo
+  exit 99
+}
+
+if ! has-ghn; then
+  exit 0
+fi
+
+if [ "$#" -ne "0" ]; then
+  usage
+fi
+
+GHN_MAC_ADDR=$(cat "$GHN_DIR"/mac_addr)
+while true; do
+  if configlayer -o GET -i eth1 -m "$GHN_MAC_ADDR" -w paterna \
+    -p NODE.GENERAL.ENABLE \
+    -p NTP.GENERAL.STATUS \
+    -p NODE.GENERAL.DEVICE_ALIAS \
+    -p NODE.GENERAL.DEVICE_NAME \
+    -p SYSTEM.PRODUCTION.DEVICE_NAME \
+    -p NODE.GENERAL.LAST_CHANGE \
+    -p SYSTEM.PRODUCTION.MAC_ADDR \
+    -p SYSTEM.GENERAL.API_VERSION \
+    -p SYSTEM.GENERAL.FW_VERSION \
+    -p SYSTEM.GENERAL.FW_VERSION_CORE \
+    -p NODE.GENERAL.DOMAIN_NAME \
+    -p NODE.GENERAL.DNI \
+    -p NODE.GENERAL.DOMAIN_ID \
+    -p NODE.GENERAL.DEVICE_ID \
+    -p NODE.GENERAL.NODE_TYPE \
+    -p SYSTEM.GENERAL.DOMAIN_MASTER_CAPABLE \
+    -p SYSTEM.GENERAL.SEC_CONTROLLER_CAPABLE \
+    -p SYSTEM.GENERAL.SEC_CONTROLLER_STATUS \
+    -p DIDMNG.GENERAL.NUM_DIDS \
+    -p DIDMNG.GENERAL.DIDS \
+    -p DIDMNG.GENERAL.MACS \
+    -p DIDMNG.GENERAL.TX_BPS \
+    -p DIDMNG.GENERAL.RX_BPS \
+    -p DIDMNG.GENERAL.ACTIVE \
+    > "${GHN_STATS_FILE}.tmp"; then
+    # Do write in two stages to preserve atomicity
+    mv "${GHN_STATS_FILE}.tmp" "$GHN_STATS_FILE"
+  else
+    echo "$0 failed to grab config from G.hn: $GHN_MAC_ADDR"
+  fi
+  sleep 60
+done
diff --git a/fs/skeleton/usr/bin/lasertune.platform_gfiberlt b/fs/skeleton/usr/bin/lasertune.platform_gfiberlt
index 7b7a091..aa0f553 100755
--- a/fs/skeleton/usr/bin/lasertune.platform_gfiberlt
+++ b/fs/skeleton/usr/bin/lasertune.platform_gfiberlt
@@ -3,7 +3,6 @@
 . /etc/utils.sh
 
 laser_channel_file="/sys/devices/platform/gpon/misc/laserChannel"
-platform=$(cat /etc/platform)
 prev_laser_channel=-1
 
 # Initially be very aggressive about acquiring a channel, then back off once
@@ -15,7 +14,7 @@
   echo "$@" >&2
 }
 
-if ! startswith "$platform" "GFLT3"; then
+if ! has-tuneable-laser; then
   # not all fiberjacks have a tunable laser.
   exit 0
 fi
diff --git a/fs/skeleton/usr/bin/read-ghn-local.platform_gfiberlt b/fs/skeleton/usr/bin/read-ghn-local.platform_gfiberlt
new file mode 100755
index 0000000..b528523
--- /dev/null
+++ b/fs/skeleton/usr/bin/read-ghn-local.platform_gfiberlt
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. /etc/utils.sh
+
+GHN_DIR="/tmp/ghn"
+
+usage() {
+  echo "Usage:"
+  echo
+  echo "  $0 $1"
+  echo
+  echo "  A wrapper for 'read-ghn-node' when querying the local G.hn node "
+  echo "  Grabs a single paramater and prints the value. "
+  echo
+  exit 99
+}
+
+if ! has-ghn; then
+  exit 0
+fi
+
+if [ "$#" -ne "1" ]; then
+  usage "$1"
+fi
+
+GHN_MAC_ADDR=$(cat "$GHN_DIR"/mac_addr)
+read-ghn-node "$GHN_MAC_ADDR" "$1"
diff --git a/fs/skeleton/usr/bin/reset-ghn.platform_gfiberlt b/fs/skeleton/usr/bin/reset-ghn.platform_gfiberlt
new file mode 100755
index 0000000..87f6a52
--- /dev/null
+++ b/fs/skeleton/usr/bin/reset-ghn.platform_gfiberlt
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. /etc/utils.sh
+
+usage() {
+  echo "Usage:"
+  echo
+  echo "  $0"
+  echo
+  echo "  Uses gpio0 (GHN_RESET_N_L) to reset G.hn chip. No arguments."
+  echo
+  exit 99
+}
+
+if ! has-ghn; then
+  # Only GFLT400 has G.hn chip (Marvell's 88x5153)
+  exit 0
+fi
+
+if [ "$#" -ne "0" ]; then
+  usage
+fi
+
+echo 0 > /sys/class/gpio/gpio0/value
+echo 1 > /sys/class/gpio/gpio0/value
diff --git a/fs/skeleton/usr/bin/set_laser_channel.platform_gfiberlt b/fs/skeleton/usr/bin/set_laser_channel.platform_gfiberlt
index e822152..ea159c8 100755
--- a/fs/skeleton/usr/bin/set_laser_channel.platform_gfiberlt
+++ b/fs/skeleton/usr/bin/set_laser_channel.platform_gfiberlt
@@ -2,8 +2,6 @@
 
 . /etc/utils.sh
 
-platform=$(cat /etc/platform)
-
 usage() {
   echo "Usage:"
   echo
@@ -15,7 +13,7 @@
   exit 99
 }
 
-if ! startswith "$platform" "GFLT3"; then
+if ! has-tuneable-laser; then
   # not all fiberjacks have tuneable optics.
   exit 0
 fi
@@ -40,7 +38,7 @@
 fi
 
 # Program the laser channel.
-result=$(i2cset -y 0 0x51 0x91 $1)
+result=$(i2cset -y 0 0x51 0x90 0 $1 i)
 if [ "$?" -ne "0" ]; then
   echo "Failed to set laser channel! i2cset error: $result"
   exit 1
diff --git a/linux/linux.mk b/linux/linux.mk
index 1320e9a..d367cac 100644
--- a/linux/linux.mk
+++ b/linux/linux.mk
@@ -45,14 +45,10 @@
 	INSTALL_MOD_PATH=$(TARGET_DIR) \
 	CROSS_COMPILE="$(CCACHE) $(TARGET_CROSS)" \
 	DEPMOD=$(HOST_DIR)/usr/sbin/depmod
-	initramfs=true
-# (initramfs=true replaces the $(initramfs) build command with 'true',
-# effectively making the kernel build scripts never replace the initramfs
-# with a different one; making the initramfs is our job in buildroot.)
 
 # Get the real Linux version, which tells us where kernel modules are
 # going to be installed in the target filesystem.
-LINUX_VERSION_PROBED = $(shell $(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) --no-print-directory -s kernelrelease)
+LINUX_VERSION_PROBED = $(shell LOGLINEAR_LEAVE_STDOUT=1 $(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) --no-print-directory -s kernelrelease 2>/dev/null)
 
 ifeq ($(BR2_LINUX_KERNEL_USE_INTREE_DTS),y)
 KERNEL_DTS_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_INTREE_DTS_NAME))
@@ -225,6 +221,8 @@
 endef
 endif
 
+LINUX_MAKE_MODULES_EXTRA_FLAGS += $(if LINUX_KBUILD_EXTRA_SYMBOLS,KBUILD_EXTRA_SYMBOLS="$(LINUX_KBUILD_EXTRA_SYMBOLS)")
+
 # Compilation. We make sure the kernel gets rebuilt when the
 # configuration has changed.
 define LINUX_BUILD_CMDS
@@ -234,7 +232,7 @@
 		cp $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_DTS_PATH)) $(KERNEL_ARCH_PATH)/boot/dts/)
 	$(TARGET_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_IMAGE_NAME)
 	@if grep -q "CONFIG_MODULES=y" $(@D)/.config; then 	\
-		$(TARGET_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) modules ;	\
+		$(TARGET_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) $(LINUX_MAKE_MODULES_EXTRA_FLAGS) -C $(@D) modules ;	\
 	fi
 	$(LINUX_BUILD_DTB)
 	$(LINUX_APPEND_DTB)
diff --git a/loglinear b/loglinear
index 873d9b1..6afc211 100755
--- a/loglinear
+++ b/loglinear
@@ -249,8 +249,12 @@
       _Write(conn.fileno(), '%s %s\nPWD: %s\nStarting: %s (%s)\n'
              % (parent, nice_cmdline or '',
                 os.getcwd(), cmdline, nice_cmdline))
-      os.dup2(conn.fileno(), 1)
-      os.dup2(conn.fileno(), 2)
+      if os.environ.get('LOGLINEAR_LEAVE_STDOUT'):
+        _Write(conn.fileno(), 'Not redirecting stdout or stderr ' \
+            'because LOGLINEAR_LEAVE_STDOUT is set')
+      else:
+        os.dup2(conn.fileno(), 1)
+        os.dup2(conn.fileno(), 2)
       conn.close()
       os.environ['LOGLINEAR_PARENT'] = str(myid)
       os.execvp(cmdline[0], cmdline)
diff --git a/package/clockspeed/clockspeed-0005-wait-longer.patch b/package/clockspeed/clockspeed-0005-wait-longer.patch
new file mode 100644
index 0000000..d235402
--- /dev/null
+++ b/package/clockspeed/clockspeed-0005-wait-longer.patch
@@ -0,0 +1,11 @@
+--- a/sntpclock.c	2017-01-19 12:08:54.003237871 -0800
++++ b/sntpclock.c	2017-01-19 12:27:31.212751112 -0800
+@@ -202,7 +202,7 @@
+       strerr_die2sys(111,FATAL,"unable to send request: ");
+     FD_ZERO(&rfds);
+     FD_SET(s,&rfds);
+-    tvselect.tv_sec = 1;
++    tvselect.tv_sec = 5;
+     tvselect.tv_usec = 0;
+     if (select(s + 1,&rfds,(fd_set *) 0,(fd_set *) 0,&tvselect) != 1) {
+       strerr_warn2(WARNING,"unable to read clock: timed out",0);
diff --git a/package/golang/go_cloud/go_cloud.mk b/package/golang/go_cloud/go_cloud.mk
index 28c28b0..6a9689d 100644
--- a/package/golang/go_cloud/go_cloud.mk
+++ b/package/golang/go_cloud/go_cloud.mk
@@ -10,7 +10,7 @@
 
 define GO_CLOUD_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/google.golang.org/"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/google.golang.org/cloud"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/google.golang.org/cloud"
 endef
 
 GO_CLOUD_POST_PATCH_HOOKS += GO_CLOUD_FIX_PATH
diff --git a/package/golang/go_cron/go_cron.mk b/package/golang/go_cron/go_cron.mk
index 4e9e518..71a55e5 100644
--- a/package/golang/go_cron/go_cron.mk
+++ b/package/golang/go_cron/go_cron.mk
@@ -10,7 +10,7 @@
 
 define GO_CRON_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/robfig/"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/robfig/cron"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/robfig/cron"
 endef
 
 GO_CRON_POST_PATCH_HOOKS += GO_CRON_FIX_PATH
diff --git a/package/golang/go_fsnotify/go_fsnotify.mk b/package/golang/go_fsnotify/go_fsnotify.mk
index 357a915..e6ed876 100644
--- a/package/golang/go_fsnotify/go_fsnotify.mk
+++ b/package/golang/go_fsnotify/go_fsnotify.mk
@@ -10,7 +10,7 @@
 
 define GO_FSNOTIFY_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/go-fsnotify/"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/go-fsnotify/fsnotify"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/go-fsnotify/fsnotify"
 endef
 
 GO_FSNOTIFY_POST_PATCH_HOOKS += GO_FSNOTIFY_FIX_PATH
diff --git a/package/golang/go_glog/go_glog.mk b/package/golang/go_glog/go_glog.mk
index d01dbd6..5779579 100644
--- a/package/golang/go_glog/go_glog.mk
+++ b/package/golang/go_glog/go_glog.mk
@@ -10,7 +10,7 @@
 
 define GO_GLOG_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/golang"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/golang/glog"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/golang/glog"
 endef
 
 GO_GLOG_POST_PATCH_HOOKS += GO_GLOG_FIX_PATH
diff --git a/package/golang/go_goczmq/go_goczmq.mk b/package/golang/go_goczmq/go_goczmq.mk
index fdb7950..076ba30 100644
--- a/package/golang/go_goczmq/go_goczmq.mk
+++ b/package/golang/go_goczmq/go_goczmq.mk
@@ -10,7 +10,7 @@
 
 define GO_GOCZMQ_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/zeromq"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/zeromq/goczmq"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/zeromq/goczmq"
 endef
 
 GO_GOCZMQ_POST_PATCH_HOOKS += GO_GOCZMQ_FIX_PATH
diff --git a/package/golang/go_godbus_dbus/go_godbus_dbus.mk b/package/golang/go_godbus_dbus/go_godbus_dbus.mk
index fc16412..15c040e 100644
--- a/package/golang/go_godbus_dbus/go_godbus_dbus.mk
+++ b/package/golang/go_godbus_dbus/go_godbus_dbus.mk
@@ -10,7 +10,7 @@
 
 define GO_GODBUS_DBUS_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/godbus/"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/godbus/dbus"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/godbus/dbus"
 endef
 
 GO_GODBUS_DBUS_POST_PATCH_HOOKS += GO_GODBUS_DBUS_FIX_PATH
diff --git a/package/golang/go_golua/go_golua.mk b/package/golang/go_golua/go_golua.mk
index 27e65c6..f8e9d5b 100644
--- a/package/golang/go_golua/go_golua.mk
+++ b/package/golang/go_golua/go_golua.mk
@@ -10,7 +10,7 @@
 
 define GO_GOLUA_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/aarzilli"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/aarzilli/golua"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/aarzilli/golua"
 endef
 
 GO_GOLUA_POST_PATCH_HOOKS += GO_GOLUA_FIX_PATH
diff --git a/package/golang/go_gonzojive_mdns/go_gonzojive_mdns.mk b/package/golang/go_gonzojive_mdns/go_gonzojive_mdns.mk
index 340a339..5f842e0 100644
--- a/package/golang/go_gonzojive_mdns/go_gonzojive_mdns.mk
+++ b/package/golang/go_gonzojive_mdns/go_gonzojive_mdns.mk
@@ -10,7 +10,7 @@
 
 define GO_GONZOJIVE_MDNS_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/gonzojive"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/gonzojive/mdns"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/gonzojive/mdns"
 endef
 
 GO_GONZOJIVE_MDNS_POST_PATCH_HOOKS += GO_GONZOJIVE_MDNS_FIX_PATH
diff --git a/package/golang/go_google_api/go_google_api.mk b/package/golang/go_google_api/go_google_api.mk
index 4b96596..f063fb4 100644
--- a/package/golang/go_google_api/go_google_api.mk
+++ b/package/golang/go_google_api/go_google_api.mk
@@ -10,7 +10,7 @@
 
 define GO_GOOGLE_API_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/google.golang.org"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/google.golang.org/api"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/google.golang.org/api"
 endef
 
 GO_GOOGLE_API_POST_PATCH_HOOKS += GO_GOOGLE_API_FIX_PATH
diff --git a/package/golang/go_grpc/go_grpc.mk b/package/golang/go_grpc/go_grpc.mk
index 21e68cc..97ca85d 100644
--- a/package/golang/go_grpc/go_grpc.mk
+++ b/package/golang/go_grpc/go_grpc.mk
@@ -10,7 +10,7 @@
 
 define GO_GRPC_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/google.golang.org/"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/google.golang.org/grpc"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/google.golang.org/grpc"
 endef
 
 GO_GRPC_POST_PATCH_HOOKS += GO_GRPC_FIX_PATH
diff --git a/package/golang/go_luar/go_luar.mk b/package/golang/go_luar/go_luar.mk
index 86432d4..0a7386d 100644
--- a/package/golang/go_luar/go_luar.mk
+++ b/package/golang/go_luar/go_luar.mk
@@ -10,7 +10,7 @@
 
 define GO_LUAR_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/stevedonovan/"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/stevedonovan/luar"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/stevedonovan/luar"
 endef
 
 GO_LUAR_POST_PATCH_HOOKS += GO_LUAR_FIX_PATH
diff --git a/package/golang/go_miekg_dns/go_miekg_dns.mk b/package/golang/go_miekg_dns/go_miekg_dns.mk
index 1917ca2..86133b6 100644
--- a/package/golang/go_miekg_dns/go_miekg_dns.mk
+++ b/package/golang/go_miekg_dns/go_miekg_dns.mk
@@ -10,7 +10,7 @@
 
 define GO_MIEKG_DNS_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/miekg"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/miekg/dns"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/miekg/dns"
 endef
 
 GO_MIEKG_DNS_POST_PATCH_HOOKS += GO_MIEKG_DNS_FIX_PATH
diff --git a/package/golang/go_net/go_net.mk b/package/golang/go_net/go_net.mk
index 4dff340..0e3ef15 100644
--- a/package/golang/go_net/go_net.mk
+++ b/package/golang/go_net/go_net.mk
@@ -10,7 +10,7 @@
 
 define GO_NET_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/golang.org/x"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/golang.org/x/net"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/golang.org/x/net"
 endef
 
 GO_NET_POST_PATCH_HOOKS += GO_NET_FIX_PATH
diff --git a/package/golang/go_oauth2/go_oauth2.mk b/package/golang/go_oauth2/go_oauth2.mk
index f2fe500..756208e 100644
--- a/package/golang/go_oauth2/go_oauth2.mk
+++ b/package/golang/go_oauth2/go_oauth2.mk
@@ -10,7 +10,7 @@
 
 define GO_OAUTH2_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/golang.org/x"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/golang.org/x/oauth2"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/golang.org/x/oauth2"
 endef
 
 GO_OAUTH2_POST_PATCH_HOOKS += GO_OAUTH2_FIX_PATH
diff --git a/package/golang/go_protobuf/go_protobuf.mk b/package/golang/go_protobuf/go_protobuf.mk
index a714e4d..3989108 100644
--- a/package/golang/go_protobuf/go_protobuf.mk
+++ b/package/golang/go_protobuf/go_protobuf.mk
@@ -10,7 +10,7 @@
 
 define GO_PROTOBUF_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/github.com/golang"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/golang/protobuf"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/github.com/golang/protobuf"
 endef
 
 GO_PROTOBUF_POST_PATCH_HOOKS += GO_PROTOBUF_FIX_PATH
@@ -20,7 +20,7 @@
 # Install Go protobuf compiler on host
 define HOST_GO_PROTOBUF_INSTALL_CMDS
 	mkdir -p "$(@D)/go/src/github.com/golang"
-	ln -sT "$(@D)" "$(@D)/go/src/github.com/golang/protobuf"
+	ln -sfT "$(@D)" "$(@D)/go/src/github.com/golang/protobuf"
         export $(GOLANG_ENV) ; \
 	GOARCH= GOBIN="$(HOST_DIR)/usr/bin" GOPATH="$(@D)/go" \
 	go install github.com/golang/protobuf/protoc-gen-go
diff --git a/package/golang/go_sys/go_sys.mk b/package/golang/go_sys/go_sys.mk
index 72cdcb5..dff37ba 100644
--- a/package/golang/go_sys/go_sys.mk
+++ b/package/golang/go_sys/go_sys.mk
@@ -10,7 +10,7 @@
 
 define GO_SYS_FIX_PATH
 	mkdir -p "$(BUILD_DIR)/go_pkgs/src/golang.org/x"
-	ln -sT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/golang.org/x/sys"
+	ln -sfT "$(@D)" "$(BUILD_DIR)/go_pkgs/src/golang.org/x/sys"
 endef
 
 GO_SYS_POST_PATCH_HOOKS += GO_SYS_FIX_PATH
diff --git a/package/google/google_gl_dart/Config.in b/package/google/google_gl_dart/Config.in
index 7692663..0bd1c7f 100644
--- a/package/google/google_gl_dart/Config.in
+++ b/package/google/google_gl_dart/Config.in
@@ -2,5 +2,6 @@
         bool "google_gl_dart"
   depends on BR2_PACKAGE_BCM_ROCKFORD
   depends on BR2_PACKAGE_GOOGLE_DART_VM
+  depends on BR2_PACKAGE_GOOGLE_MINICLIENT
 	help
           Builds the Dart GL bindings
diff --git a/package/google/google_gl_dart/google_gl_dart.mk b/package/google/google_gl_dart/google_gl_dart.mk
index 51c3a95..bbcfea1 100644
--- a/package/google/google_gl_dart/google_gl_dart.mk
+++ b/package/google/google_gl_dart/google_gl_dart.mk
@@ -1,7 +1,8 @@
 GOOGLE_GL_DART_SITE=repo://vendor/google/gl_dart
 GOOGLE_GL_DART_DEPENDENCIES=\
 	bcm_rockford \
-	google_dart_vm
+	google_dart_vm \
+	google_miniclient
 GOOGLE_GL_DART_INSTALL_STAGING=YES
 
 define GOOGLE_GL_DART_BUILD_CMDS
diff --git a/package/google/google_glfw_dart/Config.in b/package/google/google_glfw_dart/Config.in
index e816c43..977d139 100644
--- a/package/google/google_glfw_dart/Config.in
+++ b/package/google/google_glfw_dart/Config.in
@@ -1,7 +1,8 @@
 config BR2_PACKAGE_GOOGLE_GLFW_DART
         bool "google_glfw_dart"
-  depends on BR2_PACKAGE_BCM_COMMON
-  depends on BR2_PACKAGE_GOOGLE_GLFW_NEXUS
-  depends on BR2_PACKAGE_GOOGLE_DART_VM
+  select BR2_PACKAGE_BCM_COMMON
+  select BR2_PACKAGE_GOOGLE_GLFW_NEXUS
+  select BR2_PACKAGE_GOOGLE_DART_VM
+  depends on BR2_PACKAGE_GOOGLE_MINICLIENT
 	help
           Builds the Dart GLFW bindings
diff --git a/package/google/google_glfw_dart/google_glfw_dart.mk b/package/google/google_glfw_dart/google_glfw_dart.mk
index 8fc300e..0788d12 100644
--- a/package/google/google_glfw_dart/google_glfw_dart.mk
+++ b/package/google/google_glfw_dart/google_glfw_dart.mk
@@ -1,7 +1,7 @@
 GOOGLE_GLFW_DART_SITE=repo://vendor/google/glfw_dart
 GOOGLE_GLFW_DART_DEPENDENCIES=\
 	bcm_common \
-	google_glfw_nexus google_dart_vm
+	google_glfw_nexus google_dart_vm google_miniclient
 GOOGLE_GLFW_DART_INSTALL_STAGING=YES
 
 define GOOGLE_GLFW_DART_BUILD_CMDS
diff --git a/package/google/google_glfw_nexus/Config.in b/package/google/google_glfw_nexus/Config.in
index 386405c..5586666 100644
--- a/package/google/google_glfw_nexus/Config.in
+++ b/package/google/google_glfw_nexus/Config.in
@@ -1,5 +1,6 @@
 config BR2_PACKAGE_GOOGLE_GLFW_NEXUS
         bool "google_glfw_nexus"
 	select BR2_PACKAGE_BCM_ROCKFORD
+	depends on BR2_PACKAGE_GOOGLE_MINICLIENT
 	help
           Builds the GLFW with Nexus backend
diff --git a/package/google/google_miniclient/S11mpserver b/package/google/google_miniclient/S11mpserver
index 0b304e1..9c9f9f3 100755
--- a/package/google/google_miniclient/S11mpserver
+++ b/package/google/google_miniclient/S11mpserver
@@ -10,6 +10,7 @@
       # mcnmp_server playback code needs widevine and pullreader .so
       export LD_LIBRARY_PATH=/app/client
       export SAGEBIN_PATH=/usr/lib/sage_firmware
+      export DRM_BIN_FILE=/user/widevine/drm.bin
       rm -f /tmp/nexus_multiprocess
       babysit 10 mcnmp_server 2>&1 | logos mcnmp_server 0 20000000 &
       wait-until-created /tmp/nexus_multiprocess
diff --git a/package/google/google_miniclient/runminiclient b/package/google/google_miniclient/runminiclient
index a5e65bc..4dde33f 100755
--- a/package/google/google_miniclient/runminiclient
+++ b/package/google/google_miniclient/runminiclient
@@ -33,6 +33,7 @@
 }
 
 export LD_LIBRARY_PATH=/app/client:/usr/local/lib:$LD_LIBRARY_PATH
+export DRM_BIN_FILE=/user/widevine/drm.bin
 export SERIALNUMBER=$(cat /etc/serial)
 
 ulimit -c 49152
diff --git a/package/google/google_oregano_native/Config.in b/package/google/google_oregano_native/Config.in
index c6cb4dd..c6b26f3 100644
--- a/package/google/google_oregano_native/Config.in
+++ b/package/google/google_oregano_native/Config.in
@@ -1,5 +1,7 @@
 config BR2_PACKAGE_GOOGLE_OREGANO_NATIVE
 	bool "google_oregano_native"
 	select BR2_PACKAGE_GOOGLE_DART_VM
+	select BR2_PACKAGE_GOOGLE_GL_DART if BR2_mipsel
+	select BR2_PACKAGE_GOOGLE_GLFW_DART if BR2_mipsel
 	help
 	  Native extensions for Oregano projects.
diff --git a/package/google/google_platform/Config.in b/package/google/google_platform/Config.in
index 8a462d0..8d0ca58 100644
--- a/package/google/google_platform/Config.in
+++ b/package/google/google_platform/Config.in
@@ -101,6 +101,12 @@
 	help
 	  Include the ledpattern tool.
 
+config BR2_PACKAGE_GOOGLE_PLATFORM_SYSLOG
+	bool "include syslogd"
+	default n
+	help
+	  Simple syslog daemon with strong filtering support.
+
 config BR2_PACKAGE_GOOGLE_OPENBOX
 	bool "Openbox Release"
 	default n
diff --git a/package/google/google_platform/google_platform.mk b/package/google/google_platform/google_platform.mk
index b660253..4b7923d 100644
--- a/package/google/google_platform/google_platform.mk
+++ b/package/google/google_platform/google_platform.mk
@@ -143,6 +143,10 @@
 BUILD_LEDPATTERN=y
 endif
 
+ifeq ($(BR2_PACKAGE_GOOGLE_PLATFORM_SYSLOG),y)
+BUILD_SYSLOG=y
+endif
+
 ifneq ($(BR2_PACKAGE_GOOGLE_FIBER_JACK),y)
 # fiber jack kernel is too old for the new-style loguploader for now
 BUILD_LOGUPLOAD=y
@@ -277,6 +281,11 @@
 	$(INSTALL) -m 0755 -D -T package/google/google_platform/gfiber_public.der/$(PUB_KEY) $(TARGET_DIR)/etc/gfiber_public.der
 	$(if $(BR2_PACKAGE_GOOGLE_TV_BOX),mkdir -p -m 0755 $(TARGET_DIR)/usr/sv/)
 	$(if $(BR2_PACKAGE_GOOGLE_TV_BOX),$(INSTALL) -m 0555 -D package/google/google_platform/*.ts $(TARGET_DIR)/usr/sv/)
+	$(INSTALL) -m 0644 -D package/google/google_platform/syslog.conf $(TARGET_DIR)/etc/
+
+	# Avahi service files
+	$(INSTALL) -m 0644 -D package/google/google_platform/services/isoping.service $(TARGET_DIR)/etc/avahi/services
+	$(if $(BUILD_SYSLOG),$(INSTALL) -m 0644 -D package/google/google_platform/services/syslog.service $(TARGET_DIR)/etc/avahi/services)
 
 	# registercheck
 	#TODO(apenwarr): do we actually need this for anything?
diff --git a/package/google/google_platform/rc/syslog/dependencies b/package/google/google_platform/rc/syslog/dependencies
new file mode 100644
index 0000000..f977fbb
--- /dev/null
+++ b/package/google/google_platform/rc/syslog/dependencies
@@ -0,0 +1 @@
+firewall
diff --git a/package/google/google_platform/rc/syslog/run b/package/google/google_platform/rc/syslog/run
new file mode 100755
index 0000000..ee90f69
--- /dev/null
+++ b/package/google/google_platform/rc/syslog/run
@@ -0,0 +1,5 @@
+#!/usr/bin/execlineb
+fdmove -c 2 1
+if { runnable syslogd }
+# run with CAP_NET_BIND_SERVICE
+minijail0 -u syslog -g syslog -c 0x400 /bin/syslogd -p 514
diff --git a/package/google/google_platform/rc/syslog/type b/package/google/google_platform/rc/syslog/type
new file mode 100644
index 0000000..5883cff
--- /dev/null
+++ b/package/google/google_platform/rc/syslog/type
@@ -0,0 +1 @@
+longrun
diff --git a/package/google/google_platform/services/isoping.service b/package/google/google_platform/services/isoping.service
new file mode 100644
index 0000000..6a6618d
--- /dev/null
+++ b/package/google/google_platform/services/isoping.service
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+<service-group>
+    <name replace-wildcards="yes">isoping on %h</name>
+    <service>
+        <type>_isoping._udp</type>
+        <port>4948</port>
+    </service>
+</service-group>
diff --git a/package/google/google_platform/services/syslog.service b/package/google/google_platform/services/syslog.service
new file mode 100644
index 0000000..172abc6
--- /dev/null
+++ b/package/google/google_platform/services/syslog.service
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+<service-group>
+    <name replace-wildcards="yes">syslog on %h</name>
+    <service>
+        <type>_syslog._udp</type>
+        <port>514</port>
+    </service>
+</service-group>
diff --git a/package/google/google_platform/syslog.conf b/package/google/google_platform/syslog.conf
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/package/google/google_platform/syslog.conf
@@ -0,0 +1 @@
+.*
diff --git a/package/mv_app/xml_params/i2c_xml_cfg_file.xml b/package/mv_app/xml_params/i2c_xml_cfg_file.xml
index b41c999..3512bfa 100644
--- a/package/mv_app/xml_params/i2c_xml_cfg_file.xml
+++ b/package/mv_app/xml_params/i2c_xml_cfg_file.xml
@@ -2,6 +2,6 @@
 <cnfg>
     <I2C_CONFIG>
         <!--  Whether the transceiver can use i2c block read or character read 0-automatic, 1-read byte, 2-read block -->
-        <i2c_xvr_read_mode>0</i2c_xvr_read_mode>
+        <i2c_xvr_read_mode>2</i2c_xvr_read_mode>
     </I2C_CONFIG>
 </cnfg>
diff --git a/package/quantenna_drivers/quantenna_drivers.mk b/package/quantenna_drivers/quantenna_drivers.mk
index c24891d..3ed6491 100644
--- a/package/quantenna_drivers/quantenna_drivers.mk
+++ b/package/quantenna_drivers/quantenna_drivers.mk
@@ -21,8 +21,19 @@
 	$(QUANTENNA_DRIVERS_MAKE_ENV) $(MAKE) -C $(@D) $(QUANTENNA_DRIVERS_TARGET)
 endef
 
+# We need to re-run modules_install for depmod to discover the
+# binary kernel modules that we just installed
 define QUANTENNA_DRIVERS_INSTALL_TARGET_CMDS
 	$(QUANTENNA_DRIVERS_MAKE_ENV) $(MAKE) -C $(@D) $(QUANTENNA_DRIVERS_TARGET)_install
+
+	$(TARGET_MAKE_ENV) $(MAKE1) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR)		\
+		DEPMOD="$(HOST_DIR)/usr/sbin/depmod" modules_install ;		\
+	rm -f $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/build ;		\
+	rm -f $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/source
 endef
 
+ifeq ($(BR2_PACKAGE_QUANTENNA_DRIVERS),y)
+LINUX_KBUILD_EXTRA_SYMBOLS = $(QUANTENNA_DRIVERS_DIR)/binary_kos.symvers/$(QUANTENNA_DRIVERS_TARGET)/$(LINUX_VERSION_PROBED)/Module.symvers
+endif
+
 $(eval $(call GENTARGETS))
diff --git a/package/toybox/toybox.config b/package/toybox/toybox.config
index b01f19b..2b09397 100644
--- a/package/toybox/toybox.config
+++ b/package/toybox/toybox.config
@@ -206,7 +206,7 @@
 CONFIG_FREE=y
 # CONFIG_FREERAMDISK is not set
 # CONFIG_FSFREEZE is not set
-# CONFIG_FSYNC is not set
+CONFIG_FSYNC=y
 # CONFIG_HELP is not set
 # CONFIG_HELP_EXTRAS is not set
 # CONFIG_HEXEDIT is not set
diff --git a/support/scripts/mkmakefile b/support/scripts/mkmakefile
index a059052..336068c 100755
--- a/support/scripts/mkmakefile
+++ b/support/scripts/mkmakefile
@@ -40,6 +40,8 @@
 
 Makefile:;
 
+menuconfig linux-menuconfig backports-menuconfig: LOGLINEAR=
+
 \$(all): all
 	@:
 
diff --git a/toolchain/golang_bootstrap/golang_bootstrap.mk b/toolchain/golang_bootstrap/golang_bootstrap.mk
index d29a22f..d2e2b30 100644
--- a/toolchain/golang_bootstrap/golang_bootstrap.mk
+++ b/toolchain/golang_bootstrap/golang_bootstrap.mk
@@ -25,6 +25,8 @@
 define HOST_GOLANG_BOOTSTRAP_BUILD_CMDS
 	export PATH=$(TARGET_PATH) ; \
 	cd "$(@D)/src" && \
+	GOBIN= \
+	GOEXE= \
 	GOPATH= \
 	GOROOT= \
 	GOROOT_FINAL="$(GOLANG_BOOTSTRAP_GOROOT)" \