1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-28 03:25:31 +03:00

Merge pull request #19611 from yuwata/network-dhcp-server-introduce-server-address

network: dhcp-server: introduce ServerAddress= setting
This commit is contained in:
Yu Watanabe 2021-05-19 10:29:43 +09:00 committed by GitHub
commit e7901aba14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 280 additions and 136 deletions

View File

@ -2344,6 +2344,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>ServerAddress=</varname></term>
<listitem><para>Specifies server address for the DHCP server. Takes an IPv4 address with prefix
length, e.g., <literal>192.168.0.1/24</literal>. This setting may be useful when the link which
DHCP server running on has multiple static addresses. When unset, one of static addresses in
the link will be automatically selected. Defaults to unset.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>PoolOffset=</varname></term>
<term><varname>PoolSize=</varname></term>

View File

@ -225,7 +225,7 @@ int config_parse_address_label(
return 0;
}
if (k == 0xffffffffUL) {
if (k == UINT32_C(0xffffffff)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Address label is invalid, ignoring: %s", rvalue);
return 0;
}

View File

@ -146,12 +146,38 @@ Address *address_free(Address *address) {
static bool address_may_have_broadcast(const Address *a) {
assert(a);
if (a->family != AF_INET)
return false;
if (in4_addr_is_set(&a->in_addr_peer.in))
return false;
/* A /31 or /32 IPv4 address does not have a broadcast address.
* See https://tools.ietf.org/html/rfc3021 */
if (a->prefixlen > 30)
return false;
return a->family == AF_INET &&
in4_addr_is_null(&a->in_addr_peer.in) &&
a->prefixlen <= 30;
if (a->set_broadcast >= 0)
return a->set_broadcast;
return true; /* Defaults to true. */
}
void address_set_broadcast(Address *a) {
assert(a);
if (!address_may_have_broadcast(a))
return;
/* If explicitly configured, do not update the address. */
if (in4_addr_is_set(&a->broadcast))
return;
/* If Address= is 0.0.0.0, then the broadcast address will be set later in address_acquire(). */
if (in4_addr_is_null(&a->in_addr.in))
return;
a->broadcast.s_addr = a->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> a->prefixlen);
}
static bool address_may_set_broadcast(const Address *a, const Link *link) {
@ -161,9 +187,6 @@ static bool address_may_set_broadcast(const Address *a, const Link *link) {
if (!address_may_have_broadcast(a))
return false;
if (a->set_broadcast >= 0)
return a->set_broadcast;
/* Typical configuration for wireguard does not set broadcast. */
return !streq_ptr(link->kind, "wireguard");
}
@ -466,7 +489,7 @@ int address_get(Link *link, const Address *in, Address **ret) {
return -ENOENT;
}
int link_has_ipv6_address(Link *link, const struct in6_addr *address) {
int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **ret) {
_cleanup_(address_freep) Address *a = NULL;
int r;
@ -482,10 +505,10 @@ int link_has_ipv6_address(Link *link, const struct in6_addr *address) {
a->family = AF_INET6;
a->in_addr.in6 = *address;
return address_get(link, a, NULL) >= 0;
return address_get(link, a, ret);
}
static int link_get_ipv4_address(Set *addresses, const struct in_addr *address, Address **ret) {
static int addresses_get_ipv4_address(Set *addresses, const struct in_addr *address, Address **ret) {
Address *a;
assert(address);
@ -506,7 +529,35 @@ static int link_get_ipv4_address(Set *addresses, const struct in_addr *address,
return -ENOENT;
}
int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned char prefixlen, Address **ret) {
int r;
assert(link);
assert(address);
if (prefixlen != 0) {
_cleanup_(address_freep) Address *a = NULL;
/* If prefixlen is set, then we can use address_get(). */
r = address_new(&a);
if (r < 0)
return r;
a->family = AF_INET;
a->in_addr.in = *address;
a->prefixlen = prefixlen;
return address_get(link, a, ret);
}
if (addresses_get_ipv4_address(link->addresses, address, ret) >= 0)
return 0;
return addresses_get_ipv4_address(link->addresses_foreign, address, ret);
}
int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready) {
Address *a;
Link *link;
int r;
@ -514,18 +565,12 @@ int manager_has_address(Manager *manager, int family, const union in_addr_union
assert(IN_SET(family, AF_INET, AF_INET6));
assert(address);
if (family == AF_INET)
HASHMAP_FOREACH(link, manager->links) {
Address *a;
if (link_get_ipv4_address(link->addresses, &address->in, &a) >= 0)
if (family == AF_INET) {
HASHMAP_FOREACH(link, manager->links)
if (link_get_ipv4_address(link, &address->in, 0, &a) >= 0)
return !check_ready || address_is_ready(a);
if (link_get_ipv4_address(link->addresses_foreign, &address->in, &a) >= 0)
return !check_ready || address_is_ready(a);
}
else {
} else {
_cleanup_(address_freep) Address *tmp = NULL;
Address *a;
r = address_new(&tmp);
if (r < 0)
@ -825,7 +870,6 @@ int link_drop_addresses(Link *link) {
static int address_acquire(Link *link, const Address *original, Address **ret) {
union in_addr_union in_addr = IN_ADDR_NULL;
struct in_addr broadcast = {};
_cleanup_(address_freep) Address *na = NULL;
int r;
@ -847,16 +891,10 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
if (r == 0)
return -EBUSY;
if (original->family == AF_INET) {
/* Pick first address in range for ourselves ... */
/* Pick first address in range for ourselves. */
if (original->family == AF_INET)
in_addr.in.s_addr = in_addr.in.s_addr | htobe32(1);
/* .. and use last as broadcast address */
if (original->prefixlen > 30)
broadcast.s_addr = 0;
else
broadcast.s_addr = in_addr.in.s_addr | htobe32(0xFFFFFFFFUL >> original->prefixlen);
} else if (original->family == AF_INET6)
else if (original->family == AF_INET6)
in_addr.in6.s6_addr[15] |= 1;
r = address_new(&na);
@ -867,8 +905,8 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
if (r < 0)
return r;
na->broadcast = broadcast;
na->in_addr = in_addr;
address_set_broadcast(na);
r = set_ensure_put(&link->pool_addresses, &address_hash_ops, na);
if (r < 0)
@ -1119,6 +1157,32 @@ int link_request_static_addresses(Link *link) {
req->after_configure = static_address_after_configure;
}
if (in4_addr_is_set(&link->network->dhcp_server_address)) {
_cleanup_(address_freep) Address *address = NULL;
r = address_new(&address);
if (r < 0)
return log_oom();
address->family = AF_INET;
address->in_addr.in = link->network->dhcp_server_address;
address->prefixlen = link->network->dhcp_server_address_prefixlen;
address_set_broadcast(address);
/* The same address may be explicitly configured in [Address] or [Network] section.
* Configure the DHCP server address only when it is not. */
if (!link_is_static_address_configured(link, address)) {
Request *req;
r = link_request_address(link, TAKE_PTR(address), true, &link->static_address_messages,
static_address_handler, &req);
if (r < 0)
return r;
req->after_configure = static_address_after_configure;
}
}
if (link->static_address_messages == 0) {
link->static_addresses_configured = true;
link_check_ready(link);
@ -1960,10 +2024,9 @@ static int address_section_verify(Address *address) {
address->section->filename, address->section->line);
}
if (address_may_have_broadcast(address)) {
if (address->broadcast.s_addr == 0 && address->set_broadcast != 0)
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(0xfffffffflu >> address->prefixlen);
} else if (address->broadcast.s_addr != 0) {
if (address_may_have_broadcast(address))
address_set_broadcast(address);
else if (address->broadcast.s_addr != 0) {
log_warning("%s: broadcast address is set for IPv6 address or IPv4 address with prefixlength larger than 30. "
"Ignoring Broadcast= setting in the [Address] section from line %u.",
address->section->filename, address->section->line);

View File

@ -57,6 +57,7 @@ int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Lin
int address_remove(const Address *address, Link *link, link_netlink_message_handler_t callback);
bool address_equal(const Address *a1, const Address *a2);
bool address_is_ready(const Address *a);
void address_set_broadcast(Address *a);
int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret);
@ -65,7 +66,8 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
int link_drop_addresses(Link *link);
int link_drop_foreign_addresses(Link *link);
bool link_address_is_dynamic(const Link *link, const Address *address);
int link_has_ipv6_address(Link *link, const struct in6_addr *address);
int link_get_ipv6_address(Link *link, const struct in6_addr *address, Address **ret);
int link_get_ipv4_address(Link *link, const struct in_addr *address, unsigned char prefixlen, Address **ret);
int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready);
void ipv4_dad_unref(Link *link);

View File

@ -29,33 +29,70 @@ static bool link_dhcp4_server_enabled(Link *link) {
if (!link->network)
return false;
if (link->network->bond)
return false;
if (link->iftype == ARPHRD_CAN)
return false;
return link->network->dhcp_server;
}
static Address* link_find_dhcp_server_address(Link *link) {
void network_adjust_dhcp_server(Network *network) {
assert(network);
if (!network->dhcp_server)
return;
if (network->bond) {
log_warning("%s: DHCPServer= is enabled for bond slave. Disabling DHCP server.",
network->filename);
network->dhcp_server = false;
return;
}
if (!in4_addr_is_set(&network->dhcp_server_address)) {
Address *address;
bool have = false;
ORDERED_HASHMAP_FOREACH(address, network->addresses_by_section) {
if (section_is_invalid(address->section))
continue;
if (address->family == AF_INET &&
!in4_addr_is_localhost(&address->in_addr.in) &&
in4_addr_is_null(&address->in_addr_peer.in)) {
have = true;
break;
}
}
if (!have) {
log_warning("%s: DHCPServer= is enabled, but no static address configured. "
"Disabling DHCP server.",
network->filename);
network->dhcp_server = false;
return;
}
}
}
static int link_find_dhcp_server_address(Link *link, Address **ret) {
Address *address;
assert(link);
assert(link->network);
/* The first statically configured address if there is any */
ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section)
/* If ServerAddress= is specified, then use the address. */
if (in4_addr_is_set(&link->network->dhcp_server_address))
return link_get_ipv4_address(link, &link->network->dhcp_server_address,
link->network->dhcp_server_address_prefixlen, ret);
/* If not, then select one from static addresses. */
SET_FOREACH(address, link->static_addresses)
if (address->family == AF_INET &&
in_addr_is_set(address->family, &address->in_addr))
return address;
!in4_addr_is_localhost(&address->in_addr.in) &&
in4_addr_is_null(&address->in_addr_peer.in)) {
*ret = address;
return 0;
}
/* If that didn't work, find a suitable address we got from the pool */
SET_FOREACH(address, link->pool_addresses)
if (address->family == AF_INET)
return address;
return NULL;
return -ENOENT;
}
static int link_push_uplink_to_dhcp_server(
@ -277,10 +314,9 @@ int dhcp4_server_configure(Link *link) {
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set callback for DHCPv4 server instance: %m");
address = link_find_dhcp_server_address(link);
if (!address)
return log_link_error_errno(link, SYNTHETIC_ERRNO(EBUSY),
"Failed to find suitable address for DHCPv4 server instance.");
r = link_find_dhcp_server_address(link, &address);
if (r < 0)
return log_link_error_errno(link, r, "Failed to find suitable address for DHCPv4 server instance: %m");
/* use the server address' subnet as the pool */
r = sd_dhcp_server_configure_pool(link->dhcp_server, &address->in_addr.in, address->prefixlen,
@ -429,7 +465,6 @@ int config_parse_dhcp_server_relay_agent_suboption(
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
*suboption_value = mfree(*suboption_value);
return 0;
@ -444,32 +479,6 @@ int config_parse_dhcp_server_relay_agent_suboption(
return free_and_strdup(suboption_value, empty_to_null(p));
}
int config_parse_dhcp_server_relay_target(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = userdata;
union in_addr_union a;
int r;
r = in_addr_from_string(AF_INET, rvalue, &a);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s= address '%s', ignoring: %m", lvalue, rvalue);
return 0;
}
network->dhcp_server_relay_target = a.in;
return r;
}
int config_parse_dhcp_server_emit(
const char *unit,
const char *filename,
@ -518,3 +527,48 @@ int config_parse_dhcp_server_emit(
emit->addresses[emit->n_addresses++] = a.in;
}
}
int config_parse_dhcp_server_address(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = userdata;
union in_addr_union a;
unsigned char prefixlen;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
network->dhcp_server_address = (struct in_addr) {};
network->dhcp_server_address_prefixlen = 0;
return 0;
}
r = in_addr_prefix_from_string(rvalue, AF_INET, &a, &prefixlen);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
if (in4_addr_is_null(&a.in) || in4_addr_is_localhost(&a.in)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"DHCP server address cannot be the ANY address or a localhost address, "
"ignoring assignment: %s", rvalue);
return 0;
}
network->dhcp_server_address = a.in;
network->dhcp_server_address_prefixlen = prefixlen;
return 0;
}

View File

@ -2,13 +2,14 @@
#pragma once
#include "conf-parser.h"
#include "networkd-link.h"
#include "networkd-util.h"
typedef struct Link Link;
typedef struct Network Network;
void network_adjust_dhcp_server(Network *network);
int dhcp4_server_configure(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_target);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_address);

View File

@ -1888,47 +1888,3 @@ int config_parse_dhcp6_pd_subnet_id(
return 0;
}
int config_parse_dhcp6_pd_token(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
struct in6_addr *addr = data;
union in_addr_union tmp;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
*addr = (struct in6_addr) {};
return 0;
}
r = in_addr_from_string(AF_INET6, rvalue, &tmp);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse DHCPv6 Prefix Delegation token, ignoring: %s", rvalue);
return 0;
}
if (in_addr_is_null(AF_INET6, &tmp)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"DHCPv6 Prefix Delegation token cannot be the ANY address, ignoring: %s", rvalue);
return 0;
}
*addr = tmp.in6;
return 0;
}

View File

@ -41,7 +41,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_client_start_mode);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_subnet_id);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_token);
const char* dhcp6_client_start_mode_to_string(DHCP6ClientStartMode i) _const_;
DHCP6ClientStartMode dhcp6_client_start_mode_from_string(const char *s) _pure_;

View File

@ -31,9 +31,9 @@ static int address_new_from_ipv4ll(Link *link, Address **ret) {
address->family = AF_INET;
address->in_addr.in = addr;
address->prefixlen = 16;
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> address->prefixlen);
address->scope = RT_SCOPE_LINK;
address->route_metric = IPV4LL_ROUTE_METRIC;
address_set_broadcast(address);
*ret = TAKE_PTR(address);
return 0;

View File

@ -541,7 +541,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
if (link_has_ipv6_address(link, &gateway) > 0) {
if (link_get_ipv6_address(link, &gateway, NULL) >= 0) {
if (DEBUG_LOGGING) {
_cleanup_free_ char *buffer = NULL;
@ -918,7 +918,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
if (link_has_ipv6_address(link, &gateway) > 0) {
if (link_get_ipv6_address(link, &gateway, NULL) >= 0) {
if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL;

View File

@ -261,7 +261,8 @@ IPv6AcceptRA.PrefixAllowList, config_parse_ndisc_address_filter,
IPv6AcceptRA.PrefixDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix)
IPv6AcceptRA.RouteAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_route_prefix)
IPv6AcceptRA.RouteDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_route_prefix)
DHCPServer.RelayTarget, config_parse_dhcp_server_relay_target, 0, 0
DHCPServer.ServerAddress, config_parse_dhcp_server_address, 0, 0
DHCPServer.RelayTarget, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_relay_target)
DHCPServer.RelayAgentCircuitId, config_parse_dhcp_server_relay_agent_suboption, 0, offsetof(Network, dhcp_server_relay_agent_circuit_id)
DHCPServer.RelayAgentRemoteId, config_parse_dhcp_server_relay_agent_suboption, 0, offsetof(Network, dhcp_server_relay_agent_remote_id)
DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec)
@ -314,7 +315,7 @@ DHCPv6PrefixDelegation.SubnetId, config_parse_dhcp6_pd_subnet_id,
DHCPv6PrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp6_pd_announce)
DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign)
DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address)
DHCPv6PrefixDelegation.Token, config_parse_dhcp6_pd_token, 0, offsetof(Network, dhcp6_pd_token)
DHCPv6PrefixDelegation.Token, config_parse_in_addr_non_null, AF_INET6, offsetof(Network, dhcp6_pd_token)
DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp6_pd_route_metric)
IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed)

View File

@ -240,6 +240,8 @@ int network_verify(Network *network) {
network_drop_invalid_traffic_control(network);
network_drop_invalid_sr_iov(network);
network_adjust_dhcp_server(network);
return 0;
}

View File

@ -189,10 +189,11 @@ struct Network {
/* DHCP Server Support */
bool dhcp_server;
bool dhcp_server_bind_to_interface;
unsigned char dhcp_server_address_prefixlen;
struct in_addr dhcp_server_address;
struct in_addr dhcp_server_relay_target;
char *dhcp_server_relay_agent_circuit_id;
char *dhcp_server_relay_agent_remote_id;
NetworkDHCPServerEmitAddress dhcp_server_emit[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
bool dhcp_server_emit_router;
bool dhcp_server_emit_timezone;

View File

@ -16,6 +16,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "in-addr-util.h"
#include "log.h"
#include "macro.h"
#include "missing_network.h"
@ -1359,5 +1360,57 @@ int config_parse_hwaddrs(
}
}
int config_parse_in_addr_non_null(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
/* data must be a pointer to struct in_addr or in6_addr, and the type is determined by ltype. */
struct in_addr *ipv4 = data;
struct in6_addr *ipv6 = data;
union in_addr_union a;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
assert(IN_SET(ltype, AF_INET, AF_INET6));
if (isempty(rvalue)) {
if (ltype == AF_INET)
*ipv4 = (struct in_addr) {};
else
*ipv6 = (struct in6_addr) {};
return 0;
}
r = in_addr_from_string(ltype, rvalue, &a);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
if (!in_addr_is_set(ltype, &a)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"%s= cannot be the ANY address, ignoring: %s", lvalue, rvalue);
return 0;
}
if (ltype == AF_INET)
*ipv4 = a.in;
else
*ipv6 = a.in6;
return 0;
}
DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
DEFINE_CONFIG_PARSE(config_parse_permyriad, parse_permyriad, "Failed to parse permyriad value");

View File

@ -149,6 +149,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
CONFIG_PARSER_PROTOTYPE(config_parse_in_addr_non_null);
CONFIG_PARSER_PROTOTYPE(config_parse_percent);
CONFIG_PARSER_PROTOTYPE(config_parse_permyriad);

View File

@ -364,6 +364,7 @@ BindToInterface=
RelayTarget=
RelayAgentCircuitId=
RelayAgentRemoteId=
ServerAddress=
[NextHop]
Id=
Gateway=

View File

@ -4,9 +4,11 @@ Name=veth-peer
[Network]
IPv6AcceptRA=false
Address=192.168.5.1/24
Address=192.168.5.2/24
DHCPServer=yes
[DHCPServer]
Address=192.168.5.1/24
PoolOffset=10
PoolSize=50
EmitRouter=yes

View File

@ -2,11 +2,11 @@
Name=veth-peer
[Network]
Address=192.168.5.1/24
IPv6AcceptRA=false
DHCPServer=yes
[DHCPServer]
ServerAddress=192.168.5.1/24
PoolOffset=10
PoolSize=50
DNS=192.168.5.1