Package: isc-dhcp-client Version: 4.4.1-2.1+b2 The distributed dhclient-script will does not work correctly in a VRF environment, the default route will be added to the main routing table when the lease is obtained. This functionality should be extended, thus this is more of a feature request than a bug (though it does behave badly when presented with such an environment). Example: root@test:~# ip link add external type vrf table 1 root@test:~# ip rule add iif external table 1 root@test:~# ip rule add oif external table 1 root@test:~# ip link set ext master external root@test:~# dhclient ext root@test:~# ip route show table 1 broadcast 172.19.121.0 (172.19.226.0) dev ext proto kernel scope link src 172.19.121.181 172.19.121.0/24 (172.19.226.0/24) dev ext proto kernel scope link src 172.19.121.181 local 172.19.121.181 (172.19.226.181) dev ext proto kernel scope host src 172.19.121.181 (172.19.226.181) broadcast 172.19.121.255 (172.19.226.255) dev ext proto kernel scope link src 172.19.121.181 (172.19.226.181) root@test:~# ip route show default via 172.19.121.1 (172.19.226.1) dev ext
Expected behavior: if the interface is in a VRF, the default route will be added to the VRF. Here are the changes I made to the script (the detection method I used might break bridges though, however, I'd think bridge interfaces will never make it to that point anyway). My logic: detect whether this interface has a master or not, find it, find which table this route is meant to be a part of, and then set the string. If none of that happened, the string will be empty and things will work as they do now. This could be improved (in many ways, but in particular) by doing a backcheck of ip link show vrf $vrf and observing that we do indeed see $interface within that output. Tested in my environment and it properly gives two default routes, one in the VRF, one not. --- /sbin/dhclient-script 2020-03-23 03:08:55.000000000 -0600 +++ dhclient-script 2020-07-04 10:34:11.197856308 -0600 @@ -264,15 +264,23 @@ if_metric=${if_metric:-1} fi + # For VRFs. + vrf="`ip link show dev ${interface} | grep master | awk '{print $9}'`" + if [ ! -z $vrf ]; then + # find parent table + vrf_table="`ip vrf show | grep $vrf | awk '{print $2}'`" + vrf_string="table $vrf_table" + fi + for router in $new_routers; do if [ "$new_subnet_mask" = "255.255.255.255" ]; then # point-to-point connection => set explicit route - ip -4 route add ${router} dev $interface >/dev/null 2>&1 + ip -4 route add ${router} dev $interface $vrf_string >/dev/null 2>&1 fi # set default route ip -4 route add default via ${router} dev ${interface} \ - ${if_metric:+metric $if_metric} >/dev/null 2>&1 + ${if_metric:+metric $if_metric} $vrf_string >/dev/null 2>&1 if [ -n "$if_metric" ]; then if_metric=$((if_metric+1))