diff --git a/src/initscripts/networking/dhcpcd.exe b/src/initscripts/networking/dhcpcd.exe
index 8a409d010..be6d63708 100644
--- a/src/initscripts/networking/dhcpcd.exe
+++ b/src/initscripts/networking/dhcpcd.exe
@@ -20,6 +20,7 @@
 
 . /etc/sysconfig/rc
 . $rc_functions
+. /etc/init.d/networking/functions.network
 
 eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
 
@@ -85,9 +86,70 @@ dhcpcd_down()
 	fi
 }
 
+# Called when dhcpcd relies on a third party to configure an IP address
+dhcpcd_3rdparty() {
+	local qmi_device="$(qmi_find_device "${interface}")"
+
+	if [ -n "${qmi_device}" ]; then
+		setup_qmi "${qmi_device}" || return $?
+	fi
+
+	return 0
+}
+
+setup_qmi() {
+	local device="${1}"
+
+	local address
+	local netmask
+	local gateway
+	local mtu=1500
+
+	local line
+	while read -r line; do
+		# Extract the value
+		value="${line#*: }"
+
+		case "${line}" in
+			*IPv4\ address:*)
+				address="${value}"
+				;;
+			*IPv4\ subnet\ mask:*)
+				netmask="${value}"
+				;;
+			*IPv4\ gateway\ address:*)
+				gateway="${value}"
+				;;
+			*MTU:*)
+				mtu="${value}"
+				;;
+		esac
+	done <<< "$(qmicli --device="${device}" --wds-get-current-settings)"
+
+	if [ -z "${address}" ] || [ -z "${netmask}" ] || [ -z "${gateway}" ]; then
+		logger -p "local0.info" -t "dhcpcd.exe[$$]" \
+			"Could not retrieve all information from the QMI interface"
+		return 1
+	fi
+
+	# Flush any previous configuration
+	ip addr flush dev "${interface}"
+
+	# Configure the IP address
+	ip addr add "${address}/${netmask}" dev "${interface}"
+
+	# Configure the default route
+	ip route add default via "${gateway}" #mtu "${mtu}"
+
+	return 0
+}
+
 case "$reason" in
 BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC)	dhcpcd_up;;
 PREINIT|EXPIRE|FAIL|IPV4LL|NAK|RELEASE|STOP)		dhcpcd_down;;
+3RDPARTY)
+	dhcpcd_3rdparty
+	;;
 *)
 	logger -p "local0.info" -t "dhcpcd.exe[$$]" "Unhandled DHCP event: ${reason}"
 	;;
diff --git a/src/initscripts/networking/functions.network b/src/initscripts/networking/functions.network
index f246919de..9698424fd 100644
--- a/src/initscripts/networking/functions.network
+++ b/src/initscripts/networking/functions.network
@@ -169,3 +169,93 @@ dhcpcd_stop() {
 		echo_failure
 	fi
 }
+
+# QMI stuff
+
+qmi_find_device() {
+	local intf="${1}"
+	local _intf
+
+	local path
+	for path in /dev/cdc-*; do
+		if [ -c "${path}" ]; then
+			_intf="$(qmicli --device="${path}" --device-open-proxy --get-wwan-iface)"
+
+			# Check if the interface matches
+			if [ "${intf}" = "${_intf}" ]; then
+				echo "${path}"
+				return 0
+			fi
+		fi
+	done
+
+	# Nothing found
+	return 1
+}
+
+qmi_enable_rawip_mode() {
+	local intf="${1}"
+
+	# Shut down the device first
+	ip link set "${intf}" down &>/dev/null
+
+	echo "Y" > "/sys/class/net/${intf}/qmi/raw_ip"
+}
+
+qmi_configure_apn() {
+	local device="${1}"
+
+	# APN settings
+	local apn="${2}"
+	local auth="${3}"
+	local username="${4}"
+	local password="${5}"
+
+	local args=(
+		# We only support IPv4 right now
+		"ip-type=4"
+	)
+
+	# Set APN
+	if [ -n "${apn}" ]; then
+		args+=( "apn=${apn}" )
+	fi
+
+	# Set auth
+	case "${auth}" in
+		PAP|CHAP)
+			args+=( "auth=${auth}" )
+			;;
+	esac
+
+	# Set username
+	if [ -n "${username}" ]; then
+		args+=( "username=${username}" )
+	fi
+
+	# Set password
+	if [ -n "${password}" ]; then
+		args+=( "password=${password}" )
+	fi
+
+	local _args
+
+	local arg
+	for arg in ${args[@]}; do
+		if [ -n "${_args}" ]; then
+			_args="${_args},"
+		fi
+		_args="${_args}${arg}"
+	done
+
+	qmicli --device="${device}" --device-open-proxy \
+		--wds-start-network="${_args}" \
+		--client-no-release-cid
+}
+
+qmi_reset() {
+	local device="${1}"
+
+	qmicli --device="${device}" --device-open-proxy \
+		--wds-reset
+}
diff --git a/src/initscripts/networking/red b/src/initscripts/networking/red
index fc10e077a..7df61c1cf 100644
--- a/src/initscripts/networking/red
+++ b/src/initscripts/networking/red
@@ -210,6 +210,27 @@ case "${1}" in
 				if [ "$TYPE" == "pptpatm" ]; then
 					TYPE="pptp"
 				fi
+
+			# QMI
+			elif [ "$TYPE" = "qmi" ]; then
+				DEVICE="$(qmi_find_device "${RED_DEV}")"
+
+				boot_mesg "Bringing up QMI on ${RED_DEV} (${DEVICE})..."
+
+				# Enable RAW-IP mode
+				qmi_enable_rawip_mode "${RED_DEV}"
+
+				# Configure APN
+				qmi_configure_apn "${DEVICE}" "${APN}" "${AUTH}" "${USERNAME}" "${PASSWORD}"
+
+				# Set up the interface
+				ip link set "${RED_DEV}" up &>/dev/null
+
+				# Start the DHCP client
+				dhcpcd_start "${RED_DEV}" --debug
+
+				# Done
+				exit 0
 			fi
 
 			if [ "$TYPE" == "vdsl" ]; then
@@ -477,6 +498,21 @@ case "${1}" in
 			run_subdir ${rc_base}/init.d/networking/red.down/
 
 		elif [ "$TYPE" == "PPPOE" ]; then
+			eval $(/usr/local/bin/readhash /var/ipfire/ppp/settings)
+
+			if [ "${TYPE}" = "qmi" ]; then
+				boot_mesg "Bringing down the QMI interface ${RED_DEV}..."
+				DEVICE="$(qmi_find_device "${RED_DEV}")"
+
+				# Stop the DHCP client on RED
+				dhcpcd_stop "${RED_DEV}"
+
+				# Reset any QMI settings
+				qmi_reset "${DEVICE}"
+
+				exit 0
+			fi
+
 			boot_mesg "Bringing down the PPP interface ..."
 			rm -f /var/ipfire/red/keepconnected
 			killall -w -s TERM /usr/sbin/pppd 2>/dev/null
