<p dir="ltr">Hi Zbyszek,</p>
<p dir="ltr">On 27 May 2014 04:38, "Zbigniew Jędrzejewski-Szmek" <<a href="mailto:zbyszek@in.waw.pl">zbyszek@in.waw.pl</a>> wrote:<br>
><br>
> On Mon, May 26, 2014 at 09:39:46PM +0200, Tom Gundersen wrote:<br>
> > When enabled in [Network] it will set up a dhcp server on the interface, listening<br>
> > on one of its statically configured IPv4 addresses and with a fixed size pool of<br>
> > leases determined from it.<br>
> Hi Tom,<br>
> before looking at the code, a couple of general questions:<br>
> - does the DHCP server have to be part of networkd? Isn't the job<br>
>   of acquiring addresses and giving out addresses separate and shouldn't<br>
>   two different processes be responsible?</p>
<p dir="ltr">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.</p>

<p dir="ltr">> - why the fixed limit of 32 addresses? Shouldn't the default be to give<br>
>   out all possible addresses except for the server one.</p>
<p dir="ltr">This should be configurable, but until we have figure out the syntax I just hard coded this to make it easy to test.</p>
<p dir="ltr">> > [Match]<br>
> > Name=ve-arch-tree<br>
> ><br>
> > [Network]<br>
> > Address=<a href="http://192.168.12.5/24">192.168.12.5/24</a><br>
> > DHCPServer=yes<br>
> ><br>
> > [Route]<br>
> > Gateway=192.168.12.5<br>
> > Destination=<a href="http://192.168.12.0/24">192.168.12.0/24</a><br>
> ><br>
> > In this case we will configure ve-arch-tree with the address 192.168.12.5 and<br>
> > hand out addresses in the range 192.168.12.6 - 192.168.12.38.<br>
> ><br>
> > In the future, we should (as suggested by Lennart) introduce a syntax to pick the<br>
> > server address automatically.<br>
> > ---<br>
> >  src/network/networkd-link.c              | 101 ++++++++++++++++++++++++++-----<br>
> >  src/network/networkd-network-gperf.gperf |   1 +<br>
> >  src/network/networkd.h                   |   5 ++<br>
> >  3 files changed, 93 insertions(+), 14 deletions(-)<br>
> ><br>
> > diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c<br>
> > index 6677b94..b80a002 100644<br>
> > --- a/src/network/networkd-link.c<br>
> > +++ b/src/network/networkd-link.c<br>
> > @@ -174,19 +174,6 @@ void link_drop(Link *link) {<br>
> >          return;<br>
> >  }<br>
> ><br>
> > -static int link_enter_configured(Link *link) {<br>
> > -        assert(link);<br>
> > -        assert(link->state == LINK_STATE_SETTING_ROUTES);<br>
> > -<br>
> > -        log_info_link(link, "link configured");<br>
> > -<br>
> > -        link->state = LINK_STATE_CONFIGURED;<br>
> > -<br>
> > -        link_save(link);<br>
> > -<br>
> > -        return 0;<br>
> > -}<br>
> > -<br>
> >  static void link_enter_unmanaged(Link *link) {<br>
> >          assert(link);<br>
> ><br>
> > @@ -227,6 +214,16 @@ static int link_stop_clients(Link *link) {<br>
> >                  }<br>
> >          }<br>
> ><br>
> > +        if (link->network->dhcp_server) {<br>
> > +                assert(link->dhcp_server);<br>
> > +<br>
> > +                k = sd_dhcp_server_stop(link->dhcp_server);<br>
> > +                if (k < 0) {<br>
> > +                        log_warning_link(link, "Could not stop DHCPv4 server: %s", strerror(-r));<br>
> > +                        r = k;<br>
> > +                }<br>
> > +        }<br>
> > +<br>
> >          return r;<br>
> >  }<br>
> ><br>
> > @@ -245,6 +242,37 @@ static void link_enter_failed(Link *link) {<br>
> >          link_save(link);<br>
> >  }<br>
> ><br>
> > +static int link_enter_configured(Link *link) {<br>
> > +        int r;<br>
> > +<br>
> > +        assert(link);<br>
> > +        assert(link->network);<br>
> > +        assert(link->state == LINK_STATE_SETTING_ROUTES);<br>
> > +<br>
> > +<br>
> > +        if (link->network->dhcp_server) {<br>
> > +                log_debug_link(link, "offering DHCPv4 leases");<br>
> > +<br>
> > +                r = sd_dhcp_server_start(link->dhcp_server);<br>
> > +                if (r < 0) {<br>
> > +                        log_warning_link(link, "could not start DHCPv4 server "<br>
> > +                                         "instance: %s", strerror(-r));<br>
> > +<br>
> > +                        link_enter_failed(link);<br>
> > +<br>
> > +                        return 0;<br>
> > +                }<br>
> > +        }<br>
> > +<br>
> > +        log_info_link(link, "link configured");<br>
> > +<br>
> > +        link->state = LINK_STATE_CONFIGURED;<br>
> > +<br>
> > +        link_save(link);<br>
> > +<br>
> > +        return 0;<br>
> > +}<br>
> > +<br>
> >  static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {<br>
> >          Link *link = userdata;<br>
> >          int r;<br>
> > @@ -1663,7 +1691,52 @@ static int link_configure(Link *link) {<br>
> >                  }<br>
> >          }<br>
> ><br>
> > -        if (link_has_carrier(link->flags, link->kernel_operstate)) {<br>
> > +        if (link->network->dhcp_server) {<br>
> > +                Address *address;<br>
> > +<br>
> > +                r = sd_dhcp_server_new(&link->dhcp_server, link->ifindex);<br>
> > +                if (r < 0)<br>
> > +                        return r;<br>
> > +<br>
> > +                r = sd_dhcp_server_attach_event(link->dhcp_server, NULL, 0);<br>
> > +                if (r < 0)<br>
> > +                        return r;<br>
> > +<br>
> > +                LIST_FOREACH(addresses, address,<br>
> > +                             link->network->static_addresses) {<br>
> > +                        struct in_addr pool_start;<br>
> > +<br>
> > +                        if (address->family != AF_INET)<br>
> > +                                continue;<br>
> > +<br>
> > +                        /* currently this is picked essentially at random */<br>
> > +                        r = sd_dhcp_server_set_address(link->dhcp_server,<br>
> > +                                                       &address-><a href="http://in_addr.in">in_addr.in</a>);<br>
> > +                        if (r < 0)<br>
> > +                                return r;<br>
> > +<br>
> > +                        /* offer 32 addresses starting from the address following the server address */<br>
> > +                        pool_start.s_addr = htobe32(be32toh(address->in_addr.in.s_addr) + 1);<br>
> > +                        r = sd_dhcp_server_set_lease_pool(link->dhcp_server,<br>
> > +                                                          &pool_start, 32);<br>
> > +<br>
> > +                        break;<br>
> > +                }<br>
> > +<br>
> > +                /* TODO:<br>
> > +                r = sd_dhcp_server_set_router(link->dhcp_server,<br>
> > +                                              &main_address-><a href="http://in_addr.in">in_addr.in</a>);<br>
> > +                if (r < 0)<br>
> > +                        return r;<br>
> > +<br>
> > +                r = sd_dhcp_server_set_prefixlen(link->dhcp_server,<br>
> > +                                                 main_address->prefixlen);<br>
> > +                if (r < 0)<br>
> > +                        return r;<br>
> > +                */<br>
> > +        }<br>
> > +<br>
> > +        if (link_has_carrier(link->flags, link->operstate)) {<br>
> >                  r = link_acquire_conf(link);<br>
> >                  if (r < 0)<br>
> >                          return r;<br>
> > diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf<br>
> > index 5038cb5..7ef467e 100644<br>
> > --- a/src/network/networkd-network-gperf.gperf<br>
> > +++ b/src/network/networkd-network-gperf.gperf<br>
> > @@ -30,6 +30,7 @@ Network.Bond,                config_parse_netdev,                0,<br>
> >  Network.VLAN,                config_parse_netdev,                0,                             offsetof(Network, vlans)<br>
> >  Network.MACVLAN,             config_parse_netdev,                0,                             offsetof(Network, macvlans)<br>
> >  Network.DHCP,                config_parse_bool,                  0,                             offsetof(Network, dhcp)<br>
> > +Network.DHCPServer,          config_parse_bool,                  0,                             offsetof(Network, dhcp_server)<br>
> >  Network.IPv4LL,              config_parse_bool,                  0,                             offsetof(Network, ipv4ll)<br>
> >  Network.Address,             config_parse_address,               0,                             0<br>
> >  Network.Gateway,             config_parse_gateway,               0,                             0<br>
> > diff --git a/src/network/networkd.h b/src/network/networkd.h<br>
> > index cfe24f5..994c052 100644<br>
> > --- a/src/network/networkd.h<br>
> > +++ b/src/network/networkd.h<br>
> > @@ -27,6 +27,7 @@<br>
> >  #include "sd-rtnl.h"<br>
> >  #include "sd-bus.h"<br>
> >  #include "sd-dhcp-client.h"<br>
> > +#include "sd-dhcp-server.h"<br>
> >  #include "sd-ipv4ll.h"<br>
> >  #include "udev.h"<br>
> ><br>
> > @@ -145,6 +146,8 @@ struct Network {<br>
> >          bool dhcp_critical;<br>
> >          bool ipv4ll;<br>
> ><br>
> > +        bool dhcp_server;<br>
> > +<br>
> >          LIST_HEAD(Address, static_addresses);<br>
> >          LIST_HEAD(Route, static_routes);<br>
> ><br>
> > @@ -252,6 +255,8 @@ struct Link {<br>
> >          char *lease_file;<br>
> >          uint16_t original_mtu;<br>
> >          sd_ipv4ll *ipv4ll;<br>
> > +<br>
> > +        sd_dhcp_server *dhcp_server;<br>
> >  };<br>
> ><br>
> >  struct Manager {<br>
> > --<br>
> > 1.9.0<br>
> ><br>
> > _______________________________________________<br>
> > systemd-devel mailing list<br>
> > <a href="mailto:systemd-devel@lists.freedesktop.org">systemd-devel@lists.freedesktop.org</a><br>
> > <a href="http://lists.freedesktop.org/mailman/listinfo/systemd-devel">http://lists.freedesktop.org/mailman/listinfo/systemd-devel</a><br>
> ><br>
</p>