summaryrefslogtreecommitdiff
path: root/src/etc/dhcp
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-02-13 17:32:18 +0100
committerGitHub <noreply@github.com>2020-02-13 17:32:18 +0100
commit13bc01034d287ffdf1249138ddfbdbb1866b5a93 (patch)
tree755a97aa42b8e98699927543ffe7766f5b847a0f /src/etc/dhcp
parent233c463b4cf6f8ca4d3e2a1a3a30e5c62ce42061 (diff)
parente39f2ead18c17fa4a8fdfe35437202fb202e983a (diff)
downloadvyos-1x-13bc01034d287ffdf1249138ddfbdbb1866b5a93.tar.gz
vyos-1x-13bc01034d287ffdf1249138ddfbdbb1866b5a93.zip
Merge pull request #218 from zdc/T1987
dhclient-script: T1987: Multiple fixes in dhclient-script
Diffstat (limited to 'src/etc/dhcp')
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/01-vyos-logging20
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/02-vyos-stopdhclient27
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper76
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf39
-rw-r--r--src/etc/dhcp/dhclient-enter-hooks.d/05-vyos-mtureplace38
-rw-r--r--src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup16
-rw-r--r--src/etc/dhcp/dhclient-exit-hooks.d/vyatta-dhclient-hook39
7 files changed, 255 insertions, 0 deletions
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/01-vyos-logging b/src/etc/dhcp/dhclient-enter-hooks.d/01-vyos-logging
new file mode 100644
index 000000000..121fb21be
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/01-vyos-logging
@@ -0,0 +1,20 @@
+# enable logging
+LOG_ENABLE="yes"
+LOG_STDERR="no"
+LOG_TAG="dhclient-script-vyos"
+
+function logmsg () {
+ # log message to journal
+ case $1 in
+ error) LOG_PRIO="daemon.err" ;;
+ info) LOG_PRIO="daemon.info" ;;
+ esac
+
+ if [ "${LOG_ENABLE}" == "yes" ] ; then
+ if [ "${LOG_STDERR}" == "yes" ] ; then
+ /usr/bin/logger -e --id=$$ -s -p ${LOG_PRIO} -t ${LOG_TAG} "${@:2}"
+ else
+ /usr/bin/logger -e --id=$$ -p ${LOG_PRIO} -t ${LOG_TAG} "${@:2}"
+ fi
+ fi
+}
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/02-vyos-stopdhclient b/src/etc/dhcp/dhclient-enter-hooks.d/02-vyos-stopdhclient
new file mode 100644
index 000000000..d5d90632c
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/02-vyos-stopdhclient
@@ -0,0 +1,27 @@
+# skip all of this if dhclient-script running by stop command defined below
+if [ -z ${CONTROLLED_STOP} ] ; then
+ # stop dhclient for this interface, if it is not current one
+ # get PID for current dhclient
+ current_dhclient=`ps --no-headers --format ppid --pid $$ | awk '{ print $1 }'`
+
+ # get PID for master process (current can be a fork)
+ master_dhclient=`ps --no-headers --format ppid --pid $current_dhclient | awk '{ print $1 }'`
+
+ # get IP version for current dhclient
+ ipversion_arg=`ps --no-headers --format args --pid $current_dhclient | awk '{ print $2 }'`
+
+ # get list of all dhclient running for current interface
+ dhclients_pids=(`ps --no-headers --format pid,args -C dhclient | awk -v IFACE="/sbin/dhclient $ipversion_arg .*$interface$" '$0 ~ IFACE { print $1 }'`)
+
+ logmsg info "Current dhclient PID: $current_dhclient, Parent PID: $master_dhclient, IP version: $ipversion_arg, All dhclients for interface $interface: ${dhclients_pids[@]}"
+ # stop all dhclients for current interface, except current one
+ for dhclient in ${dhclients_pids[@]}; do
+ if ([ $dhclient -ne $current_dhclient ] && [ $dhclient -ne $master_dhclient ]); then
+ logmsg info "Stopping dhclient with PID: ${dhclient}"
+ # get path to PID-file of dhclient process
+ local dhclient_pidfile=`ps --no-headers --format args --pid $dhclient | awk 'match($0, ".*-pf (/.*pid) .*", PF) { print PF[1] }'`
+ # stop dhclient with native command - this will run dhclient-script with correct reason unlike simple kill
+ dhclient -e CONTROLLED_STOP=yes -x -pf $dhclient_pidfile
+ fi
+ done
+fi
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
new file mode 100644
index 000000000..59f92703c
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/03-vyos-ipwrapper
@@ -0,0 +1,76 @@
+# redefine ip command to use FRR when it is available
+
+# get status of FRR
+function frr_alive () {
+ /usr/lib/frr/watchfrr.sh all_status
+ if [ "$?" -eq "0" ] ; then
+ logmsg info "FRR status: running"
+ return 0
+ else
+ logmsg info "FRR status: not running"
+ return 1
+ fi
+}
+
+# convert ip route command to vtysh
+function iptovtysh () {
+ # prepare variables for vtysh command
+ VTYSH_DISTANCE="210"
+ VTYSH_TAG="210"
+ # convert default route to 0.0.0.0/0
+ if [ "$4" == "default" ] ; then
+ VTYSH_NETADDR="0.0.0.0/0"
+ else
+ VTYSH_NETADDR=$4
+ fi
+ # add /32 to ip addresses without netmasks
+ if [[ ! $VTYSH_NETADDR =~ ^.*/[[:digit:]]+$ ]] ; then
+ VTYSH_NETADDR="$VTYSH_NETADDR/32"
+ fi
+ # get gateway address
+ if [ "$5" == "via" ] ; then
+ VTYSH_GATEWAY=$6
+ fi
+ # get device name
+ if [ "$5" == "dev" ]; then
+ VTYSH_DEV=$6
+ elif [ "$7" == "dev" ]; then
+ VTYSH_DEV=$8
+ fi
+ VTYSH_CMD="ip route $VTYSH_NETADDR $VTYSH_GATEWAY $VTYSH_DEV tag $VTYSH_TAG $VTYSH_DISTANCE"
+ # delete route if the command is "del"
+ if [ "$3" == "del" ] ; then
+ VTYSH_CMD="no $VTYSH_CMD"
+ fi
+ logmsg info "Converted vtysh command: \"$VTYSH_CMD\""
+}
+
+# delete the same route from kernel before adding new one
+function delroute () {
+ logmsg info "Checking if the route presented in kernel: $@"
+ if /usr/sbin/ip route show $@ | grep -qx "$1 " ; then
+ logmsg info "Deleting IP route: \"/usr/sbin/ip route del $@\""
+ /usr/sbin/ip route del $@
+ fi
+}
+
+# replace ip command with this wrapper
+function ip () {
+ # pass comand to system `ip` if this is not related to routes change
+ if [ "$2" != "route" ] ; then
+ logmsg info "Passing command to /usr/sbin/ip: \"$@\""
+ /usr/sbin/ip $@
+ else
+ # if we want to work with routes, try to use FRR first
+ if frr_alive ; then
+ delroute ${@:4}
+ iptovtysh $@
+ logmsg info "Sending command to vtysh"
+ vtysh -c "conf t" -c "$VTYSH_CMD"
+ else
+ # add ip route to kernel
+ logmsg info "Modifying routes in kernel: \"/usr/sbin/ip $@\""
+ /usr/sbin/ip $@
+ fi
+ fi
+}
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf b/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf
new file mode 100644
index 000000000..ea5562ea8
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/04-vyos-resolvconf
@@ -0,0 +1,39 @@
+# modified make_resolv_conf () for Vyatta system below
+make_resolv_conf() {
+ if [ -n "$new_domain_name" ]; then
+ logmsg info "Adding search-domain \"$new_domain_name\" via vyos-hostsd-client"
+ /usr/bin/vyos-hostsd-client --set-host-name --search-domain $new_domain_name
+ fi
+
+ if [ -n "$new_dhcp6_domain_search" ]; then
+ logmsg info "Adding search-domain \"$new_dhcp6_domain_search\" via vyos-hostsd-client"
+ /usr/bin/vyos-hostsd-client --set-host-name --search-domain $new_dhcp6_domain_search
+ fi
+
+ if [ -n "$new_domain_name_servers" ] && ! cli-shell-api existsEffective system disable-dhcp-nameservers && [ "$new_domain_name_servers" != "$old_domain_name_servers" ] ; then
+ logmsg info "Deleting nameservers with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ vyos-hostsd-client --delete-name-servers --tag dhcp-$interface
+ NEW_SERVERS=""
+ for nameserver in $new_domain_name_servers; do
+ NEW_SERVERS="$NEW_SERVERS --name-server $nameserver"
+ done
+ logmsg info "Adding nameservers \"$NEW_SERVERS\" with tag \"dhcp-$interface\" via vyos-hostsd-client"
+ /usr/bin/vyos-hostsd-client --add-name-servers $NEW_SERVERS --tag dhcp-$interface
+ fi
+
+ if [ -n "$new_dhcp6_name_servers" ] && ! cli-shell-api existsEffective system disable-dhcp-nameservers && [ "$new_dhcp6_name_servers" != "$old_dhcp6_name_servers" ] ; then
+ logmsg info "Deleting nameservers with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ vyos-hostsd-client --delete-name-servers --tag dhcpv6-$interface
+ NEW_SERVERS=""
+ for nameserver in $new_dhcp6_name_servers; do
+ NEW_SERVERS="$NEW_SERVERS --name-server $nameserver"
+ done
+ logmsg info "Adding nameservers \"$NEW_SERVERS\" with tag \"dhcpv6-$interface\" via vyos-hostsd-client"
+ /usr/bin/vyos-hostsd-client --add-name-servers $NEW_SERVERS --tag dhcpv6-$interface
+ fi
+
+ if cli-shell-api existsEffective service dns forwarding; then
+ logmsg info "Enabling DNS forwarding"
+ /usr/libexec/vyos/conf_mode/dns_forwarding.py --dhclient
+ fi
+}
diff --git a/src/etc/dhcp/dhclient-enter-hooks.d/05-vyos-mtureplace b/src/etc/dhcp/dhclient-enter-hooks.d/05-vyos-mtureplace
new file mode 100644
index 000000000..4a08765ba
--- /dev/null
+++ b/src/etc/dhcp/dhclient-enter-hooks.d/05-vyos-mtureplace
@@ -0,0 +1,38 @@
+# replace MTU with value from configuration
+
+# get MTU value via Python
+# as configuration is not available to cli-shell-api at the first boot, we must use vyos.config, which contain workaround for this, instead clean shell
+function get_mtu {
+python3 - <<PYEND
+from vyos.config import Config
+import os
+import re
+
+# check if interface is not VLAN and fix name if necessary
+interface_name = os.getenv('interface', '')
+regex_filter = re.compile('^(?P<interface>\w+)\.(?P<vid>\d+)$')
+if regex_filter.search(interface_name):
+ iface = regex_filter.search(interface_name).group('interface')
+ vid = regex_filter.search(interface_name).group('vid')
+ interface_name = "{} vif {}".format(iface, vid)
+
+# initialize config
+config = Config()
+if config.exists('interfaces'):
+ iface_types = config.list_nodes('interfaces')
+ for iface_type in iface_types:
+ # check if configuration contain MTU value for interface and return (print) it
+ if config.exists("interfaces {} {} mtu".format(iface_type, interface_name)):
+ print(format(config.return_value("interfaces {} {} mtu".format(iface_type, interface_name))))
+PYEND
+}
+
+# check if DHCP server return MTU value
+if [ -n "$new_interface_mtu" ]; then
+ # try to get MTU from config and replace original one
+ configured_mtu="$(get_mtu)"
+ if [[ -n $configured_mtu ]] ; then
+ logmsg info "Replacing MTU value for $interface with preconfigured one: $configured_mtu"
+ new_interface_mtu="$configured_mtu"
+ fi
+fi
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup
new file mode 100644
index 000000000..ce846f6c3
--- /dev/null
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/01-vyos-cleanup
@@ -0,0 +1,16 @@
+if [[ $reason =~ (EXPIRE|FAIL|RELEASE|STOP) ]]; then
+ # delete dynamic nameservers from a configuration if lease was deleted
+ logmsg info "Deleting nameservers with tag \"dhcp-${interface}\" via vyos-hostsd-client"
+ vyos-hostsd-client --delete-name-servers --tag dhcp-${interface}
+ # try to delete default ip route (NOTE: here we use 'ip' wrapper, therefore a route will be actually deleted via /usr/sbin/ip or vtysh, according to the system state)
+ for router in $old_routers; do
+ logmsg info "Deleting default route: via $router dev ${interface}"
+ ip -4 route del default via $router dev ${interface}
+ done
+fi
+
+if [[ $reason =~ (EXPIRE6|RELEASE6|STOP6) ]]; then
+ # delete dynamic nameservers from a configuration if lease was deleted
+ logmsg info "Deleting nameservers with tag \"dhcpv6-${interface}\" via vyos-hostsd-client"
+ vyos-hostsd-client --delete-name-servers --tag dhcpv6-${interface}
+fi
diff --git a/src/etc/dhcp/dhclient-exit-hooks.d/vyatta-dhclient-hook b/src/etc/dhcp/dhclient-exit-hooks.d/vyatta-dhclient-hook
new file mode 100644
index 000000000..dcd06644f
--- /dev/null
+++ b/src/etc/dhcp/dhclient-exit-hooks.d/vyatta-dhclient-hook
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Author: Stig Thormodsrud <stig@vyatta.com>
+# Date: 2007
+# Description: dhcp client hook
+
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2006, 2007, 2008 Vyatta, Inc.
+# All Rights Reserved.
+# **** End License ****
+
+# To enable this script set the following variable to "yes"
+RUN="yes"
+
+if [ "$RUN" = "yes" ]; then
+ LOG=/var/lib/dhcp/dhclient_"$interface"_lease
+ echo `date` > $LOG
+
+ for i in reason interface new_expiry new_dhcp_lease_time medium \
+ alias_ip_address new_ip_address new_broadcast_address \
+ new_subnet_mask new_domain_name new_network_number \
+ new_domain_name_servers new_routers new_static_routes \
+ new_dhcp_server_identifier new_dhcp_message_type \
+ old_ip_address old_subnet_mask old_domain_name \
+ old_domain_name_servers old_routers \
+ old_static_routes; do
+ echo $i=\'${!i}\' >> $LOG
+ done
+fi