From 59b8f6b628145586e87b8a4f6e29c755ad7d61ed Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 4 Aug 2014 20:57:02 +0200 Subject: [PATCH] sd-dhcp-server: always send out ROUTER and SUBNET_MASK For now we simply take these values from the server's address. --- src/libsystemd-network/dhcp-server-internal.h | 1 + src/libsystemd-network/sd-dhcp-server.c | 26 ++++++++++++++++++- src/libsystemd-network/test-dhcp-server.c | 9 ++++--- src/network/networkd-link.c | 2 +- src/systemd/sd-dhcp-server.h | 2 +- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index cdaa471b6..480da22c0 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -55,6 +55,7 @@ struct sd_dhcp_server { int index; be32_t address; + be32_t netmask; be32_t pool_start; size_t pool_size; size_t next_offer; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 50d9b7fcf..c224aa151 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -51,13 +51,16 @@ int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *addres return 0; } -int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address) { +int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen) { assert_return(server, -EINVAL); assert_return(address, -EINVAL); assert_return(address->s_addr, -EINVAL); + assert_return(prefixlen <= 32, -ERANGE); assert_return(server->address == htobe32(INADDR_ANY), -EBUSY); + assert_return(server->netmask == htobe32(INADDR_ANY), -EBUSY); server->address = address->s_addr; + server->netmask = htobe32(0xfffffffflu << (32 - prefixlen)); return 0; } @@ -150,6 +153,7 @@ int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) { server->fd_raw = -1; server->fd = -1; server->address = htobe32(INADDR_ANY); + server->netmask = htobe32(INADDR_ANY); server->index = ifindex; server->leases_by_client_id = hashmap_new(client_id_hash_func, client_id_compare_func); @@ -408,6 +412,16 @@ static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req, be32_t ad if (r < 0) return r; + r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_SUBNET_MASK, 4, &server->netmask); + if (r < 0) + return r; + + r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_ROUTER, 4, &server->address); + if (r < 0) + return r; + r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset); if (r < 0) return r; @@ -433,6 +447,16 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req, be32_t addr if (r < 0) return r; + r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_SUBNET_MASK, 4, &server->netmask); + if (r < 0) + return r; + + r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, + DHCP_OPTION_ROUTER, 4, &server->address); + if (r < 0) + return r; + r = dhcp_server_send_packet(server, req, packet, DHCP_ACK, offset); if (r < 0) return r; diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c index a9bdb9ab8..a94b62f8e 100644 --- a/src/libsystemd-network/test-dhcp-server.c +++ b/src/libsystemd-network/test-dhcp-server.c @@ -56,9 +56,10 @@ static int test_basic(sd_event *event) { assert_se(!sd_dhcp_server_unref(server)); assert_se(sd_dhcp_server_start(server) == -EUNATCH); - assert_se(sd_dhcp_server_set_address(server, &address_any) == -EINVAL); - assert_se(sd_dhcp_server_set_address(server, &address_lo) >= 0); - assert_se(sd_dhcp_server_set_address(server, &address_lo) == -EBUSY); + assert_se(sd_dhcp_server_set_address(server, &address_any, 28) == -EINVAL); + assert_se(sd_dhcp_server_set_address(server, &address_any, 38) == -ERANGE); + assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) >= 0); + assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) == -EBUSY); assert_se(sd_dhcp_server_set_lease_pool(server, &address_any, 1) == -EINVAL); assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 0) == -EINVAL); @@ -120,7 +121,7 @@ static void test_message_handler(void) { }; assert_se(sd_dhcp_server_new(&server, 1) >= 0); - assert_se(sd_dhcp_server_set_address(server, &address_lo) >= 0); + assert_se(sd_dhcp_server_set_address(server, &address_lo, 8) >= 0); assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0); assert_se(sd_dhcp_server_start(server) >= 0); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index e674b3b12..accb42bf3 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -311,7 +311,7 @@ static int link_enter_configured(Link *link) { log_debug_link(link, "offering DHCPv4 leases"); - r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in); + r = sd_dhcp_server_set_address(link->dhcp_server, &address->in_addr.in, address->prefixlen); if (r < 0) return r; diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index a4f7c85d6..9af3b6532 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -44,7 +44,7 @@ bool sd_dhcp_server_is_running(sd_dhcp_server *server); int sd_dhcp_server_start(sd_dhcp_server *server); int sd_dhcp_server_stop(sd_dhcp_server *server); -int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address); +int sd_dhcp_server_set_address(sd_dhcp_server *server, struct in_addr *address, unsigned char prefixlen); int sd_dhcp_server_set_lease_pool(sd_dhcp_server *server, struct in_addr *start, size_t size); int sd_dhcp_server_forcerenew(sd_dhcp_server *server); -- 2.30.2