From dd2eb5e5686655c996ae95285b8ad7eb73d63d0b Mon Sep 17 00:00:00 2001 From: Brandon Stepler Date: Mon, 15 Feb 2021 10:30:00 -0500 Subject: dhcp: T3300: add DHCP default route distance --- data/templates/dhcp-client/daemon-options.tmpl | 2 +- interface-definitions/include/dhcp-options.xml.i | 12 ++++++++++ python/vyos/ifconfig/interface.py | 7 +++--- .../dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper | 28 +++++++++++++++------- src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup | 8 +++++-- 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/data/templates/dhcp-client/daemon-options.tmpl b/data/templates/dhcp-client/daemon-options.tmpl index 290aefa49..40629dca1 100644 --- a/data/templates/dhcp-client/daemon-options.tmpl +++ b/data/templates/dhcp-client/daemon-options.tmpl @@ -1,4 +1,4 @@ ### Autogenerated by interface.py ### -DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases {{ifname}}" +DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases{{" -e IF_METRIC=" ~ dhcp_options.default_route_distance if dhcp_options.default_route_distance is defined and dhcp_options.default_route_distance is not none}} {{ifname}}" diff --git a/interface-definitions/include/dhcp-options.xml.i b/interface-definitions/include/dhcp-options.xml.i index df9c7a97a..774714251 100644 --- a/interface-definitions/include/dhcp-options.xml.i +++ b/interface-definitions/include/dhcp-options.xml.i @@ -25,6 +25,18 @@ + + + Distance for the default route from DHCP server + + u32:1-255 + Distance for the default route from DHCP server (default 210) + + + + + + diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index d9507d816..86529b265 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -951,6 +951,9 @@ class Interface(Control): pid_file = f'{config_base}_{ifname}.pid' lease_file = f'{config_base}_{ifname}.leases' + # Stop client with old config files to get the right IF_METRIC. + self._cmd(f'systemctl stop dhclient@{ifname}.service') + if enable and 'disable' not in self._config: if dict_search('dhcp_options.host_name', self._config) == None: # read configured system hostname. @@ -969,10 +972,8 @@ class Interface(Control): # 'up' check is mandatory b/c even if the interface is A/D, as soon as # the DHCP client is started the interface will be placed in u/u state. # This is not what we intended to do when disabling an interface. - return self._cmd(f'systemctl restart dhclient@{ifname}.service') + return self._cmd(f'systemctl start dhclient@{ifname}.service') else: - self._cmd(f'systemctl stop dhclient@{ifname}.service') - # cleanup old config files for file in [config_file, options_file, pid_file, lease_file]: if os.path.isfile(file): diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper index d1161e704..8d996209f 100644 --- a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper +++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper @@ -1,5 +1,8 @@ # redefine ip command to use FRR when it is available +# default route distance +IF_METRIC=${IF_METRIC:-210} + # get status of FRR function frr_alive () { /usr/lib/frr/watchfrr.sh all_status @@ -15,11 +18,12 @@ function frr_alive () { # convert ip route command to vtysh function iptovtysh () { # prepare variables for vtysh command - local VTYSH_DISTANCE="210" - local VTYSH_TAG="210" + local VTYSH_ACTION=$3 local VTYSH_NETADDR="" local VTYSH_GATEWAY="" local VTYSH_DEV="" + local VTYSH_TAG="210" + local VTYSH_DISTANCE="" # convert default route to 0.0.0.0/0 if [ "$4" == "default" ] ; then VTYSH_NETADDR="0.0.0.0/0" @@ -30,15 +34,21 @@ function iptovtysh () { if [[ ! $VTYSH_NETADDR =~ ^.*/[[:digit:]]+$ ]] ; then VTYSH_NETADDR="$VTYSH_NETADDR/32" fi + shift 4 # get gateway address - if [ "$5" == "via" ] ; then - VTYSH_GATEWAY=$6 + if [ "$1" == "via" ] ; then + VTYSH_GATEWAY=$2 + shift 2 fi # get device name - if [ "$5" == "dev" ]; then - VTYSH_DEV=$6 - elif [ "$7" == "dev" ]; then - VTYSH_DEV=$8 + if [ "$1" == "dev" ]; then + VTYSH_DEV=$2 + shift 2 + fi + # get distance + if [ "$1" == "metric" ]; then + VTYSH_DISTANCE=$2 + shift 2 fi # Add route to VRF routing table @@ -49,7 +59,7 @@ function iptovtysh () { VTYSH_CMD="ip route $VTYSH_NETADDR $VTYSH_GATEWAY $VTYSH_DEV tag $VTYSH_TAG $VTYSH_DISTANCE $VTYSH_VRF" # delete route if the command is "del" - if [ "$3" == "del" ] ; then + if [ "$VTYSH_ACTION" == "del" ] ; then VTYSH_CMD="no $VTYSH_CMD" fi logmsg info "Converted vtysh command: \"$VTYSH_CMD\"" diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup index b768e1ae5..edb7c7b27 100644 --- a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup +++ b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup @@ -13,6 +13,8 @@ if [[ $reason =~ (EXPIRE|FAIL|RELEASE|STOP) ]]; then $hostsd_client --delete-name-servers --tag "dhcp-${interface}" hostsd_changes=y + if_metric="$IF_METRIC" + # try to delete default ip route for router in $old_routers; do # check if we are bound to a VRF @@ -21,8 +23,10 @@ if [[ $reason =~ (EXPIRE|FAIL|RELEASE|STOP) ]]; then vrf="vrf $vrf_name" fi - logmsg info "Deleting default route: via $router dev ${interface} ${vrf}" - ip -4 route del default via $router dev ${interface} ${vrf} + logmsg info "Deleting default route: via $router dev ${interface} ${if_metric:+metric $if_metric} ${vrf}" + ip -4 route del default via $router dev ${interface} ${if_metric:+metric $if_metric} ${vrf} + + if_metric=$((if_metric+1)) done # delete rfc3442 routes -- cgit v1.2.3