[systemd-devel] [PATCH 17/17] networkd: add dhcp server support
Zbigniew Jędrzejewski-Szmek
zbyszek at in.waw.pl
Mon May 26 19:38:05 PDT 2014
On Mon, May 26, 2014 at 09:39:46PM +0200, Tom Gundersen wrote:
> When enabled in [Network] it will set up a dhcp server on the interface, listening
> on one of its statically configured IPv4 addresses and with a fixed size pool of
> leases determined from it.
Hi Tom,
before looking at the code, a couple of general questions:
- does the DHCP server have to be part of networkd? Isn't the job
of acquiring addresses and giving out addresses separate and shouldn't
two different processes be responsible?
- why the fixed limit of 32 addresses? Shouldn't the default be to give
out all possible addresses except for the server one?
Zbyszek
> Example:
>
> [Match]
> Name=ve-arch-tree
>
> [Network]
> Address=192.168.12.5/24
> DHCPServer=yes
>
> [Route]
> Gateway=192.168.12.5
> Destination=192.168.12.0/24
>
> In this case we will configure ve-arch-tree with the address 192.168.12.5 and
> hand out addresses in the range 192.168.12.6 - 192.168.12.38.
>
> In the future, we should (as suggested by Lennart) introduce a syntax to pick the
> server address automatically.
> ---
> src/network/networkd-link.c | 101 ++++++++++++++++++++++++++-----
> src/network/networkd-network-gperf.gperf | 1 +
> src/network/networkd.h | 5 ++
> 3 files changed, 93 insertions(+), 14 deletions(-)
>
> diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
> index 6677b94..b80a002 100644
> --- a/src/network/networkd-link.c
> +++ b/src/network/networkd-link.c
> @@ -174,19 +174,6 @@ void link_drop(Link *link) {
> return;
> }
>
> -static int link_enter_configured(Link *link) {
> - assert(link);
> - assert(link->state == LINK_STATE_SETTING_ROUTES);
> -
> - log_info_link(link, "link configured");
> -
> - link->state = LINK_STATE_CONFIGURED;
> -
> - link_save(link);
> -
> - return 0;
> -}
> -
> static void link_enter_unmanaged(Link *link) {
> assert(link);
>
> @@ -227,6 +214,16 @@ static int link_stop_clients(Link *link) {
> }
> }
>
> + if (link->network->dhcp_server) {
> + assert(link->dhcp_server);
> +
> + k = sd_dhcp_server_stop(link->dhcp_server);
> + if (k < 0) {
> + log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));
> + r = k;
> + }
> + }
> +
> return r;
> }
>
> @@ -245,6 +242,37 @@ static void link_enter_failed(Link *link) {
> link_save(link);
> }
>
> +static int link_enter_configured(Link *link) {
> + int r;
> +
> + assert(link);
> + assert(link->network);
> + assert(link->state == LINK_STATE_SETTING_ROUTES);
> +
> +
> + if (link->network->dhcp_server) {
> + log_debug_link(link, "offering DHCPv4 leases");
> +
> + r = sd_dhcp_server_start(link->dhcp_server);
> + if (r < 0) {
> + log_warning_link(link, "could not start DHCPv4 server "
> + "instance: %s", strerror(-r));
> +
> + link_enter_failed(link);
> +
> + return 0;
> + }
> + }
> +
> + log_info_link(link, "link configured");
> +
> + link->state = LINK_STATE_CONFIGURED;
> +
> + link_save(link);
> +
> + return 0;
> +}
> +
> static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
> Link *link = userdata;
> int r;
> @@ -1663,7 +1691,52 @@ static int link_configure(Link *link) {
> }
> }
>
> - if (link_has_carrier(link->flags, link->kernel_operstate)) {
> + if (link->network->dhcp_server) {
> + Address *address;
> +
> + r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);
> + if (r < 0)
> + return r;
> +
> + r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);
> + if (r < 0)
> + return r;
> +
> + LIST_FOREACH(addresses, address,
> + link->network->static_addresses) {
> + struct in_addr pool_start;
> +
> + if (address->family != AF_INET)
> + continue;
> +
> + /* currently this is picked essentially at random */
> + r = sd_dhcp_server_set_address(link->dhcp_server,
> + &address->in_addr.in);
> + if (r < 0)
> + return r;
> +
> + /* offer 32 addresses starting from the address following the server address */
> + pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);
> + r = sd_dhcp_server_set_lease_pool(link->dhcp_server,
> + &pool_start, 32);
> +
> + break;
> + }
> +
> + /* TODO:
> + r = sd_dhcp_server_set_router(link->dhcp_server,
> + &main_address->in_addr.in);
> + if (r < 0)
> + return r;
> +
> + r = sd_dhcp_server_set_prefixlen(link->dhcp_server,
> + main_address->prefixlen);
> + if (r < 0)
> + return r;
> + */
> + }
> +
> + if (link_has_carrier(link->flags, link->operstate)) {
> r = link_acquire_conf(link);
> if (r < 0)
> return r;
> diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
> index 5038cb5..7ef467e 100644
> --- a/src/network/networkd-network-gperf.gperf
> +++ b/src/network/networkd-network-gperf.gperf
> @@ -30,6 +30,7 @@ Network.Bond, config_parse_netdev, 0,
> Network.VLAN, config_parse_netdev, 0, offsetof(Network, vlans)
> Network.MACVLAN, config_parse_netdev, 0, offsetof(Network, macvlans)
> Network.DHCP, config_parse_bool, 0, offsetof(Network, dhcp)
> +Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server)
> Network.IPv4LL, config_parse_bool, 0, offsetof(Network, ipv4ll)
> Network.Address, config_parse_address, 0, 0
> Network.Gateway, config_parse_gateway, 0, 0
> diff --git a/src/network/networkd.h b/src/network/networkd.h
> index cfe24f5..994c052 100644
> --- a/src/network/networkd.h
> +++ b/src/network/networkd.h
> @@ -27,6 +27,7 @@
> #include "sd-rtnl.h"
> #include "sd-bus.h"
> #include "sd-dhcp-client.h"
> +#include "sd-dhcp-server.h"
> #include "sd-ipv4ll.h"
> #include "udev.h"
>
> @@ -145,6 +146,8 @@ struct Network {
> bool dhcp_critical;
> bool ipv4ll;
>
> + bool dhcp_server;
> +
> LIST_HEAD(Address, static_addresses);
> LIST_HEAD(Route, static_routes);
>
> @@ -252,6 +255,8 @@ struct Link {
> char *lease_file;
> uint16_t original_mtu;
> sd_ipv4ll *ipv4ll;
> +
> + sd_dhcp_server *dhcp_server;
> };
>
> struct Manager {
> --
> 1.9.0
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
More information about the systemd-devel
mailing list