diff --git a/package/network/services/noddos/patches/050-fix-gcc13.patch b/package/network/services/noddos/patches/050-fix-gcc13.patch
new file mode 100644
index 00000000000000..1b2c600cec2571
--- /dev/null
+++ b/package/network/services/noddos/patches/050-fix-gcc13.patch
@@ -0,0 +1,10 @@
+--- a/src/iDeviceInfoSource.h
++++ b/src/iDeviceInfoSource.h
+@@ -23,6 +23,7 @@
+ #ifndef IDEVICEINFOSOURCE_H_
+ #define IDEVICEINFOSOURCE_H_
+ 
++#include <cstdint>
+ #include <string>
+ 
+ class iDeviceInfoSource {
diff --git a/package/network/utils/uqmi/Makefile b/package/network/utils/uqmi/Makefile
index 26eeee12a630e7..af9f8cc73435ff 100644
--- a/package/network/utils/uqmi/Makefile
+++ b/package/network/utils/uqmi/Makefile
@@ -1,19 +1,20 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uqmi
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL=$(PROJECT_GIT)/project/uqmi.git
-PKG_SOURCE_DATE:=2022-05-04
-PKG_SOURCE_VERSION:=56cb2d4056fef132ccf78dfb6f3074ae5d109992
-PKG_MIRROR_HASH:=cc832b5318805df8c8387a3650f250dee72d5f1dbda4e4866b5503e186b2210c
+PKG_SOURCE_DATE:=2024-08-25
+PKG_SOURCE_VERSION:=28b48a10dbcd1177095b73c6d8086d10114f49b8
+PKG_MIRROR_HASH:=bf1f8112c94ce49a7c03a4b9593141129d63ce679f98594257c1f6ab9bc49766
 PKG_MAINTAINER:=Matti Laakso <malaakso@elisanet.fi>
 
 PKG_LICENSE:=GPL-2.0
 PKG_LICENSE_FILES:=
 
 PKG_FLAGS:=nonshared
+PKG_BUILD_FLAGS:=gc-sections
 
 include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/cmake.mk
@@ -31,20 +32,16 @@ define Package/uqmi/description
   the QMI-protocol.
 endef
 
-TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include -ffunction-sections -fdata-sections
-
-ifneq (,$(findstring $(GCC_MAJOR_VERSION), 12 13))
-	TARGET_CFLAGS += -Wno-error=dangling-pointer -Wno-error=maybe-uninitialized
-endif
-
-TARGET_LDFLAGS += -Wl,--gc-sections
+TARGET_CFLAGS += \
+	-I$(STAGING_DIR)/usr/include \
+	-Wno-error=maybe-uninitialized
 
 CMAKE_OPTIONS += \
 	-DDEBUG=1
 
 define Package/uqmi/install
 	$(INSTALL_DIR) $(1)/sbin
-	$(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi $(1)/sbin/
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/uqmi/uqmi $(1)/sbin/
 	$(CP) ./files/* $(1)/
 endef
 
diff --git a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
index c0134f44dde3e5..8ec577a90b7823 100755
--- a/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
+++ b/package/network/utils/uqmi/files/lib/netifd/proto/qmi.sh
@@ -11,6 +11,7 @@ proto_qmi_init_config() {
 	no_device=1
 	proto_config_add_string "device:device"
 	proto_config_add_string apn
+	proto_config_add_string v6apn
 	proto_config_add_string auth
 	proto_config_add_string username
 	proto_config_add_string password
@@ -19,8 +20,11 @@ proto_qmi_init_config() {
 	proto_config_add_string modes
 	proto_config_add_string pdptype
 	proto_config_add_int profile
+	proto_config_add_int v6profile
 	proto_config_add_boolean dhcp
 	proto_config_add_boolean dhcpv6
+	proto_config_add_boolean sourcefilter
+	proto_config_add_boolean delegate
 	proto_config_add_boolean autoconnect
 	proto_config_add_int plmn
 	proto_config_add_int timeout
@@ -31,14 +35,15 @@ proto_qmi_init_config() {
 proto_qmi_setup() {
 	local interface="$1"
 	local dataformat connstat plmn_mode mcc mnc
-	local device apn auth username password pincode delay modes pdptype
-	local profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS
+	local device apn v6apn auth username password pincode delay modes pdptype
+	local profile v6profile dhcp dhcpv6 autoconnect plmn timeout mtu $PROTO_DEFAULT_OPTIONS
 	local ip4table ip6table
 	local cid_4 pdh_4 cid_6 pdh_6
 	local ip_6 ip_prefix_length gateway_6 dns1_6 dns2_6
+	local profile_pdptype
 
-	json_get_vars device apn auth username password pincode delay modes
-	json_get_vars pdptype profile dhcp dhcpv6 autoconnect plmn ip4table
+	json_get_vars device apn v6apn auth username password pincode delay modes
+	json_get_vars pdptype profile v6profile dhcp dhcpv6 sourcefilter delegate autoconnect plmn ip4table
 	json_get_vars ip6table timeout mtu $PROTO_DEFAULT_OPTIONS
 
 	[ "$timeout" = "" ] && timeout="10"
@@ -81,7 +86,9 @@ proto_qmi_setup() {
 
 	echo "Waiting for SIM initialization"
 	local uninitialized_timeout=0
-	while uqmi -s -d "$device" --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
+	# timeout 3s for first call to avoid hanging uqmi
+	uqmi -d "$device" -t 3000 --get-pin-status > /dev/null 2>&1
+	while uqmi -s -d "$device" -t 1000 --get-pin-status | grep '"UIM uninitialized"' > /dev/null; do
 		[ -e "$device" ] || return 1
 		if [ "$uninitialized_timeout" -lt "$timeout" -o "$timeout" = "0" ]; then
 			let uninitialized_timeout++
@@ -94,9 +101,41 @@ proto_qmi_setup() {
 		fi
 	done
 
-	if uqmi -s -d "$device" --get-pin-status | grep '"Not supported"\|"Invalid QMI command"' > /dev/null; then
+	# Check if UIM application is stuck in illegal state
+	local uim_state_timeout=0
+	while true; do
+		json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)"
+		json_get_var card_application_state card_application_state
+
+		# SIM card is either completely absent or state is labeled as illegal
+		# Try to power-cycle the SIM card to recover from this state
+		if [ -z "$card_application_state" -o "$card_application_state" = "illegal" ]; then
+			echo "SIM in illegal state - Power-cycling SIM"
+
+			# Try to reset SIM application
+			uqmi -d "$device" -t 1000 --uim-power-off --uim-slot 1
+			sleep 3
+			uqmi -d "$device" -t 1000 --uim-power-on --uim-slot 1
+
+			if [ "$uim_state_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
+				let uim_state_timeout++
+				sleep 1
+				continue
+			fi
+
+			# Recovery failed
+			proto_notify_error "$interface" SIM_ILLEGAL_STATE
+			proto_block_restart "$interface"
+			return 1
+		else
+			break
+		fi
+	done
+
+	if uqmi -s -d "$device" -t 1000 --uim-get-sim-state | grep -q '"Not supported"\|"Invalid QMI command"' &&
+	   uqmi -s -d "$device" -t 1000 --get-pin-status | grep -q '"Not supported"\|"Invalid QMI command"' ; then
 		[ -n "$pincode" ] && {
-			uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null || {
+			uqmi -s -d "$device" -t 1000 --verify-pin1 "$pincode" > /dev/null || uqmi -s -d "$device" -t 1000 --uim-verify-pin1 "$pincode" > /dev/null || {
 				echo "Unable to verify PIN"
 				proto_notify_error "$interface" PIN_FAILED
 				proto_block_restart "$interface"
@@ -104,9 +143,12 @@ proto_qmi_setup() {
 			}
 		}
 	else
-		. /usr/share/libubox/jshn.sh
-		json_load "$(uqmi -s -d "$device" --get-pin-status)"
+		json_load "$(uqmi -s -d "$device" -t 1000 --get-pin-status)"
 		json_get_var pin1_status pin1_status
+		if [ -z "$pin1_status" ]; then
+			json_load "$(uqmi -s -d "$device" -t 1000 --uim-get-sim-state)"
+			json_get_var pin1_status pin1_status
+		fi
 		json_get_var pin1_verify_tries pin1_verify_tries
 
 		case "$pin1_status" in
@@ -127,7 +169,7 @@ proto_qmi_setup() {
 					return 1
 				}
 				if [ -n "$pincode" ]; then
-					uqmi -s -d "$device" --verify-pin1 "$pincode" > /dev/null 2>&1 || uqmi -s -d "$device" --uim-verify-pin1 "$pincode" > /dev/null 2>&1 || {
+					uqmi -s -d "$device" -t 1000 --verify-pin1 "$pincode" > /dev/null 2>&1 || uqmi -s -d "$device" -t 1000 --uim-verify-pin1 "$pincode" > /dev/null 2>&1 || {
 						echo "Unable to verify PIN"
 						proto_notify_error "$interface" PIN_FAILED
 						proto_block_restart "$interface"
@@ -144,16 +186,17 @@ proto_qmi_setup() {
 				echo "PIN already verified"
 				;;
 			*)
-				echo "PIN status failed ($pin1_status)"
+				echo "PIN status failed (${pin1_status:-sim_not_present})"
 				proto_notify_error "$interface" PIN_STATUS_FAILED
 				proto_block_restart "$interface"
 				return 1
 			;;
 		esac
+		json_cleanup
 	fi
 
 	if [ -n "$plmn" ]; then
-		json_load "$(uqmi -s -d "$device" --get-plmn)"
+		json_load "$(uqmi -s -d "$device" -t 1000 --get-plmn)"
 		json_get_var plmn_mode mode
 		json_get_vars mcc mnc || {
 			mcc=0
@@ -176,25 +219,17 @@ proto_qmi_setup() {
 		fi
 	fi
 
-	if [ -n "$mcc" -a -n "$mnc" ]; then
-		uqmi -s -d "$device" --set-plmn --mcc "$mcc" --mnc "$mnc" > /dev/null 2>&1 || {
-			echo "Unable to set PLMN"
-			proto_notify_error "$interface" PLMN_FAILED
-			proto_block_restart "$interface"
-			return 1
-		}
-	fi
-
 	# Cleanup current state if any
-	uqmi -s -d "$device" --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
+	uqmi -s -d "$device" -t 1000 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
+	uqmi -s -d "$device" -t 1000 --set-ip-family ipv6 --stop-network 0xffffffff --autoconnect > /dev/null 2>&1
 
 	# Go online
-	uqmi -s -d "$device" --set-device-operating-mode online > /dev/null 2>&1
+	uqmi -s -d "$device" -t 1000 --set-device-operating-mode online > /dev/null 2>&1
 
 	# Set IP format
-	uqmi -s -d "$device" --set-data-format 802.3 > /dev/null 2>&1
-	uqmi -s -d "$device" --wda-set-data-format 802.3 > /dev/null 2>&1
-	dataformat="$(uqmi -s -d "$device" --wda-get-data-format)"
+	uqmi -s -d "$device" -t 1000 --set-data-format 802.3 > /dev/null 2>&1
+	uqmi -s -d "$device" -t 1000 --wda-set-data-format 802.3 > /dev/null 2>&1
+	dataformat="$(uqmi -s -d "$device" -t 1000 --wda-get-data-format)"
 
 	if [ "$dataformat" = '"raw-ip"' ]; then
 
@@ -207,16 +242,33 @@ proto_qmi_setup() {
 		echo "Y" > /sys/class/net/$ifname/qmi/raw_ip
 	fi
 
-	uqmi -s -d "$device" --sync > /dev/null 2>&1
+	uqmi -s -d "$device" -t 1000 --sync > /dev/null 2>&1
 
-	uqmi -s -d "$device" --network-register > /dev/null 2>&1
+	uqmi -s -d "$device" -t 20000 --network-register > /dev/null 2>&1
+
+	# PLMN selection must happen after the call to network-register
+	if [ -n "$mcc" -a -n "$mnc" ]; then
+		uqmi -s -d "$device" -t 1000 --set-plmn --mcc "$mcc" --mnc "$mnc" > /dev/null 2>&1 || {
+			echo "Unable to set PLMN"
+			proto_notify_error "$interface" PLMN_FAILED
+			proto_block_restart "$interface"
+			return 1
+		}
+	fi
+
+	[ -n "$modes" ] && {
+		uqmi -s -d "$device" -t 1000 --set-network-modes "$modes" > /dev/null 2>&1
+		sleep 3
+		# Scan network to not rely on registration-timeout after RAT change
+		uqmi -s -d "$device" -t 30000 --network-scan > /dev/null 2>&1
+	}
 
 	echo "Waiting for network registration"
-	sleep 1
+	sleep 5
 	local registration_timeout=0
 	local registration_state=""
 	while true; do
-		registration_state=$(uqmi -s -d "$device" --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null)
+		registration_state=$(uqmi -s -d "$device" -t 1000 --get-serving-system 2>/dev/null | jsonfilter -e "@.registration" 2>/dev/null)
 
 		[ "$registration_state" = "registered" ] && break
 
@@ -224,7 +276,7 @@ proto_qmi_setup() {
 			if [ "$registration_timeout" -lt "$timeout" ] || [ "$timeout" = "0" ]; then
 				[ "$registration_state" = "searching" ] || {
 					echo "Device stopped network registration. Restart network registration"
-					uqmi -s -d "$device" --network-register > /dev/null 2>&1
+					uqmi -s -d "$device" -t 20000 --network-register > /dev/null 2>&1
 				}
 				let registration_timeout++
 				sleep 1
@@ -237,17 +289,23 @@ proto_qmi_setup() {
 		fi
 
 		proto_notify_error "$interface" NETWORK_REGISTRATION_FAILED
-		proto_block_restart "$interface"
 		return 1
 	done
 
-	[ -n "$modes" ] && uqmi -s -d "$device" --set-network-modes "$modes" > /dev/null 2>&1
 
 	echo "Starting network $interface"
 
-	pdptype=$(echo "$pdptype" | awk '{print tolower($0)}')
+	pdptype="$(echo "$pdptype" | awk '{print tolower($0)}')"
+
 	[ "$pdptype" = "ip" -o "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] || pdptype="ip"
 
+	# Configure PDP type and APN for profile 1.
+	# In case GGSN rejects IPv4v6 PDP, modem might not be able to
+	# establish a non-LTE data session.
+	profile_pdptype="$pdptype"
+	[ "$profile_pdptype" = "ip" ] && profile_pdptype="ipv4"
+	uqmi -s -d "$device" -t 1000 --modify-profile "3gpp,1" --apn "$apn" --pdp-type "$profile_pdptype" > /dev/null 2>&1
+
 	if [ "$pdptype" = "ip" ]; then
 		[ -z "$autoconnect" ] && autoconnect=1
 		[ "$autoconnect" = 0 ] && autoconnect=""
@@ -256,16 +314,16 @@ proto_qmi_setup() {
 	fi
 
 	[ "$pdptype" = "ip" -o "$pdptype" = "ipv4v6" ] && {
-		cid_4=$(uqmi -s -d "$device" --get-client-id wds)
+		cid_4=$(uqmi -s -d "$device" -t 1000 --get-client-id wds)
 		if ! [ "$cid_4" -eq "$cid_4" ] 2> /dev/null; then
 			echo "Unable to obtain client ID"
 			proto_notify_error "$interface" NO_CID
 			return 1
 		fi
 
-		uqmi -s -d "$device" --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1
+		uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --set-ip-family ipv4 > /dev/null 2>&1
 
-		pdh_4=$(uqmi -s -d "$device" --set-client-id wds,"$cid_4" \
+		pdh_4=$(uqmi -s -d "$device" -t 5000 --set-client-id wds,"$cid_4" \
 			--start-network \
 			${apn:+--apn $apn} \
 			${profile:+--profile $profile} \
@@ -277,35 +335,38 @@ proto_qmi_setup() {
 		# pdh_4 is a numeric value on success
 		if ! [ "$pdh_4" -eq "$pdh_4" ] 2> /dev/null; then
 			echo "Unable to connect IPv4"
-			uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
+			uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
 			proto_notify_error "$interface" CALL_FAILED
 			return 1
 		fi
 
 		# Check data connection state
-		connstat=$(uqmi -s -d "$device" --get-data-status)
+		connstat=$(uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --get-data-status)
 		[ "$connstat" == '"connected"' ] || {
 			echo "No data link!"
-			uqmi -s -d "$device" --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
+			uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_4" --release-client-id wds > /dev/null 2>&1
 			proto_notify_error "$interface" CALL_FAILED
 			return 1
 		}
 	}
 
 	[ "$pdptype" = "ipv6" -o "$pdptype" = "ipv4v6" ] && {
-		cid_6=$(uqmi -s -d "$device" --get-client-id wds)
+		cid_6=$(uqmi -s -d "$device" -t 1000 --get-client-id wds)
 		if ! [ "$cid_6" -eq "$cid_6" ] 2> /dev/null; then
 			echo "Unable to obtain client ID"
 			proto_notify_error "$interface" NO_CID
 			return 1
 		fi
 
-		uqmi -s -d "$device" --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1
+		uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --set-ip-family ipv6 > /dev/null 2>&1
+
+		: "${v6apn:=${apn}}"
+		: "${v6profile:=${profile}}"
 
-		pdh_6=$(uqmi -s -d "$device" --set-client-id wds,"$cid_6" \
+		pdh_6=$(uqmi -s -d "$device" -t 5000 --set-client-id wds,"$cid_6" \
 			--start-network \
-			${apn:+--apn $apn} \
-			${profile:+--profile $profile} \
+			${v6apn:+--apn $v6apn} \
+			${v6profile:+--profile $v6profile} \
 			${auth:+--auth-type $auth} \
 			${username:+--username $username} \
 			${password:+--password $password} \
@@ -314,16 +375,16 @@ proto_qmi_setup() {
 		# pdh_6 is a numeric value on success
 		if ! [ "$pdh_6" -eq "$pdh_6" ] 2> /dev/null; then
 			echo "Unable to connect IPv6"
-			uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
+			uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
 			proto_notify_error "$interface" CALL_FAILED
 			return 1
 		fi
 
 		# Check data connection state
-		connstat=$(uqmi -s -d "$device" --get-data-status)
+		connstat=$(uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --set-ip-family ipv6 --get-data-status)
 		[ "$connstat" == '"connected"' ] || {
 			echo "No data link!"
-			uqmi -s -d "$device" --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
+			uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid_6" --release-client-id wds > /dev/null 2>&1
 			proto_notify_error "$interface" CALL_FAILED
 			return 1
 		}
@@ -348,7 +409,7 @@ proto_qmi_setup() {
 
 	[ -n "$pdh_6" ] && {
 		if [ -z "$dhcpv6" -o "$dhcpv6" = 0 ]; then
-			json_load "$(uqmi -s -d $device --set-client-id wds,$cid_6 --get-current-settings)"
+			json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_6 --get-current-settings)"
 			json_select ipv6
 			json_get_var ip_6 ip
 			json_get_var gateway_6 gateway
@@ -376,11 +437,14 @@ proto_qmi_setup() {
 			json_init
 			json_add_string name "${interface}_6"
 			json_add_string ifname "@$interface"
+			[ "$pdptype" = "ipv4v6" ] && json_add_string iface_464xlat "0"
 			json_add_string proto "dhcpv6"
 			[ -n "$ip6table" ] && json_add_string ip6table "$ip6table"
 			proto_add_dynamic_defaults
 			# RFC 7278: Extend an IPv6 /64 Prefix to LAN
 			json_add_string extendprefix 1
+			[ "$delegate" = "0" ] && json_add_boolean delegate "0"
+			[ "$sourcefilter" = "0" ] && json_add_boolean sourcefilter "0"
 			[ -n "$zone" ] && json_add_string zone "$zone"
 			json_close_object
 			ubus call network add_dynamic "$(json_dump)"
@@ -389,7 +453,7 @@ proto_qmi_setup() {
 
 	[ -n "$pdh_4" ] && {
 		if [ "$dhcp" = 0 ]; then
-			json_load "$(uqmi -s -d $device --set-client-id wds,$cid_4 --get-current-settings)"
+			json_load "$(uqmi -s -d $device -t 1000 --set-client-id wds,$cid_4 --get-current-settings)"
 			json_select ipv4
 			json_get_var ip_4 ip
 			json_get_var gateway_4 gateway
@@ -432,16 +496,16 @@ qmi_wds_stop() {
 
 	[ -n "$cid" ] || return
 
-	uqmi -s -d "$device" --set-client-id wds,"$cid" \
+	uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
 		--stop-network 0xffffffff \
 		--autoconnect > /dev/null 2>&1
 
 	[ -n "$pdh" ] && {
-		uqmi -s -d "$device" --set-client-id wds,"$cid" \
+		uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
 			--stop-network "$pdh" > /dev/null 2>&1
 	}
 
-	uqmi -s -d "$device" --set-client-id wds,"$cid" \
+	uqmi -s -d "$device" -t 1000 --set-client-id wds,"$cid" \
 		--release-client-id wds > /dev/null 2>&1
 }