<!-- language-all: sh -->

NetworkManager can either:

* update `resolv.conf` itself;

* delegate to `resolvconf` (for the `NetworkManager` interface);

* or use `netconfig`.

The different configurations coming from each interface are simply aggregated (see `update_dns()`).

If you do *not* use NetworkManager for the VPN, you might use `openresolv` exclusive mode (`-x`) in order to override the nameservers from `NetworkManager` with the ones from the VPN instead of adding them. This can be done with this (ugly) [script](https://wiki.ldn-fai.net/wiki/Tuto_Client_OpenVPN) (OpenVPN hook):

 #!/bin/sh
 
 # Dump all foreign options (coming from environment variables foreign_option_N) to stdout
 foreign_options() {
 local i
 i=1
 while true; do
 local varname=foreign_option_$i
 local value="$(eval echo \$$varname)"
 if [ -z "$value" ]; then
 return
 fi
 echo $value
 i=$((i+1))
 done
 }
 
 #Create a resolv.conf file from OpenVPN environment variables
 create_resolvconf() {
 foreign_options | grep "^dhcp-option DNS " | sed "s/^dhcp-option DNS /nameserver /"
 }
 
 route_up() { 
 create_resolvconf | resolvconf -x -a $dev
 }
 
 down() {
 resolvconf -d $dev
 }
 
 case "$script_type" in
 route-up) route_up "$@" ;;
 down) down "$@" ;;
 esac

You should be able to adapt this to be used as a NetworkManager dispatcher script (see man 8 NetworkManager) using:

* `VPN_IP4_NAMESERVERS`
* `VPN_IP6_NAMESERVERS`

I didn't test it but something like this should do the trick:

 #!/bin/sh
 
 create_resolvconf() {
 for ip in $VPN_IP4_NAMESERVERS $VPN_IP6_NAMESERVERS; do
 	 echo "nameserver $ip"
 done
 }
 
 up() {
 create_resolvconf | resolvconf -x -a $VPN_IP_IFAC
 }
 
 down() {
 resolvconf -d $VPN_IP_IFAC
 }

 if [ -z "$VPN_IP_IFACE" ]; then
 return 0
 fi
 
 case "$2" in
 up) up ;;
 down) down ;;
 esac