[arch-projects] [netctl][PATCH 1/2] Factor out DHCP client support
Support for additional DHCP clients is now easy to add. --- Makefile | 3 +- docs/netctl.profile.5.txt | 16 +++++---- src/lib/connections/README | 2 +- src/lib/dhcp/README | 34 +++++++++++++++++++ src/lib/dhcp/dhclient | 27 +++++++++++++++ src/lib/dhcp/dhcpcd | 28 ++++++++++++++++ src/lib/ip | 83 ++++++++++++++-------------------------------- 7 files changed, 126 insertions(+), 67 deletions(-) create mode 100644 src/lib/dhcp/README create mode 100644 src/lib/dhcp/dhclient create mode 100644 src/lib/dhcp/dhcpcd diff --git a/Makefile b/Makefile index b22fbe0..08ad462 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,10 @@ install: install -d $(DESTDIR)/etc/netctl/{examples,hooks,interfaces} install -m644 docs/examples/* $(DESTDIR)/etc/netctl/examples/ # Libs - install -d $(DESTDIR)/usr/lib/network/connections + install -d $(DESTDIR)/usr/lib/network/{connections,dhcp} install -m644 src/lib/{globals,ip,rfkill,wpa} $(DESTDIR)/usr/lib/network/ install -m644 src/lib/connections/* $(DESTDIR)/usr/lib/network/connections/ + install -m644 src/lib/dhcp/* $(DESTDIR)/usr/lib/network/dhcp/ install -m755 src/lib/{auto.action,network} $(DESTDIR)/usr/lib/network/ # Scripts install -d $(DESTDIR)/usr/bin diff --git a/docs/netctl.profile.5.txt b/docs/netctl.profile.5.txt index dfc13bb..2cf0285 100644 --- a/docs/netctl.profile.5.txt +++ b/docs/netctl.profile.5.txt @@ -137,18 +137,20 @@ network. In particular, these connection types are +ethernet+, An array of custom routes of the form + `**<address range>** via **<gateway>**'. -'DHCPClient=' [requires a DHCP setting]:: - The name of the preferred DHCP client. Supported options are - `dhcpcd' and `dhclient'. Defaults to `dhcpcd'. +'DHCPClient=' [requires 'IP=dhcp']:: + The name of the DHCP client to use. Clients may accept additional + options through client-specific variables. By default, *netctl* + comes with support for `dhcpcd' and `dhclient'. Defaults to + `++dhcpcd++'. + +'DHCP6Client=' [requires 'IP6=dhcp' or 'IP6=dhcp-noaddr']:: + The name of the DHCPv6 client to use. By default, only `dhclient' + is supported. Defaults to `++dhclient++'. 'DHCPReleaseOnStop=':: Set to `++yes++' to release the DHCP lease when the profile is stopped. -'DhcpcdOptions=', 'DhclientOptions=', 'DhclientOptions6=':: - Additional options to be passed to the DHCP client. Do not use this - unless you know what you are doing. - 'IPCustom=()':: An array of argument lines to pass to `ip`. This can be used to achieve complicated configurations within the framework of *netctl*. diff --git a/src/lib/connections/README b/src/lib/connections/README index 6d8db9b..2dd4b7b 100644 --- a/src/lib/connections/README +++ b/src/lib/connections/README @@ -10,7 +10,7 @@ for the aviancarrier connection type will be provided by the file: Files that implement support for a connection type should NOT be executable. Such files should contain valid Bash code, among which two functions, namely <connection_type>_up and <connection_type>_down. For -the aviancarrier file this would be: +the aviancarrier file these would be: aviancarrier_up aviancarrier_down diff --git a/src/lib/dhcp/README b/src/lib/dhcp/README new file mode 100644 index 0000000..f55a06e --- /dev/null +++ b/src/lib/dhcp/README @@ -0,0 +1,34 @@ +Support for dhcp clients is implemented by files in + + /usr/lib/network/dhcp/ + +The file name determines the name of the client for the profile, so +support for a client named dhcpcd is provided by the file: + + /usr/lib/network/connections/dhcpcd + +Files that implement support for a connection type should NOT be +executable. Such files should contain valid Bash code, among which two +functions, namely <client_name>_start and <client_name>_stop. For +the client named dhcpcd these would be: + + dhcpcd_start + dhcpcd_stop + +These functions are responsible for starting and stopping the dhcp +client. When the functions are called, three bash files are already +sourced, so all functions and variables in those files are available. +The readily sourced files are: + + /usr/lib/network/network + /usr/lib/network/globals + /etc/netctl/<profile> + +Here, <profile> is the profile file specifying the desired network +configuration. + +When called, the start and stop functions get as their first argument +the version of the IP protocol that the dhcp client is expected to use. +In the case of starting the client for IPv6, an additional second +argument 'noaddr' may be supplied, which indicates that the dhcp client +should configure everything but an IP address. diff --git a/src/lib/dhcp/dhclient b/src/lib/dhcp/dhclient new file mode 100644 index 0000000..42b5f14 --- /dev/null +++ b/src/lib/dhcp/dhclient @@ -0,0 +1,27 @@ +type dhclient &> /dev/null || return + +dhclient_start() { + local options pidfile="/run/dhclient$1-$Interface.pid" + case $1 in + 4) options=$DhclientOptions;; + 6) options=$DhclientOptions6;; + *) return 1;; + esac + [[ $2 == "noaddr" ]] && options+=" -S" + rm -f "$pidfile" + if ! do_debug dhclient -$1 -q -e "TIMEOUT=${TimeoutDHCP:-30}" -pf "$pidfile" $options "$Interface"; then + report_error "DHCP IPv$1 lease attempt failed on interface '$Interface'" + return 1 + fi +} + +dhclient_stop() { + local stop="-x" pidfile="/run/dhclient$1-$Interface.pid" + if [[ -f $pidfile ]]; then + is_yes "${DHCPReleaseOnStop:-no}" && stop="-r" + do_debug dhclient -$1 -q $stop "$Interface" -pf "$pidfile" > /dev/null + fi +} + + +# vim: ft=sh ts=4 et sw=4: diff --git a/src/lib/dhcp/dhcpcd b/src/lib/dhcp/dhcpcd new file mode 100644 index 0000000..42f33ef --- /dev/null +++ b/src/lib/dhcp/dhcpcd @@ -0,0 +1,28 @@ +type dhcpcd &> /dev/null || return + +dhcpcd_start() { + if [[ $1 != "4" ]]; then + report_error "Using 'dhcpcd' for IPv6 is currently not possible in netctl" + return 1 + fi + rm -f "/run/dhcpcd-$Interface".{pid,cache} + # If using own dns, tell dhcpcd to NOT replace resolv.conf + [[ $DNS ]] && DhcpcdOptions+=" -C resolv.conf" + do_debug dhcpcd -4qL -t "${TimeoutDHCP:-30}" $DhcpcdOptions "$Interface" |& report_debug "$(cat)" + # The first array value of PIPESTATUS is the exit status of dhcpcd + if (( PIPESTATUS != 0 )); then + report_error "DHCP IP lease attempt failed on interface '$Interface'" + return 1 + fi +} + +dhcpcd_stop() { + local stop="-x" + if [[ -f "/run/dhcpcd-$Interface.pid" ]]; then + is_yes "${DHCPReleaseOnStop:-no}" && stop="-k" + do_debug dhcpcd -q $stop "$Interface" > /dev/null + fi +} + + +# vim: ft=sh ts=4 et sw=4: diff --git a/src/lib/ip b/src/lib/ip index 4698595..e737fc5 100644 --- a/src/lib/ip +++ b/src/lib/ip @@ -1,6 +1,26 @@ ## /usr/lib/network/globals needs to be sourced before this file +## Interface a DHCP client +# $1: DHCP client +# $2: command +# $3...: additional arguments +dhcp_call() { + local client="$1" command="$2" + shift 2 + + if [[ ! -r "$SUBR_DIR/dhcp/$client" ]]; then + report_error "DHCP client '$client' is unsupported" + return 127 + fi + if ! source "$SUBR_DIR/dhcp/$client"; then + report_error "DHCP client '$client' is not installed or not ready" + return 127 + fi + "${client}_$command" "$@" +} + + ## Add resolv.conf entries for an interface # $1: interface name # $2...: entries, one line per variable @@ -43,30 +63,7 @@ ip_set() { case $IP in dhcp) - case ${DHCPClient:-dhcpcd} in - dhcpcd) - rm -f "/run/dhcpcd-$Interface".{pid,cache} - # If using own dns, tell dhcpcd to NOT replace resolv.conf - [[ $DNS ]] && DhcpcdOptions+=" -C resolv.conf" - do_debug dhcpcd -4qL -t "${TimeoutDHCP:-30}" $DhcpcdOptions "$Interface" |& report_debug "$(cat)" - # The first array value of PIPESTATUS is the exit status of dhcpcd - if (( PIPESTATUS != 0 )); then - report_error "DHCP IP lease attempt failed on interface '$Interface'" - return 1 - fi - ;; - dhclient) - rm -f "/run/dhclient-${Interface}.pid" - if ! do_debug dhclient -4 -q -e "TIMEOUT=${TimeoutDHCP:-30}" -pf "/run/dhclient-$Interface.pid" $DhclientOptions "$Interface"; then - report_error "DHCP IP lease attempt failed on interface '$Interface'" - return 1 - fi - ;; - *) - report_error "Unsupported DHCP client: '$DHCPClient'" - return 1 - ;; - esac + dhcp_call "${DHCPClient:-dhcpcd}" start 4 || return ;; static) for addr in "${Address[@]}"; do @@ -103,17 +100,8 @@ ip_set() { fi case "$IP6" in - dhcp*) - if ! type dhclient &>/dev/null; then - report_error "You need to install dhclient to use DHCPv6" - return 1 - fi - [[ $IP6 == "dhcp-noaddr" ]] && DhclientOptions6+=" -S" - rm -f "/run/dhclient6-${Interface}.pid" - if ! do_debug dhclient -6 -q -e "TIMEOUT=${TimeoutDHCP:-30}" -pf "/run/dhclient6-${Interface}.pid" $DhclientOptions6 "$Interface"; then - report_error "DHCPv6 IP lease attempt failed on interface '$Interface'" - return 1 - fi + dhcp|dhcp-noaddr) + dhcp_call "${DHCP6Client:-dhclient}" start 6 ${IP6:5} || return ;; stateless|static) for addr in "${Address6[@]}"; do @@ -179,29 +167,8 @@ ip_set() { # $IP: type of IPv4 configuration # $IP6: type of IPv6 configuration ip_unset() { - local stop="-x" - if [[ $IP == "dhcp" ]]; then - case ${DHCPClient:-dhcpcd} in - dhcpcd) - if [[ -f "/run/dhcpcd-$Interface.pid" ]]; then - is_yes "${DHCPReleaseOnStop:-no}" && stop="-k" - do_debug dhcpcd -q $stop "$Interface" >/dev/null - fi - ;; - dhclient) - if [[ -f "/run/dhclient-$Interface.pid" ]]; then - is_yes "${DHCPReleaseOnStop:-no}" && stop="-r" - do_debug dhclient -q $stop "$Interface" -pf "/run/dhclient-$Interface.pid" >/dev/null - fi - ;; - esac - fi - if [[ $IP6 == dhcp* ]]; then - if [[ -f "/run/dhclient6-$Interface.pid" ]]; then - do_debug dhclient -6 -q -x "$Interface" -pf "/run/dhclient6-$Interface.pid" >/dev/null - fi - fi - + [[ $IP == "dhcp" ]] && dhcp_call "${DHCPClient:-dhcpcd}" stop 4 + [[ $IP6 == dhcp* ]] && dhcp_call "${DHCP6Client:-dhclient}" stop 6 [[ $DNS ]] && resolvconf -d "$Interface" ip route flush dev "$Interface" &>/dev/null ip -6 route flush dev "$Interface" &>/dev/null -- 1.9.0
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly... Thanks, -- Leonid Isaev GPG key fingerprint: C0DF 20D0 C075 C3F1 E1BE 775A A7AE F6CB 164B 5A6D
On Thu, Feb 27, 2014 at 12:56:02PM -0500, Leonid Isaev wrote:
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly...
This sounds like pointless masturbation. Just use networkd directly.
On Thu, 27 Feb 2014 13:03:27 -0500 Dave Reisner <d@falconindy.com> wrote:
On Thu, Feb 27, 2014 at 12:56:02PM -0500, Leonid Isaev wrote:
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly...
This sounds like pointless masturbation. Just use networkd directly.
That's what I originally thought, and (in a nutshell) this is what I am currently using. However, networkd config is based on an interface name, not a profile. Hence there are special cases when e.g. 2 wireless networks use different settings (dynamic/static IP, different DNS, etc.). In these scenarios one needs wpa_actiond. As long as the correct profile is selected, one can make use of networkd instead of dhcpcd. Best, -- Leonid Isaev GPG key fingerprint: C0DF 20D0 C075 C3F1 E1BE 775A A7AE F6CB 164B 5A6D
On Thu, Feb 27, 2014 at 7:20 PM, Leonid Isaev <lisaev@umail.iu.edu> wrote:
On Thu, 27 Feb 2014 13:03:27 -0500 Dave Reisner <d@falconindy.com> wrote:
On Thu, Feb 27, 2014 at 12:56:02PM -0500, Leonid Isaev wrote:
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly...
This sounds like pointless masturbation. Just use networkd directly.
That's what I originally thought, and (in a nutshell) this is what I am currently using.
However, networkd config is based on an interface name, not a profile. Hence there are special cases when e.g. 2 wireless networks use different settings (dynamic/static IP, different DNS, etc.). In these scenarios one needs wpa_actiond. As long as the correct profile is selected, one can make use of networkd instead of dhcpcd.
We probably want to improve networkd's [Match] logic, to also work in this case. I.e., to match on SSID. Not on my immediate TODO though, but patches welcome ;-) In general though, I quite like the idea of using networkd as a glorified dhcp client. We probably still lack some features in networkd before to make it support a bit of dynamic configuration before this really makes sense though. Cheers, Tom
On Thu, 27 Feb 2014 19:32:03 +0100 Tom Gundersen <teg@jklm.no> wrote:
On Thu, Feb 27, 2014 at 7:20 PM, Leonid Isaev <lisaev@umail.iu.edu> wrote:
On Thu, 27 Feb 2014 13:03:27 -0500 Dave Reisner <d@falconindy.com> wrote:
On Thu, Feb 27, 2014 at 12:56:02PM -0500, Leonid Isaev wrote:
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly...
This sounds like pointless masturbation. Just use networkd directly.
That's what I originally thought, and (in a nutshell) this is what I am currently using.
However, networkd config is based on an interface name, not a profile. Hence there are special cases when e.g. 2 wireless networks use different settings (dynamic/static IP, different DNS, etc.). In these scenarios one needs wpa_actiond. As long as the correct profile is selected, one can make use of networkd instead of dhcpcd.
We probably want to improve networkd's [Match] logic, to also work in this case. I.e., to match on SSID. Not on my immediate TODO though, but patches welcome ;-)
So, the SSID is supposed to be exposed by wpa_supplicant via dbus?
In general though, I quite like the idea of using networkd as a glorified dhcp client. We probably still lack some features in networkd before to make it support a bit of dynamic configuration before this really makes sense though.
Yes, but hopefully it won't become another NetworkManager :)
Cheers,
Tom
Thanks, -- Leonid Isaev GPG key fingerprint: C0DF 20D0 C075 C3F1 E1BE 775A A7AE F6CB 164B 5A6D
On Thu, Feb 27, 2014 at 9:25 PM, Leonid Isaev <lisaev@umail.iu.edu> wrote:
We probably want to improve networkd's [Match] logic, to also work in this case. I.e., to match on SSID. Not on my immediate TODO though, but patches welcome ;-)
So, the SSID is supposed to be exposed by wpa_supplicant via dbus?
The kernel exposes it over nl80211. -t
On Thu, Feb 27, 2014 at 7:20 PM, Leonid Isaev <lisaev@umail.iu.edu> wrote:
On Thu, 27 Feb 2014 13:03:27 -0500 Dave Reisner <d@falconindy.com> wrote:
On Thu, Feb 27, 2014 at 12:56:02PM -0500, Leonid Isaev wrote:
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly...
This sounds like pointless masturbation. Just use networkd directly.
That's what I originally thought, and (in a nutshell) this is what I am currently using.
However, networkd config is based on an interface name, not a profile. Hence there are special cases when e.g. 2 wireless networks use different settings (dynamic/static IP, different DNS, etc.). In these scenarios one needs wpa_actiond. As long as the correct profile is selected, one can make use of networkd instead of dhcpcd.
Contrary to networkd, netctl is profile based. This makes netctl useful in changing environments. If networkd exposes its dhcp client, this patch makes it easy to add support for it to netctl. Even better, if networkd exposes a lot of its functionality, netctl could potentially drop the dependency on iproute2 (not that there is a problem with iproute2). There are other dhcp clients (such as udhcp) for which support can already be implemented easily after this patch is applied. Regards, - Jouke
On Thu, 27 Feb 2014 20:39:18 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
On Thu, Feb 27, 2014 at 7:20 PM, Leonid Isaev <lisaev@umail.iu.edu> wrote:
On Thu, 27 Feb 2014 13:03:27 -0500 Dave Reisner <d@falconindy.com> wrote:
On Thu, Feb 27, 2014 at 12:56:02PM -0500, Leonid Isaev wrote:
On Thu, 27 Feb 2014 14:25:15 +0100 Jouke Witteveen <j.witteveen@gmail.com> wrote:
Support for additional DHCP clients is now easy to add.
Just a quick question: are there any plans to use networkd as a DHCP backend? Yes, it is config-file-driven, but one can probably generate the .network files in /run on the fly...
This sounds like pointless masturbation. Just use networkd directly.
That's what I originally thought, and (in a nutshell) this is what I am currently using.
However, networkd config is based on an interface name, not a profile. Hence there are special cases when e.g. 2 wireless networks use different settings (dynamic/static IP, different DNS, etc.). In these scenarios one needs wpa_actiond. As long as the correct profile is selected, one can make use of networkd instead of dhcpcd.
Contrary to networkd, netctl is profile based. This makes netctl useful in changing environments.
If networkd exposes its dhcp client, this patch makes it easy to add support for it to netctl.
There are no cli options, only config files. These will need to be generated based on a specific profile. So, the whole situation is similar to the way netctl-auto handles wpa-configsection.
Even better, if networkd exposes a lot of its functionality, netctl could potentially drop the dependency on iproute2 (not that there is a problem with iproute2).
Yes, static things like bridge, bond, and vlan for which netctl profiles are essentially identical to .net{dev,work} files. I think that the only advantage of netctl over networkd in this case is the ability to specify dependencies (via Before= and After=) between the respective units.
There are other dhcp clients (such as udhcp) for which support can already be implemented easily after this patch is applied.
Regards, - Jouke
Thanks, -- Leonid Isaev GPG key fingerprint: C0DF 20D0 C075 C3F1 E1BE 775A A7AE F6CB 164B 5A6D
On Thu, Feb 27, 2014 at 10:11 PM, Leonid Isaev <lisaev@umail.iu.edu> wrote:
Even better, if networkd exposes a lot of its functionality, netctl could potentially drop the dependency on iproute2 (not that there is a problem with iproute2).
Yes, static things like bridge, bond, and vlan for which netctl profiles are essentially identical to .net{dev,work} files. I think that the only advantage of netctl over networkd in this case is the ability to specify dependencies (via Before= and After=) between the respective units.
So networkd should sort out all that internally, but please let me know if you notice a usecase we are not covering. Cheers, Tom
participants (4)
-
Dave Reisner
-
Jouke Witteveen
-
Leonid Isaev
-
Tom Gundersen