[systemd-devel] [PATCH 17/17] networkd: add dhcp server support

Tom Gundersen teg at jklm.no
Tue May 27 02:08:31 PDT 2014


Hi Zbyszek,

On 27 May 2014 04:38, "Zbigniew Jędrzejewski-Szmek" <zbyszek at in.waw.pl>
wrote:
>
> 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?

As the dhcp library will need (eventually) a lot of state from networkd and
to hook into various events, I think having it integrated will make our
lives much easier. However, as all the logic lives in the library,
splitting it out later (when we know exactly how it will all look) should
not be a problem if that ends up making more sense.

> - why the fixed limit of 32 addresses? Shouldn't the default be to give
>   out all possible addresses except for the server one.

This should be configurable, but until we have figure out the syntax I just
hard coded this to make it easy to test.

> > [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
> >
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/systemd-devel/attachments/20140527/5ef14cd3/attachment-0001.html>


More information about the systemd-devel mailing list