Mercurial > hg > dhcpcd
view hooks/20-resolv.conf @ 5567:4fe5c2a71254 draft
hooks: add NOCARRIER_ROAMING reason
This is given when the OS supports the concept of wireless roaming
or the IP setup can be persisted when the carrier drops.
When this happens, routes are moved to a higher metric (if supported)
to support non preferred but non roaming routes.
The `interface_order` hook variable will now order the interfaces
according to priority and move roaming interfaces to the back of the
list.
If resolvconf is present then it is called with the -C option
to deprecate DNS and if carrier comes back it is called again with the
-c option to activate it once more.
As part of this change, default route metrics have been changed to
support a larger number of interfaces.
base metric 1000 (was 200)
wireless offset 2000 (was 100)
IPv4LL offset 1000000 (was 10000)
roaming offset 2000000
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sun, 27 Dec 2020 19:53:31 +0000 |
| parents | a0d828e25482 |
| children | aae13416e9b7 |
line wrap: on
line source
# Generate /etc/resolv.conf # Support resolvconf(8) if available # We can merge other dhcpcd resolv.conf files into one like resolvconf, # but resolvconf is preferred as other applications like VPN clients # can readily hook into it. # Also, resolvconf can configure local nameservers such as bind # or dnsmasq. This is important as the libc resolver isn't that powerful. resolv_conf_dir="$state_dir/resolv.conf" NL=" " : ${resolvconf:=resolvconf} if type "$resolvconf" >/dev/null 2>&1; then have_resolvconf=true else have_resolvconf=false fi build_resolv_conf() { cf="$state_dir/resolv.conf.$ifname" # Build a list of interfaces interfaces=$(list_interfaces "$resolv_conf_dir") # Build the resolv.conf header= if [ -n "$interfaces" ]; then # Build the header for x in ${interfaces}; do header="$header${header:+, }$x" done # Build the search list domain=$(cd "$resolv_conf_dir"; \ key_get_value "domain " ${interfaces}) search=$(cd "$resolv_conf_dir"; \ key_get_value "search " ${interfaces}) set -- ${domain} domain="$1" [ -n "$2" ] && search="$search $*" [ -n "$search" ] && search="$(uniqify $search)" [ "$domain" = "$search" ] && search= [ -n "$domain" ] && domain="domain $domain$NL" [ -n "$search" ] && search="search $search$NL" # Build the nameserver list srvs=$(cd "$resolv_conf_dir"; \ key_get_value "nameserver " ${interfaces}) for x in $(uniqify $srvs); do servers="${servers}nameserver $x$NL" done fi header="$signature_base${header:+ $from }$header" # Assemble resolv.conf using our head and tail files [ -f "$cf" ] && rm -f "$cf" [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" echo "$header" > "$cf" if [ -f /etc/resolv.conf.head ]; then cat /etc/resolv.conf.head >> "$cf" else echo "# /etc/resolv.conf.head can replace this line" >> "$cf" fi printf %s "$domain$search$servers" >> "$cf" if [ -f /etc/resolv.conf.tail ]; then cat /etc/resolv.conf.tail >> "$cf" else echo "# /etc/resolv.conf.tail can replace this line" >> "$cf" fi if change_file /etc/resolv.conf "$cf"; then chmod 644 /etc/resolv.conf fi rm -f "$cf" } # Extract any ND DNS options from the RA # Obey the lifetimes eval_nd_dns() { eval rdnsstime=\$nd${i}_rdnss${j}_lifetime [ -z "$rdnsstime" ] && return 1 ltime=$(($rdnsstime - $offset)) if [ "$ltime" -gt 0 ]; then eval rdnss=\$nd${i}_rdnss${j}_servers [ -n "$rdnss" ] && new_rdnss="$new_rdnss${new_rdnss:+ }$rdnss" fi eval dnssltime=\$nd${i}_dnssl${j}_lifetime [ -z "$dnssltime" ] && return 1 ltime=$(($dnssltime - $offset)) if [ "$ltime" -gt 0 ]; then eval dnssl=\$nd${i}_dnssl${j}_search [ -n "$dnssl" ] && new_dnssl="$new_dnssl${new_dnssl:+ }$dnssl" fi j=$(($j + 1)) return 0 } add_resolv_conf() { conf="$signature$NL" warn=true # Loop to extract the ND DNS options using our indexed shell values i=1 j=1 while true; do eval acquired=\$nd${i}_acquired [ -z "$acquired" ] && break eval now=\$nd${i}_now [ -z "$now" ] && break offset=$(($now - $acquired)) while true; do eval_nd_dns || break done i=$(($i + 1)) j=1 done [ -n "$new_rdnss" ] && \ new_domain_name_servers="$new_domain_name_servers${new_domain_name_servers:+ }$new_rdnss" [ -n "$new_dnssl" ] && \ new_domain_search="$new_domain_search${new_domain_search:+ }$new_dnssl" # Derive a new domain from our various hostname options if [ -z "$new_domain_name" ]; then if [ "$new_dhcp6_fqdn" != "${new_dhcp6_fqdn#*.}" ]; then new_domain_name="${new_dhcp6_fqdn#*.}" elif [ "$new_fqdn" != "${new_fqdn#*.}" ]; then new_domain_name="${new_fqdn#*.}" elif [ "$new_host_name" != "${new_host_name#*.}" ]; then new_domain_name="${new_host_name#*.}" fi fi # If we don't have any configuration, remove it if [ -z "$new_domain_name_servers" ] && [ -z "$new_domain_name" ] && [ -z "$new_domain_search" ]; then remove_resolv_conf return $? fi if [ -n "$new_domain_name" ]; then set -- $new_domain_name if valid_domainname "$1"; then conf="${conf}domain $1$NL" else syslog err "Invalid domain name: $1" fi # If there is no search this, make this one if [ -z "$new_domain_search" ]; then new_domain_search="$new_domain_name" [ "$new_domain_name" = "$1" ] && warn=true fi fi if [ -n "$new_domain_search" ]; then new_domain_search=$(uniqify $new_domain_search) if valid_domainname_list $new_domain_search; then conf="${conf}search $new_domain_search$NL" elif ! $warn; then syslog err "Invalid domain name in list:" \ "$new_domain_search" fi fi new_domain_name_servers=$(uniqify $new_domain_name_servers) for x in ${new_domain_name_servers}; do conf="${conf}nameserver $x$NL" done if $have_resolvconf; then [ -n "$ifmetric" ] && export IF_METRIC="$ifmetric" printf %s "$conf" | "$resolvconf" -a "$ifname" return $? fi if [ -e "$resolv_conf_dir/$ifname" ]; then rm -f "$resolv_conf_dir/$ifname" fi [ -d "$resolv_conf_dir" ] || mkdir -p "$resolv_conf_dir" printf %s "$conf" > "$resolv_conf_dir/$ifname" build_resolv_conf } remove_resolv_conf() { if $have_resolvconf; then "$resolvconf" -d "$ifname" -f else if [ -e "$resolv_conf_dir/$ifname" ]; then rm -f "$resolv_conf_dir/$ifname" fi build_resolv_conf fi } # For ease of use, map DHCP6 names onto our DHCP4 names case "$reason" in BOUND6|RENEW6|REBIND6|REBOOT6|INFORM6) new_domain_name_servers="$new_dhcp6_name_servers" new_domain_search="$new_dhcp6_domain_search" ;; esac if $if_configured; then if $have_resolvconf && [ "$reason" = NOCARRIER_ROAMING ]; then "$resolvconf" -C "$interface.*" elif $have_resolvconf && [ "$reason" = CARRIER ]; then "$resolvconf" -c "$interface.*" elif $if_up || [ "$reason" = ROUTERADVERT ]; then add_resolv_conf elif $if_down; then remove_resolv_conf fi fi
