On Tue, 27.05.14 04:38, Zbigniew Jędrzejewski-Szmek (zbys...@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? I am very sure this should be in networkd. It's a very minor step to not only configure the local address and netmask, but also offer assigning these addresses to others. It's really just the other half of dhcp. In many ways the dhcp server is actually simpler than the client, since it just reacts, never acts, and never needs to locally/actively apply configuration. Moreover, the packet handling already kinda exists due to the dhcp client we have. I also really want the integration with the rest of networkd, in regard of forwarding the various bits and pieces that we know of the network, starting from the DNS configuration (so that we can just forward DNS server info, instead of having to masquerade it), but also about NTP, about timezones and whatnot. In today's network world dhcp is even used for the most basic of links. whether you use it between a container and the host, between a VM and its host, whether you turn your laptop into a hotspot for sharing your network, whether you use bluetooth PAN stuff, or whether you use miracast, ... A DHCP server really isn't and shouldn't be that standalone thing you install, that like let's say apache, or mysql is a major service you run. Instead it is just this tiny facet that some links we set up need a bit more management than others from our side. It is and should be a tiny detail of adressing, and whether you take the role of requesting addresses via dhcp or of serving them is an implementation detail in most ways, something that isn't relevant for much.q The container usecase alone is already the reason why I am so very sure I want this stuff, and that it needs to be in networkd, and just work. I want this fully automatic, so that we can create a hundred of veth tunnels, and trivially easy (simply by setting DHCPServer=yes for their .network file) make them automatically configured, passing the relevant configuration bits on. Remember that the goal here is not to write another ldap enabled monstrosity. This really should be just this tiny thing that can pass the bits of configuration it received from the user or from other interfaces on to a few other hosts, if that's desired. The focus is clearly on being automatic, and needing very little configuration. In the long run it should even be able to pick its own address range (which is useful to scale nicely to 100 veth tunnels), and hence just b this thing that works, that nicely scales, is as automatic as possible, and not the thing that people ever want to configure in all details and bells and whistles, because we already have enough dhcp server implementations for those cases... But anyway, I think it's easy to fall in the trap to assume that the server might actually be more complex than the client. Or that a server was an uncommon case. The dhcp server is in many ways simpler (doesn't even need raw sockets, ...), and simply a commodity we need not only on real networks all the time, but also on internal virtual links and links to local periphery devices... I hope that makes sense, Lennart > - 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 { > _______________________________________________ > systemd-devel mailing list > systemd-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/systemd-devel Lennart -- Lennart Poettering, Red Hat _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel