For anyone who's having the same problem, here's the solution I came up with after a full day of reading:
#!/bin/bash
#define some variables
Primary_Interface="wlp4s0" # Replace with your primary internet-facing interface
Secondary_Interface="enp0s31f6" # Replace with your internal interface
Subnet="192.168.9.0/24"
Configure SNAT to maintain connection
nft add rule ip nat POSTROUTING oifname "$Primary_Interface" counter masquerade
nft add rule ip filter FORWARD iifname "$Primary_Interface" oifname "$Secondary_Interface" ct state related,established accept
nft add rule ip filter FORWARD iifname "$Secondary_Interface" oifname "$Primary_Interface" accept
add a rule to the mullvad's table to allow forwarding of my subnet's packets
nft insert rule inet mullvad forward ip saddr "$Subnet" accept
set a special mark on packets from and to my subnet for mullvad
nft add rule ip nat PREROUTING ip saddr "$Subnet" ct mark set 0x00000f41 meta mark set 0x6d6f6c65
nft add rule ip nat PREROUTING ip daddr "$Subnet" ct mark set 0x00000f41 meta mark set 0x6d6f6c65
Enable IP forwarding in kernel
#echo "1" > /proc/sys/net/ipv4/ip_forward
naturally, this needs to be executed with sudo.
The problem with the solution based on mullvad's own tutorial that everybody is sharing is that packets forwarded from a subnet never hit the input or output hook, going through prerouting, forward and postrouting instead. Here's a nice diagram that helped me a lot.
I have Ubuntu on my machine so the syntax here is for nftables instead of iptables.
You might want to uncomment the last line if you set this up for the first time. In my case I had ip forwarding already enabled.
Unfortunately anything added to mullvad table would disappear whenever I turn mullvad off and then back on. In this case I need to add the rule again manually (or put it in a separate script). I couldn't find a way to automate it.