networkd: add dhcp server support

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.

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.
This commit is contained in:
Tom Gundersen 2014-03-05 08:13:30 +01:00
parent 500792d818
commit dd43110f78
3 changed files with 93 additions and 14 deletions

View File

@ -178,19 +178,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);
@ -231,6 +218,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;
}
@ -249,6 +246,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;
@ -1667,7 +1695,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;

View File

@ -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

View File

@ -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"
@ -149,6 +150,8 @@ struct Network {
bool dhcp_critical;
bool ipv4ll;
bool dhcp_server;
LIST_HEAD(Address, static_addresses);
LIST_HEAD(Route, static_routes);
@ -256,6 +259,8 @@ struct Link {
char *lease_file;
uint16_t original_mtu;
sd_ipv4ll *ipv4ll;
sd_dhcp_server *dhcp_server;
};
struct Manager {