1
0
mirror of https://github.com/systemd/systemd synced 2026-04-22 23:15:20 +02:00

Compare commits

...

24 Commits

Author SHA1 Message Date
Luca Boccassi
1bd29614ff
Merge pull request #22631 from yuwata/network-redesign-request-queue
network: re-design request queue
2022-03-11 10:48:45 +00:00
Lennart Poettering
15e152acd1
Merge pull request #22618 from yuwata/network-safe-string
network: dhcp-server: refuse unsafe filename
2022-03-11 11:33:07 +01:00
Marcel Hellwig
37035235df fix signature of sd_journal_print_with_location in docs 2022-03-11 11:32:20 +01:00
Clyde Byrd III
1015da0930 gitignore: ignore mkosi.installdir 2022-03-11 09:34:04 +00:00
Yu Watanabe
09d09207de network: re-design request queue
This makes Request object takes hash, compare, free, and process functions.

With this change, the logic in networkd-queue.c can be mostly
independent of the type of the request or the object (e.g. Address) assigned
to the request, and it becomes simpler.
2022-03-11 14:20:31 +09:00
Yu Watanabe
4c8b81caa5 network: increment reference counters of Link and Request before processing requests
To prevent the request or link is freed while processing requests.
2022-03-11 14:20:31 +09:00
Yu Watanabe
eb93dc9bde network: merge RequestType and SetLinkOperation
These two enum indicate how we process the request. Hence, it is not
necessary to introduce two separated indicators.
2022-03-11 14:20:31 +09:00
Yu Watanabe
a48ffe47cf network: refuse to configure link properties when in initialized state
The condition should be satisfied only when users request to reconfigure
the link, and in that case, all request will be cancelled. Hence, it is
not necessary to process the request.
2022-03-11 14:20:31 +09:00
Yu Watanabe
e519286407 network: drop unnecessary link_enter_failed()
As returning negative errno makes the link will enter the failed state.
2022-03-11 14:20:31 +09:00
Yu Watanabe
80d62d4f1a network: introduce request_call_netlink_async()
In most netlink handlers, we do the following,
1. decrease the message counter,
2. check the link state,
3. error handling,
4. update link state via e.g. link_check_ready().

The first two steps are mostly common, hence let's extract it.

Moreover, this is not only extracting the common logic, but provide a
strong advantage; `request_call_netlink_async()` assigns the relevant
Request object to the userdata of the netlink slot, and the request object
has full information about the message we sent. Hence, in the future,
netlink handler can print more detailed error message. E.g. when
an address is failed to configure, then currently we only show an
address is failed to configure, but with this commit, potentially we can
show which address is failed explicitly.

This does not change such error handling yet. But let's do that later.
2022-03-11 14:20:31 +09:00
Yu Watanabe
e26d3d407c network: make Request object take Manager*
Previously, even though all Request object are owned by Manager, they
do not have direct reference to Manager, but through Link or NetDev
object. But, as Link or NetDev can be NULL, we need to conditionalize
how to access Manager from Request with the type of the request.
This makes the way simpler, as now Request object has direct reference
to Manager.

This also rename request_drop() -> request_detach(), as in the previous
commit, the reference counter is introduced, so even if a reference of
a Request object from Manager is dropped, the object may still alive.
The naming `request_drop()` sounds the object will freed by the
function. But it may not. And `request_detach()` suggests the object
will not be managed by Manager any more, and I think it is more
appropreate.

This is just a cleanup, and should not change any behavior.
2022-03-11 14:20:31 +09:00
Yu Watanabe
e9ef9a1484 network: introduce reference counter for Request object
Currently, all Request object are always owned by Manager, and freed
when it is processed, especially, soon after a netlink message is sent.
So, it is not necessary to introduce the reference counter.

In a later commit, the Request object will _not_ be freed at the time
when a netlink message is sent, but assigned to the relevant netlink
slot as a userdata, and will be freed when a reply is received. So, the
owner of the Request object is changed in its lifetime. In that case, it
is convenient that the object has reference counter to avoid memleak or
double free.
2022-03-11 14:20:31 +09:00
Yu Watanabe
ff51134c93 network: make request_process_address() and friends take Link and corresponding object
This also renames e.g. request_process_address() -> address_process_request().

Also, this drops type checks such as `assert(req->type == REQUEST_TYPE_ADDRESS)`,
as in the later commits, the function of processing request, e.g.
`address_process_request()`, will be assigned to the Request object when
it is created. And the request type will be used to distinguish and to
avoid deduplicating requests which do not have any assigned objects,
like REQUEST_TYPE_DHCP4_CLIENT. Hence, the type checks in process functions
are mostly not necessary and redundant.

This is mostly cleanups and preparation for later commits, and should
not change any behavior.
2022-03-11 14:16:41 +09:00
Yu Watanabe
54ff39f7ae network: make address_configure() and friends take Request object
This should not change any behavior.
Just a preparation for a later commit which introduces
request_call_netlink_async().
2022-03-11 10:40:59 +09:00
Yu Watanabe
f1eef3675c network: tc: assign netlink handlers into Request object
This should not change any behavior, as req->netlink_handler is always
qdisc_handler or tclass_handler.

This is just a preparation for a later commit which introduces
request_call_netlink_async().
2022-03-11 10:39:05 +09:00
Yu Watanabe
5b25bdd1a3 alloc-util: introduce mfree_func_type_t 2022-03-11 10:24:08 +09:00
Yu Watanabe
6278e42878 network: dhcp: rename NextServer= and Filename= settings
And make the settings configures DHCP option 66 and 67.

Follow-ups for #22615.
Fixes #22661.
2022-03-11 10:14:57 +09:00
Yu Watanabe
71a9e3a304 dhcp: list all known message type 2022-03-10 14:47:28 +09:00
Yu Watanabe
3d80c57b7e sd-dhcp6-client: rename timezone options
To make them follow corresponding DHCPv4 options.
2022-03-10 14:47:28 +09:00
Yu Watanabe
3cb62efef8 dhcp: list all known DHCP options 2022-03-10 14:47:28 +09:00
Yu Watanabe
fa787a13e2 conf-parser: introduce config_parse_dns_name() and config_parse_hostname()
This makes nspawn refuse hostnames which are invalid DNS domain names.
2022-03-10 14:47:19 +09:00
Yu Watanabe
1aaab93621 network: refuse string which contains non-safe or non-ascii characters for Filename=
The string will be used when the client load additional config file to
boot, and it must be a valid path or url. Hence, let's refuse non-safe or
non-characters.
2022-03-10 14:43:48 +09:00
Yu Watanabe
e289ce7f67 conf-parser: introduce CONFIG_PARSE_STRING_ASCII flag
When the flag is set, the string which contains non-ascii characters
will be refused.
2022-03-10 14:43:48 +09:00
Yu Watanabe
3f87eaa5d8 conf-parser: merge config_parse_string() and config_parse_safe_string()
This also makes unsafe strings escaped when logged. Otherwise,
journalctl may not show the log message unless '--all' is specified.
2022-03-10 14:43:43 +09:00
69 changed files with 1297 additions and 1580 deletions

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ __pycache__/
/mkosi.builddir/
/mkosi.output/
/mkosi.default
/mkosi.installdir/
# Ignore any mkosi config files with "local" in the name
/mkosi.default.d/**/*local*.conf
/tags

View File

@ -68,10 +68,10 @@
<funcprototype>
<funcdef>int <function>sd_journal_print_with_location</function></funcdef>
<paramdef>int <parameter>priority</parameter></paramdef>
<paramdef>const char *<parameter>file</parameter></paramdef>
<paramdef>const char *<parameter>line</parameter></paramdef>
<paramdef>const char *<parameter>func</parameter></paramdef>
<paramdef>int <parameter>priority</parameter></paramdef>
<paramdef>const char *<parameter>format</parameter></paramdef>
<paramdef></paramdef>
</funcprototype>

View File

@ -2626,19 +2626,38 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
</varlistentry>
<varlistentry>
<term><varname>NextServer=</varname></term>
<term><varname>BootServerAddress=</varname></term>
<listitem>
<para>Takes an IPv4 address. Configures the next server used by e.g. PXE boot systems.
<para>Takes an IPv4 address of the boot server used by e.g. PXE boot systems. When specified,
the address is set to the <literal>siaddr</literal> field of the DHCP message header. See
<ulink url="https://www.rfc-editor.org/rfc/rfc2131.html">RFC 2131</ulink> for more details.
Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Filename=</varname></term>
<term><varname>BootServerName=</varname></term>
<listitem>
<para>Takes a path or url to a file loaded by e.g. a PXE boot loader. Defaults to unset.</para>
<para>Takes a name of the boot server used by e.g. PXE boot systems. When specified, the
server name is set to the DHCP option 66. See
<ulink url="https://www.rfc-editor.org/rfc/rfc2132.html">RFC 2132</ulink> for more details.
Defaults to unset.</para>
<para>Note that typically one of
<varname>BootServerName=</varname>/<varname>BootServerAddress=</varname> is sufficient to be
set, but both can be set too, if desired.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>BootFilename=</varname></term>
<listitem>
<para>Takes a path or URL to a file loaded by e.g. a PXE boot loader. The specified path is
set to the DHCP option 67. See
<ulink url="https://www.rfc-editor.org/rfc/rfc2132.html">RFC 2132</ulink> for more details.
Defaults to unset.</para>
</listitem>
</varlistentry>

View File

@ -13,6 +13,7 @@
#endif
typedef void (*free_func_t)(void *p);
typedef void* (*mfree_func_t)(void *p);
/* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than
* proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */

View File

@ -6173,7 +6173,6 @@ void unit_dump_config_items(FILE *f) {
{ config_parse_si_uint64, "SIZE" },
{ config_parse_bool, "BOOLEAN" },
{ config_parse_string, "STRING" },
{ config_parse_safe_string, "STRING" },
{ config_parse_path, "PATH" },
{ config_parse_unit_path_printf, "PATH" },
{ config_parse_colon_separated_paths, "PATH" },

View File

@ -611,7 +611,7 @@ static int parse_config_file(void) {
{ "Manager", "ShutdownWatchdogSec", config_parse_watchdog_sec, 0, &arg_reboot_watchdog }, /* obsolete alias */
{ "Manager", "KExecWatchdogSec", config_parse_watchdog_sec, 0, &arg_kexec_watchdog },
{ "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device },
{ "Manager", "RuntimeWatchdogPreGovernor", config_parse_safe_string, 0, &arg_watchdog_pretimeout_governor },
{ "Manager", "RuntimeWatchdogPreGovernor", config_parse_string, CONFIG_PARSE_STRING_SAFE, &arg_watchdog_pretimeout_governor },
{ "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set },
{ "Manager", "NoNewPrivileges", config_parse_bool, 0, &arg_no_new_privs },
#if HAVE_SECCOMP

View File

@ -569,7 +569,7 @@ finalize:
static int parse_config(void) {
const ConfigTableItem items[] = {
{ "Upload", "URL", config_parse_safe_string, 0, &arg_url },
{ "Upload", "URL", config_parse_string, CONFIG_PARSE_STRING_SAFE, &arg_url },
{ "Upload", "ServerKeyFile", config_parse_path_or_ignore, 0, &arg_key },
{ "Upload", "ServerCertificateFile", config_parse_path_or_ignore, 0, &arg_cert },
{ "Upload", "TrustedCertificateFile", config_parse_path_or_ignore, 0, &arg_trust },

View File

@ -73,15 +73,24 @@ enum {
};
enum {
DHCP_DISCOVER = 1,
DHCP_OFFER = 2,
DHCP_REQUEST = 3,
DHCP_DECLINE = 4,
DHCP_ACK = 5,
DHCP_NAK = 6,
DHCP_RELEASE = 7,
DHCP_INFORM = 8,
DHCP_FORCERENEW = 9,
DHCP_DISCOVER = 1, /* [RFC2132] */
DHCP_OFFER = 2, /* [RFC2132] */
DHCP_REQUEST = 3, /* [RFC2132] */
DHCP_DECLINE = 4, /* [RFC2132] */
DHCP_ACK = 5, /* [RFC2132] */
DHCP_NAK = 6, /* [RFC2132] */
DHCP_RELEASE = 7, /* [RFC2132] */
DHCP_INFORM = 8, /* [RFC2132] */
DHCP_FORCERENEW = 9, /* [RFC3203] */
DHCPLEASEQUERY = 10, /* [RFC4388] */
DHCPLEASEUNASSIGNED = 11, /* [RFC4388] */
DHCPLEASEUNKNOWN = 12, /* [RFC4388] */
DHCPLEASEACTIVE = 13, /* [RFC4388] */
DHCPBULKLEASEQUERY = 14, /* [RFC6926] */
DHCPLEASEQUERYDONE = 15, /* [RFC6926] */
DHCPACTIVELEASEQUERY = 16, /* [RFC7724] */
DHCPLEASEQUERYSTATUS = 17, /* [RFC7724] */
DHCPTLS = 18, /* [RFC7724] */
};
enum {

View File

@ -65,8 +65,9 @@ struct sd_dhcp_server {
char *timezone;
DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
struct in_addr next_server;
char *filename;
struct in_addr boot_server_address;
char *boot_server_name;
char *boot_filename;
OrderedSet *extra_options;
OrderedSet *vendor_options;

View File

@ -72,8 +72,8 @@ bool dhcp6_option_can_request(uint16_t option) {
return false;
case SD_DHCP6_OPTION_CLIENT_FQDN:
case SD_DHCP6_OPTION_PANA_AGENT:
case SD_DHCP6_OPTION_NEW_POSIX_TIMEZONE:
case SD_DHCP6_OPTION_NEW_TZDB_TIMEZONE:
case SD_DHCP6_OPTION_POSIX_TIMEZONE:
case SD_DHCP6_OPTION_TZDB_TIMEZONE:
return true;
case SD_DHCP6_OPTION_ERO:
case SD_DHCP6_OPTION_LQ_QUERY:

View File

@ -145,11 +145,11 @@ static const uint8_t default_req_opts_anonymize[] = {
SD_DHCP_OPTION_ROUTER, /* 3 */
SD_DHCP_OPTION_DOMAIN_NAME_SERVER, /* 6 */
SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */
SD_DHCP_OPTION_ROUTER_DISCOVER, /* 31 */
SD_DHCP_OPTION_ROUTER_DISCOVERY, /* 31 */
SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */
SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */
SD_DHCP_OPTION_NETBIOS_NAMESERVER, /* 44 */
SD_DHCP_OPTION_NETBIOS_NODETYPE, /* 46 */
SD_DHCP_OPTION_NETBIOS_NAME_SERVER, /* 44 */
SD_DHCP_OPTION_NETBIOS_NODE_TYPE, /* 46 */
SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, /* 121 */
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, /* 249 */

View File

@ -709,7 +709,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse static routes, ignoring: %m");
break;
case SD_DHCP_OPTION_INTERFACE_MTU:
case SD_DHCP_OPTION_MTU_INTERFACE:
r = lease_parse_u16(option, len, &lease->mtu, 68);
if (r < 0)
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
@ -729,7 +729,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break;
case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
case SD_DHCP_OPTION_DOMAIN_SEARCH:
r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
if (r < 0)
log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m");
@ -750,13 +750,13 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse root path, ignoring: %m");
break;
case SD_DHCP_OPTION_RENEWAL_T1_TIME:
case SD_DHCP_OPTION_RENEWAL_TIME:
r = lease_parse_u32(option, len, &lease->t1, 1);
if (r < 0)
log_debug_errno(r, "Failed to parse T1 time, ignoring: %m");
break;
case SD_DHCP_OPTION_REBINDING_T2_TIME:
case SD_DHCP_OPTION_REBINDING_TIME:
r = lease_parse_u32(option, len, &lease->t2, 1);
if (r < 0)
log_debug_errno(r, "Failed to parse T2 time, ignoring: %m");
@ -768,7 +768,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse classless routes, ignoring: %m");
break;
case SD_DHCP_OPTION_NEW_TZDB_TIMEZONE: {
case SD_DHCP_OPTION_TZDB_TIMEZONE: {
_cleanup_free_ char *tz = NULL;
r = lease_parse_string(option, len, &tz);

View File

@ -12,6 +12,7 @@
#include "alloc-util.h"
#include "dhcp-internal.h"
#include "dhcp-server-internal.h"
#include "dns-domain.h"
#include "fd-util.h"
#include "in-addr-util.h"
#include "io-util.h"
@ -163,7 +164,8 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
sd_event_unref(server->event);
free(server->filename);
free(server->boot_server_name);
free(server->boot_filename);
free(server->timezone);
for (sd_dhcp_lease_server_type_t i = 0; i < _SD_DHCP_LEASE_SERVER_TYPE_MAX; i++)
@ -272,24 +274,40 @@ sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
return server->event;
}
int sd_dhcp_server_set_next_server(sd_dhcp_server *server, const struct in_addr *next_server) {
int sd_dhcp_server_set_boot_server_address(sd_dhcp_server *server, const struct in_addr *address) {
assert_return(server, -EINVAL);
if (next_server)
server->next_server = *next_server;
if (address)
server->boot_server_address = *address;
else
server->next_server = (struct in_addr) {};
server->boot_server_address = (struct in_addr) {};
return 0;
}
int sd_dhcp_server_set_filename(sd_dhcp_server *server, const char *filename) {
int sd_dhcp_server_set_boot_server_name(sd_dhcp_server *server, const char *name) {
int r;
assert_return(server, -EINVAL);
if (filename && !ascii_is_valid(filename))
if (name) {
r = dns_name_is_valid(name);
if (r < 0)
return r;
if (r == 0)
return -EINVAL;
}
return free_and_strdup(&server->boot_server_name, name);
}
int sd_dhcp_server_set_boot_filename(sd_dhcp_server *server, const char *filename) {
assert_return(server, -EINVAL);
if (filename && (!string_is_safe(filename) || !ascii_is_valid(filename)))
return -EINVAL;
return free_and_strdup(&server->filename, filename);
return free_and_strdup(&server->boot_filename, filename);
}
int sd_dhcp_server_stop(sd_dhcp_server *server) {
@ -561,7 +579,7 @@ static int server_send_offer_or_ack(
return r;
packet->dhcp.yiaddr = address;
packet->dhcp.siaddr = server->next_server.s_addr;
packet->dhcp.siaddr = server->boot_server_address.s_addr;
lease_time = htobe32(req->lifetime);
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
@ -585,18 +603,18 @@ static int server_send_offer_or_ack(
return r;
}
if (server->filename) {
/* The pxelinux magic option is marked as deprecated, but let's append it for older
* implementations. */
if (server->boot_server_name) {
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_PXELINUX_MAGIC, 4,
(const uint8_t[]) { 0xf1, 0x00, 0x74, 0x7e });
SD_DHCP_OPTION_BOOT_SERVER_NAME,
strlen(server->boot_server_name), server->boot_server_name);
if (r < 0)
return r;
}
if (server->boot_filename) {
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_CONFIGURATION_FILE,
strlen(server->filename), server->filename);
SD_DHCP_OPTION_BOOT_FILENAME,
strlen(server->boot_filename), server->boot_filename);
if (r < 0)
return r;
}
@ -628,7 +646,7 @@ static int server_send_offer_or_ack(
if (server->timezone) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE,
SD_DHCP_OPTION_TZDB_TIMEZONE,
strlen(server->timezone), server->timezone);
if (r < 0)
return r;

View File

@ -109,7 +109,7 @@ static void test_request_anonymize(sd_event *e) {
r = sd_dhcp_client_attach_event(client, e, 0);
assert_se(r >= 0);
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_NETBIOS_NAMESERVER) == 0);
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_NETBIOS_NAME_SERVER) == 0);
/* This PRL option is not set when using Anonymize */
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_HOST_NAME) == 1);
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST) == -EINVAL);

View File

@ -179,14 +179,14 @@ Tun.OneQueue, config_parse_warn_compat,
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tun.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
Tun.User, config_parse_safe_string, 0, offsetof(TunTap, user_name)
Tun.Group, config_parse_safe_string, 0, offsetof(TunTap, group_name)
Tun.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name)
Tun.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name)
Tap.OneQueue, config_parse_warn_compat, DISABLED_LEGACY, 0
Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Tap.VNetHeader, config_parse_bool, 0, offsetof(TunTap, vnet_hdr)
Tap.User, config_parse_safe_string, 0, offsetof(TunTap, user_name)
Tap.Group, config_parse_safe_string, 0, offsetof(TunTap, group_name)
Tap.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, user_name)
Tap.Group, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(TunTap, group_name)
Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
Bond.TransmitHashPolicy, config_parse_bond_xmit_hash_policy, 0, offsetof(Bond, xmit_hash_policy)
Bond.LACPTransmitRate, config_parse_bond_lacp_rate, 0, offsetof(Bond, lacp_rate)

View File

@ -578,14 +578,14 @@ static int independent_netdev_create(NetDev *netdev) {
return 0;
}
static int stacked_netdev_create(NetDev *netdev, Link *link, link_netlink_message_handler_t callback) {
static int stacked_netdev_create(NetDev *netdev, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
assert(netdev);
assert(netdev->manager);
assert(link);
assert(callback);
assert(req);
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
if (r < 0)
@ -595,13 +595,10 @@ static int stacked_netdev_create(NetDev *netdev, Link *link, link_netlink_messag
if (r < 0)
return r;
r = netlink_call_async(netdev->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
r = request_call_netlink_async(netdev->manager->rtnl, m, req);
if (r < 0)
return r;
link_ref(link);
netdev->state = NETDEV_STATE_CREATING;
log_netdev_debug(netdev, "Creating");
return 0;
@ -632,40 +629,29 @@ static int netdev_is_ready_to_create(NetDev *netdev, Link *link) {
return true;
}
int request_process_stacked_netdev(Request *req) {
NetDev *netdev;
Link *link;
static int stacked_netdev_process_request(Request *req, Link *link, void *userdata) {
NetDev *netdev = ASSERT_PTR(userdata);
int r;
assert(req);
assert(req->type == REQUEST_TYPE_NETDEV_STACKED);
assert(req->netlink_handler);
netdev = ASSERT_PTR(req->netdev);
link = ASSERT_PTR(req->link);
assert(link);
r = netdev_is_ready_to_create(netdev, link);
if (r <= 0)
return r;
r = stacked_netdev_create(netdev, link, req->netlink_handler);
r = stacked_netdev_create(netdev, link, req);
if (r < 0)
return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
return 1;
}
static int link_create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
int r;
assert(m);
assert(link);
assert(link->create_stacked_netdev_messages > 0);
link->create_stacked_netdev_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -696,10 +682,12 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) {
return 0; /* Already created. */
link->stacked_netdevs_created = false;
r = link_queue_request(link, REQUEST_TYPE_NETDEV_STACKED, netdev_ref(netdev), true,
r = link_queue_request_full(link, REQUEST_TYPE_NETDEV_STACKED,
netdev_ref(netdev), (mfree_func_t) netdev_unref,
trivial_hash_func, trivial_compare_func,
stacked_netdev_process_request,
&link->create_stacked_netdev_messages,
link_create_stacked_netdev_handler,
NULL);
create_stacked_netdev_handler, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Failed to request stacked netdev '%s': %m",
netdev->ifname);
@ -708,14 +696,11 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) {
return 0;
}
int request_process_independent_netdev(Request *req) {
NetDev *netdev;
static int independent_netdev_process_request(Request *req, Link *link, void *userdata) {
NetDev *netdev = ASSERT_PTR(userdata);
int r;
assert(req);
assert(req->type == REQUEST_TYPE_NETDEV_INDEPENDENT);
netdev = ASSERT_PTR(req->netdev);
assert(!link);
r = netdev_is_ready_to_create(netdev, NULL);
if (r <= 0)
@ -747,9 +732,9 @@ static int netdev_request_to_create(NetDev *netdev) {
} else {
/* Otherwise, wait for the dependencies being resolved. */
r = netdev_queue_request(netdev, NULL);
r = netdev_queue_request(netdev, independent_netdev_process_request, NULL);
if (r < 0)
return log_netdev_warning_errno(netdev, r, "Failed to request to create: %m");
return log_netdev_warning_errno(netdev, r, "Failed to request to create netdev: %m");
}
return 0;

View File

@ -109,7 +109,6 @@ typedef enum NetDevCreateType {
typedef struct Manager Manager;
typedef struct Condition Condition;
typedef struct Request Request;
typedef struct NetDev {
Manager *manager;
@ -209,8 +208,6 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
int netdev_generate_hw_addr(NetDev *netdev, Link *link, const char *name,
const struct hw_addr_data *hw_addr, struct hw_addr_data *ret);
int request_process_independent_netdev(Request *req);
int request_process_stacked_netdev(Request *req);
int link_request_stacked_netdev(Link *link, NetDev *netdev);
const char *netdev_kind_to_string(NetDevKind d) _const_;

View File

@ -65,19 +65,17 @@ static int address_label_new_static(Network *network, const char *filename, unsi
return 0;
}
static int address_label_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int address_label_configure_handler(
sd_netlink *rtnl,
sd_netlink_message *m,
Request *req,
Link *link,
void *userdata) {
int r;
assert(rtnl);
assert(m);
assert(link);
assert(link->ifname);
assert(link->static_address_label_messages > 0);
link->static_address_label_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -95,7 +93,7 @@ static int address_label_configure_handler(sd_netlink *rtnl, sd_netlink_message
return 1;
}
static int address_label_configure(AddressLabel *label, Link *link, link_netlink_message_handler_t callback) {
static int address_label_configure(AddressLabel *label, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -104,7 +102,7 @@ static int address_label_configure(AddressLabel *label, Link *link, link_netlink
assert(link->ifindex > 0);
assert(link->manager);
assert(link->manager->rtnl);
assert(callback);
assert(req);
r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &m, RTM_NEWADDRLABEL,
link->ifindex, AF_INET6);
@ -123,29 +121,20 @@ static int address_label_configure(AddressLabel *label, Link *link, link_netlink
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
int request_process_address_label(Request *req) {
Link *link;
static int address_label_process_request(Request *req, Link *link, void *userdata) {
AddressLabel *label = ASSERT_PTR(userdata);
int r;
assert(req);
assert(req->label);
assert(req->type == REQUEST_TYPE_ADDRESS_LABEL);
link = ASSERT_PTR(req->link);
assert(link);
if (!link_is_ready_to_configure(link, false))
return 0;
r = address_label_configure(req->label, link, req->netlink_handler);
r = address_label_configure(label, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure address label: %m");
@ -162,8 +151,11 @@ int link_request_static_address_labels(Link *link) {
link->static_address_labels_configured = false;
HASHMAP_FOREACH(label, link->network->address_labels_by_section) {
r = link_queue_request(link, REQUEST_TYPE_ADDRESS_LABEL, label, false,
&link->static_address_label_messages, address_label_configure_handler, NULL);
r = link_queue_request_full(link, REQUEST_TYPE_ADDRESS_LABEL,
label, NULL, trivial_hash_func, trivial_compare_func,
address_label_process_request,
&link->static_address_label_messages,
address_label_configure_handler, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request address label: %m");
}

View File

@ -9,7 +9,6 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef struct AddressLabel {
Network *network;
@ -26,7 +25,6 @@ AddressLabel *address_label_free(AddressLabel *label);
void network_drop_invalid_address_labels(Network *network);
int link_request_static_address_labels(Link *link);
int request_process_address_label(Request *req);
CONFIG_PARSER_PROTOTYPE(config_parse_address_label);
CONFIG_PARSER_PROTOTYPE(config_parse_address_label_prefix);

View File

@ -316,7 +316,7 @@ DEFINE_PRIVATE_HASH_OPS(
address_kernel_hash_func,
address_kernel_compare_func);
void address_hash_func(const Address *a, struct siphash *state) {
static void address_hash_func(const Address *a, struct siphash *state) {
assert(a);
siphash24_compress(&a->family, sizeof(a->family), state);
@ -1023,9 +1023,6 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
assert(link);
assert(error_msg);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_warning_errno(link, m, r, error_msg);
@ -1036,11 +1033,7 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
return 1;
}
static int address_configure(
const Address *address,
Link *link,
link_netlink_message_handler_t callback) {
static int address_configure(const Address *address, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -1050,7 +1043,7 @@ static int address_configure(
assert(link->ifindex > 0);
assert(link->manager);
assert(link->manager->rtnl);
assert(callback);
assert(req);
log_address_debug(address, "Configuring", link);
@ -1091,12 +1084,7 @@ static int address_configure(
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback, link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool address_is_ready_to_configure(Link *link, const Address *address) {
@ -1116,21 +1104,17 @@ static bool address_is_ready_to_configure(Link *link, const Address *address) {
return true;
}
int request_process_address(Request *req) {
Address *address;
Link *link;
static int address_process_request(Request *req, Link *link, Address *address) {
int r;
assert(req);
assert(req->type == REQUEST_TYPE_ADDRESS);
address = ASSERT_PTR(req->address);
link = ASSERT_PTR(req->link);
assert(link);
assert(address);
if (!address_is_ready_to_configure(link, address))
return 0;
r = address_configure(address, link, req->netlink_handler);
r = address_configure(address, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure address: %m");
@ -1143,7 +1127,7 @@ int link_request_address(
Address *address,
bool consume_object,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
address_netlink_handler_t netlink_handler,
Request **ret) {
Address *acquired, *existing;
@ -1212,7 +1196,11 @@ int link_request_address(
return r;
log_address_debug(existing, "Requesting", link);
r = link_queue_request(link, REQUEST_TYPE_ADDRESS, existing, false,
r = link_queue_request_safe(link, REQUEST_TYPE_ADDRESS,
existing, NULL,
address_hash_func,
address_compare_func,
address_process_request,
message_counter, netlink_handler, ret);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request address: %m");
@ -1224,13 +1212,10 @@ int link_request_address(
return 1;
}
static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
int r;
assert(link);
assert(link->static_address_messages > 0);
link->static_address_messages--;
r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address");
if (r <= 0)
@ -1300,10 +1285,12 @@ void address_cancel_request(Address *address) {
req = (Request) {
.link = address->link,
.type = REQUEST_TYPE_ADDRESS,
.address = address,
.userdata = address,
.hash_func = (hash_func_t) address_hash_func,
.compare_func = (compare_func_t) address_compare_func,
};
request_drop(ordered_set_get(address->link->manager->request_queue, &req));
request_detach(address->link->manager, &req);
address_cancel_requesting(address);
}

View File

@ -18,6 +18,12 @@ typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef int (*address_ready_callback_t)(Address *address);
typedef int (*address_netlink_handler_t)(
sd_netlink *rtnl,
sd_netlink_message *m,
Request *req,
Link *link,
Address *address);
struct Address {
Link *link;
@ -97,17 +103,15 @@ int link_request_address(
Address *address,
bool consume_object,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
address_netlink_handler_t netlink_handler,
Request **ret);
int link_request_static_address(Link *link, Address *address, bool consume);
int link_request_static_addresses(Link *link);
int request_process_address(Request *req);
int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
int network_drop_invalid_addresses(Network *network);
void address_hash_func(const Address *a, struct siphash *state);
int address_compare_func(const Address *a1, const Address *a2);
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Address, address);

View File

@ -93,16 +93,11 @@ static int bridge_fdb_new_static(
return 0;
}
static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
int r;
assert(m);
assert(link);
assert(link->static_bridge_fdb_messages > 0);
link->static_bridge_fdb_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -168,14 +163,14 @@ static int bridge_fdb_configure_message(const BridgeFDB *fdb, Link *link, sd_net
return 0;
}
static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, link_netlink_message_handler_t callback) {
static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
assert(fdb);
assert(link);
assert(link->manager);
assert(callback);
assert(req);
r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_NEWNEIGH, link->ifindex, AF_BRIDGE);
if (r < 0)
@ -185,13 +180,7 @@ static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, link_netlink_message
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) {
@ -219,20 +208,17 @@ static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) {
return true;
}
int request_process_bridge_fdb(Request *req) {
BridgeFDB *fdb;
Link *link;
static int bridge_fdb_process_request(Request *req, Link *link, void *userdata) {
BridgeFDB *fdb = ASSERT_PTR(userdata);
int r;
assert(req);
assert(req->type == REQUEST_TYPE_BRIDGE_FDB);
assert_se(link = req->link);
assert_se(fdb = req->fdb);
assert(link);
if (!bridge_fdb_is_ready_to_configure(fdb, link))
return 0;
r = bridge_fdb_configure(fdb, link, req->netlink_handler);
r = bridge_fdb_configure(fdb, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure bridge FDB: %m");
@ -249,8 +235,14 @@ int link_request_static_bridge_fdb(Link *link) {
link->static_bridge_fdb_configured = false;
HASHMAP_FOREACH(fdb, link->network->bridge_fdb_entries_by_section) {
r = link_queue_request(link, REQUEST_TYPE_BRIDGE_FDB, fdb, false,
&link->static_bridge_fdb_messages, bridge_fdb_configure_handler, NULL);
r = link_queue_request_full(link, REQUEST_TYPE_BRIDGE_FDB,
fdb, NULL,
trivial_hash_func,
trivial_compare_func,
bridge_fdb_process_request,
&link->static_bridge_fdb_messages,
bridge_fdb_configure_handler,
NULL);
if (r < 0)
return log_link_error_errno(link, r, "Failed to request static bridge FDB entry: %m");
}

View File

@ -14,7 +14,6 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef enum NeighborCacheEntryFlags {
NEIGHBOR_CACHE_ENTRY_FLAGS_USE = NTF_USE,
@ -47,8 +46,6 @@ void network_drop_invalid_bridge_fdb_entries(Network *network);
int link_request_static_bridge_fdb(Link *link);
int request_process_bridge_fdb(Request *req);
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr);
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id);
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_destination);

View File

@ -81,16 +81,11 @@ static int bridge_mdb_new_static(
return 0;
}
static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
int r;
assert(m);
assert(link);
assert(link->static_bridge_mdb_messages > 0);
link->static_bridge_mdb_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r == -EINVAL && streq_ptr(link->kind, "bridge") && link->master_ifindex <= 0) {
@ -114,7 +109,7 @@ static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m,
}
/* send a request to the kernel to add an MDB entry */
static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message_handler_t callback) {
static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
struct br_mdb_entry entry;
int r;
@ -122,7 +117,7 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message
assert(mdb);
assert(link);
assert(link->manager);
assert(callback);
assert(req);
if (DEBUG_LOGGING) {
_cleanup_free_ char *a = NULL;
@ -164,13 +159,7 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool bridge_mdb_is_ready_to_configure(Link *link) {
@ -205,19 +194,17 @@ static bool bridge_mdb_is_ready_to_configure(Link *link) {
return true;
}
int request_process_bridge_mdb(Request *req) {
Link *link;
static int bridge_mdb_process_request(Request *req, Link *link, void *userdata) {
BridgeMDB *mdb = ASSERT_PTR(userdata);
int r;
assert(req);
assert(req->mdb);
assert(req->type == REQUEST_TYPE_BRIDGE_MDB);
assert_se(link = req->link);
assert(link);
if (!bridge_mdb_is_ready_to_configure(link))
return 0;
r = bridge_mdb_configure(req->mdb, link, req->netlink_handler);
r = bridge_mdb_configure(mdb, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure bridge MDB: %m");
@ -240,8 +227,14 @@ int link_request_static_bridge_mdb(Link *link) {
goto finish;
HASHMAP_FOREACH(mdb, link->network->bridge_mdb_entries_by_section) {
r = link_queue_request(link, REQUEST_TYPE_BRIDGE_MDB, mdb, false,
&link->static_bridge_mdb_messages, bridge_mdb_configure_handler, NULL);
r = link_queue_request_full(link, REQUEST_TYPE_BRIDGE_MDB,
mdb, NULL,
trivial_hash_func,
trivial_compare_func,
bridge_mdb_process_request,
&link->static_bridge_mdb_messages,
bridge_mdb_configure_handler,
NULL);
if (r < 0)
return log_link_error_errno(link, r, "Failed to request MDB entry to multicast group database: %m");
}

View File

@ -9,7 +9,6 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef struct BridgeMDB {
Network *network;
@ -25,7 +24,6 @@ BridgeMDB *bridge_mdb_free(BridgeMDB *mdb);
void network_drop_invalid_bridge_mdb_entries(Network *network);
int link_request_static_bridge_mdb(Link *link);
int request_process_bridge_mdb(Request *req);
CONFIG_PARSER_PROTOTYPE(config_parse_mdb_group_address);
CONFIG_PARSER_PROTOTYPE(config_parse_mdb_vlan_id);

View File

@ -288,13 +288,10 @@ static int dhcp_pd_check_ready(Link *link) {
return 1;
}
static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
assert(link);
assert(link->dhcp_pd_messages > 0);
link->dhcp_pd_messages--;
r = route_configure_handler_internal(rtnl, m, link, "Failed to add prefix route for DHCP delegated subnet prefix");
if (r <= 0)
@ -344,13 +341,10 @@ static int dhcp_pd_request_route(Link *link, const struct in6_addr *prefix, usec
return 0;
}
static int dhcp_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
int r;
assert(link);
assert(link->dhcp_pd_messages > 0);
link->dhcp_pd_messages--;
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCP-PD address");
if (r <= 0)
@ -658,13 +652,10 @@ void dhcp4_pd_prefix_lost(Link *uplink) {
(void) link_remove(tunnel);
}
static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
assert(link);
assert(link->dhcp4_messages > 0);
link->dhcp4_messages--;
r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv4 delegated prefix");
if (r <= 0)
@ -677,13 +668,10 @@ static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message
return 1;
}
static int dhcp6_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp6_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
assert(link);
assert(link->dhcp6_messages > 0);
link->dhcp6_messages--;
r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv6 delegated prefix");
if (r <= 0)
@ -704,7 +692,7 @@ static int dhcp_request_unreachable_route(
NetworkConfigSource source,
const union in_addr_union *server_address,
unsigned *counter,
link_netlink_message_handler_t callback) {
route_netlink_handler_t callback) {
_cleanup_(route_freep) Route *route = NULL;
Route *existing;

View File

@ -416,13 +416,17 @@ static int dhcp4_server_configure(Link *link) {
return log_link_error_errno(link, r, "Failed to set default lease time for DHCPv4 server instance: %m");
}
r = sd_dhcp_server_set_next_server(link->dhcp_server, &link->network->dhcp_server_next_server);
r = sd_dhcp_server_set_boot_server_address(link->dhcp_server, &link->network->dhcp_server_boot_server_address);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set next server for DHCPv4 server instance: %m");
return log_link_warning_errno(link, r, "Failed to set boot server address for DHCPv4 server instance: %m");
r = sd_dhcp_server_set_filename(link->dhcp_server, link->network->dhcp_server_filename);
r = sd_dhcp_server_set_boot_server_name(link->dhcp_server, link->network->dhcp_server_boot_server_name);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set filename for DHCPv4 server instance: %m");
return log_link_warning_errno(link, r, "Failed to set boot server name for DHCPv4 server instance: %m");
r = sd_dhcp_server_set_boot_filename(link->dhcp_server, link->network->dhcp_server_boot_filename);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to set boot filename for DHCPv4 server instance: %m");
for (sd_dhcp_lease_server_type_t type = 0; type < _SD_DHCP_LEASE_SERVER_TYPE_MAX; type ++) {
@ -567,13 +571,10 @@ static bool dhcp_server_is_ready_to_configure(Link *link) {
return true;
}
int request_process_dhcp_server(Request *req) {
Link *link;
static int dhcp_server_process_request(Request *req, Link *link, void *userdata) {
int r;
assert(req);
assert(req->type == REQUEST_TYPE_DHCP_SERVER);
assert_se(link = req->link);
assert(link);
if (!dhcp_server_is_ready_to_configure(link))
return 0;
@ -597,7 +598,7 @@ int link_request_dhcp_server(Link *link) {
return 0;
log_link_debug(link, "Requesting DHCP server.");
r = link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, NULL, false, NULL, NULL, NULL);
r = link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, dhcp_server_process_request, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request configuration of DHCP server: %m");
@ -712,7 +713,7 @@ int config_parse_dhcp_server_address(
void *data,
void *userdata) {
Network *network = userdata;
Network *network = ASSERT_PTR(userdata);
union in_addr_union a;
unsigned char prefixlen;
int r;

View File

@ -5,13 +5,11 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
void network_adjust_dhcp_server(Network *network);
int link_request_dhcp_server_address(Link *link);
int link_request_dhcp_server(Link *link);
int request_process_dhcp_server(Request *req);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);

View File

@ -177,16 +177,11 @@ static int dhcp4_retry(Link *link) {
return dhcp4_request_address_and_routes(link, false);
}
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
assert(m);
assert(link);
assert(link->dhcp4_messages > 0);
link->dhcp4_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r == -ENETUNREACH && !link->dhcp4_route_retrying) {
@ -829,13 +824,10 @@ int dhcp4_lease_lost(Link *link) {
return link_request_static_routes(link, true);
}
static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
int r;
assert(link);
assert(link->dhcp4_messages > 0);
link->dhcp4_messages--;
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
if (r <= 0)
@ -1426,7 +1418,7 @@ static int dhcp4_configure(Link *link) {
if (!link->network->dhcp_anonymize) {
if (link->network->dhcp_use_mtu) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_INTERFACE_MTU);
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_MTU_INTERFACE);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for MTU: %m");
}
@ -1442,7 +1434,7 @@ static int dhcp4_configure(Link *link) {
}
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST);
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_DOMAIN_SEARCH);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for domain search list: %m");
}
@ -1460,7 +1452,7 @@ static int dhcp4_configure(Link *link) {
}
if (link->network->dhcp_use_timezone) {
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_TZDB_TIMEZONE);
if (r < 0)
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set request flag for timezone: %m");
}
@ -1597,15 +1589,10 @@ static int dhcp4_configure_duid(Link *link) {
return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
}
int request_process_dhcp4_client(Request *req) {
Link *link;
static int dhcp4_process_request(Request *req, Link *link, void *userdata) {
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_DHCP4_CLIENT);
link = req->link;
assert(link);
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0;
@ -1619,7 +1606,7 @@ int request_process_dhcp4_client(Request *req) {
if (r <= 0)
return r;
r = dhcp4_configure(req->link);
r = dhcp4_configure(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure DHCPv4 client: %m");
@ -1629,7 +1616,6 @@ int request_process_dhcp4_client(Request *req) {
log_link_debug(link, "DHCPv4 client is configured%s.",
r > 0 ? ", acquiring DHCPv4 lease" : "");
return 1;
}
@ -1644,7 +1630,7 @@ int link_request_dhcp4_client(Link *link) {
if (link->dhcp_client)
return 0;
r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, NULL, false, NULL, NULL, NULL);
r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, dhcp4_process_request, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv4 client: %m");

View File

@ -5,7 +5,6 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef enum DHCPClientIdentifier {
DHCP_CLIENT_ID_MAC,
@ -25,7 +24,6 @@ int dhcp4_start(Link *link);
int dhcp4_lease_lost(Link *link);
int dhcp4_check_ready(Link *link);
int request_process_dhcp4_client(Request *req);
int link_request_dhcp4_client(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);

View File

@ -136,13 +136,10 @@ int dhcp6_check_ready(Link *link) {
return 0;
}
static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
int r;
assert(link);
assert(link->dhcp6_messages > 0);
link->dhcp6_messages--;
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 address");
if (r <= 0)
@ -715,15 +712,10 @@ int dhcp6_update_mac(Link *link) {
return 0;
}
int request_process_dhcp6_client(Request *req) {
Link *link;
static int dhcp6_process_request(Request *req, Link *link, void *userdata) {
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_DHCP6_CLIENT);
link = req->link;
assert(link);
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0;
@ -751,7 +743,6 @@ int request_process_dhcp6_client(Request *req) {
log_link_debug(link, "DHCPv6 client is configured%s.",
r > 0 ? ", acquiring DHCPv6 lease" : "");
return 1;
}
@ -766,7 +757,7 @@ int link_request_dhcp6_client(Link *link) {
if (link->dhcp6_client)
return 0;
r = link_queue_request(link, REQUEST_TYPE_DHCP6_CLIENT, NULL, false, NULL, NULL, NULL);
r = link_queue_request(link, REQUEST_TYPE_DHCP6_CLIENT, dhcp6_process_request, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv6 client: %m");

View File

@ -13,7 +13,6 @@ typedef enum DHCP6ClientStartMode {
} DHCP6ClientStartMode;
typedef struct Link Link;
typedef struct Request Request;
bool link_dhcp6_with_address_enabled(Link *link);
int dhcp6_check_ready(Link *link);
@ -21,7 +20,6 @@ int dhcp6_update_mac(Link *link);
int dhcp6_start(Link *link);
int dhcp6_start_on_ra(Link *link, bool information_request);
int request_process_dhcp6_client(Request *req);
int link_request_dhcp6_client(Link *link);
int link_serialize_dhcp6_client(Link *link, FILE *f);

View File

@ -70,7 +70,7 @@ static int ipv4ll_address_lost(Link *link) {
return address_remove(existing);
}
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
int r;
assert(link);

View File

@ -26,13 +26,17 @@ void network_adjust_ipv6_proxy_ndp(Network *network) {
}
}
static int ipv6_proxy_ndp_address_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int ipv6_proxy_ndp_address_configure_handler(
sd_netlink *rtnl,
sd_netlink_message *m,
Request *req,
Link *link,
struct in6_addr *address) {
int r;
assert(m);
assert(link);
assert(link->static_ipv6_proxy_ndp_messages > 0);
link->static_ipv6_proxy_ndp_messages--;
r = sd_netlink_message_get_errno(m);
if (r < 0)
@ -48,11 +52,7 @@ static int ipv6_proxy_ndp_address_configure_handler(sd_netlink *rtnl, sd_netlink
}
/* send a request to the kernel to add an IPv6 Proxy entry to the neighbour table */
static int ipv6_proxy_ndp_address_configure(
const struct in6_addr *address,
Link *link,
link_netlink_message_handler_t callback) {
static int ipv6_proxy_ndp_address_configure(const struct in6_addr *address, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -60,7 +60,7 @@ static int ipv6_proxy_ndp_address_configure(
assert(link);
assert(link->manager);
assert(link->manager->rtnl);
assert(callback);
assert(req);
/* create new netlink message */
r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_NEWNEIGH, link->ifindex, AF_INET6);
@ -75,28 +75,20 @@ static int ipv6_proxy_ndp_address_configure(
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
int request_process_ipv6_proxy_ndp_address(Request *req) {
Link *link;
static int ipv6_proxy_ndp_address_process_request(Request *req, Link *link, struct in6_addr *address) {
int r;
assert(req);
assert(req->ipv6_proxy_ndp);
assert(req->type == REQUEST_TYPE_IPV6_PROXY_NDP);
assert_se(link = req->link);
assert(link);
assert(address);
if (!link_is_ready_to_configure(link, false))
return 0;
r = ipv6_proxy_ndp_address_configure(req->ipv6_proxy_ndp, link, req->netlink_handler);
r = ipv6_proxy_ndp_address_configure(address, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure IPv6 proxy NDP address: %m");
@ -113,9 +105,14 @@ int link_request_static_ipv6_proxy_ndp_addresses(Link *link) {
link->static_ipv6_proxy_ndp_configured = false;
SET_FOREACH(address, link->network->ipv6_proxy_ndp_addresses) {
r = link_queue_request(link, REQUEST_TYPE_IPV6_PROXY_NDP, address, false,
r = link_queue_request_safe(link, REQUEST_TYPE_IPV6_PROXY_NDP,
address, NULL,
in6_addr_hash_func,
in6_addr_compare_func,
ipv6_proxy_ndp_address_process_request,
&link->static_ipv6_proxy_ndp_messages,
ipv6_proxy_ndp_address_configure_handler, NULL);
ipv6_proxy_ndp_address_configure_handler,
NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request IPv6 proxy NDP address: %m");
}

View File

@ -5,11 +5,9 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
void network_adjust_ipv6_proxy_ndp(Network *network);
int link_request_static_ipv6_proxy_ndp_addresses(Link *link);
int request_process_ipv6_proxy_ndp_address(Request *req);
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_proxy_ndp_address);

View File

@ -906,7 +906,7 @@ static void link_drop_requests(Link *link) {
ORDERED_SET_FOREACH(req, link->manager->request_queue)
if (req->link == link)
request_drop(req);
request_detach(link->manager, req);
}
static Link *link_drop(Link *link) {

View File

@ -203,13 +203,10 @@ static int ndisc_check_ready(Link *link) {
return 0;
}
static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
assert(link);
assert(link->ndisc_messages > 0);
link->ndisc_messages--;
r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route");
if (r <= 0)
@ -254,13 +251,10 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
ndisc_route_handler, NULL);
}
static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
int r;
assert(link);
assert(link->ndisc_messages > 0);
link->ndisc_messages--;
r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address");
if (r <= 0)
@ -1122,14 +1116,10 @@ int ndisc_start(Link *link) {
return 1;
}
int request_process_ndisc(Request *req) {
Link *link;
static int ndisc_process_request(Request *req, Link *link, void *userdata) {
int r;
assert(req);
assert(req->type == REQUEST_TYPE_NDISC);
link = ASSERT_PTR(req->link);
assert(link);
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0;
@ -1148,7 +1138,6 @@ int request_process_ndisc(Request *req) {
log_link_debug(link, "IPv6 Router Discovery is configured%s.",
r > 0 ? " and started" : "");
return 1;
}
@ -1163,7 +1152,7 @@ int link_request_ndisc(Link *link) {
if (link->ndisc)
return 0;
r = link_queue_request(link, REQUEST_TYPE_NDISC, NULL, false, NULL, NULL, NULL);
r = link_queue_request(link, REQUEST_TYPE_NDISC, ndisc_process_request, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request configuring of the IPv6 Router Discovery: %m");

View File

@ -6,7 +6,6 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef enum IPv6AcceptRAStartDHCP6Client {
IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO,
@ -48,7 +47,6 @@ int ndisc_start(Link *link);
void ndisc_vacuum(Link *link);
void ndisc_flush(Link *link);
int request_process_ndisc(Request *req);
int link_request_ndisc(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_accept_ra_start_dhcp6_client);

View File

@ -87,7 +87,7 @@ static int neighbor_dup(const Neighbor *neighbor, Neighbor **ret) {
return 0;
}
void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
assert(neighbor);
siphash24_compress(&neighbor->family, sizeof(neighbor->family), state);
@ -106,7 +106,7 @@ void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
hw_addr_hash_func(&neighbor->ll_addr, state);
}
int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
static int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
int r;
r = CMP(a->family, b->family);
@ -193,11 +193,7 @@ static int neighbor_configure_message(Neighbor *neighbor, Link *link, sd_netlink
return 0;
}
static int neighbor_configure(
Neighbor *neighbor,
Link *link,
link_netlink_message_handler_t callback) {
static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -206,7 +202,7 @@ static int neighbor_configure(
assert(link->ifindex > 0);
assert(link->manager);
assert(link->manager->rtnl);
assert(callback);
assert(req);
log_neighbor_debug(neighbor, "Configuring", link);
@ -219,31 +215,20 @@ static int neighbor_configure(
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
int request_process_neighbor(Request *req) {
Neighbor *neighbor;
Link *link;
static int neighbor_process_request(Request *req, Link *link, Neighbor *neighbor) {
int r;
assert(req);
assert(req->type == REQUEST_TYPE_NEIGHBOR);
neighbor = ASSERT_PTR(req->neighbor);
link = ASSERT_PTR(req->link);
assert(link);
assert(neighbor);
if (!link_is_ready_to_configure(link, false))
return 0;
r = neighbor_configure(neighbor, link, req->netlink_handler);
r = neighbor_configure(neighbor, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure neighbor: %m");
@ -251,17 +236,11 @@ int request_process_neighbor(Request *req) {
return 1;
}
static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Neighbor *neighbor) {
int r;
assert(m);
assert(link);
assert(link->static_neighbor_messages > 0);
link->static_neighbor_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -279,13 +258,7 @@ static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_messag
return 1;
}
static int link_request_neighbor(
Link *link,
const Neighbor *neighbor,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
Request **ret) {
static int link_request_neighbor(Link *link, const Neighbor *neighbor) {
Neighbor *existing;
int r;
@ -309,8 +282,14 @@ static int link_request_neighbor(
existing->source = neighbor->source;
log_neighbor_debug(existing, "Requesting", link);
r = link_queue_request(link, REQUEST_TYPE_NEIGHBOR, existing, false,
message_counter, netlink_handler, ret);
r = link_queue_request_safe(link, REQUEST_TYPE_NEIGHBOR,
existing, NULL,
neighbor_hash_func,
neighbor_compare_func,
neighbor_process_request,
&link->static_neighbor_messages,
static_neighbor_configure_handler,
NULL);
if (r <= 0)
return r;
@ -329,8 +308,7 @@ int link_request_static_neighbors(Link *link) {
link->static_neighbors_configured = false;
HASHMAP_FOREACH(neighbor, link->network->neighbors_by_section) {
r = link_request_neighbor(link, neighbor, &link->static_neighbor_messages,
static_neighbor_configure_handler, NULL);
r = link_request_neighbor(link, neighbor);
if (r < 0)
return log_link_warning_errno(link, r, "Could not request neighbor: %m");
}

View File

@ -13,7 +13,6 @@
typedef struct Link Link;
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef struct Neighbor {
Network *network;
@ -29,9 +28,6 @@ typedef struct Neighbor {
Neighbor *neighbor_free(Neighbor *neighbor);
void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state);
int neighbor_compare_func(const Neighbor *a, const Neighbor *b);
void network_drop_invalid_neighbors(Network *network);
int link_drop_managed_neighbors(Link *link);
@ -39,7 +35,6 @@ int link_drop_foreign_neighbors(Link *link);
void link_foreignize_neighbors(Link *link);
int link_request_static_neighbors(Link *link);
int request_process_neighbor(Request *req);
int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);

View File

@ -222,7 +222,7 @@ DHCPv4.SendHostname, config_parse_bool,
DHCPv4.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname)
DHCPv4.Label, config_parse_dhcp_label, 0, offsetof(Network, dhcp_label)
DHCPv4.RequestBroadcast, config_parse_tristate, 0, offsetof(Network, dhcp_broadcast)
DHCPv4.VendorClassIdentifier, config_parse_safe_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
DHCPv4.VendorClassIdentifier, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_vendor_class_identifier)
DHCPv4.MUDURL, config_parse_mud_url, 0, offsetof(Network, dhcp_mudurl)
DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
DHCPv4.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class)
@ -305,8 +305,9 @@ DHCPServer.PoolSize, config_parse_uint32,
DHCPServer.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_server_send_vendor_options)
DHCPServer.SendOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_server_send_options)
DHCPServer.BindToInterface, config_parse_bool, 0, offsetof(Network, dhcp_server_bind_to_interface)
DHCPServer.NextServer, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_next_server)
DHCPServer.Filename, config_parse_string, 0, offsetof(Network, dhcp_server_filename)
DHCPServer.BootServerAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_boot_server_address)
DHCPServer.BootServerName, config_parse_dns_name, 0, offsetof(Network, dhcp_server_boot_server_name)
DHCPServer.BootFilename, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, dhcp_server_boot_filename)
DHCPServerStaticLease.Address, config_parse_dhcp_static_lease_address, 0, 0
DHCPServerStaticLease.MACAddress, config_parse_dhcp_static_lease_hwaddr, 0, 0
Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
@ -543,7 +544,7 @@ DHCP.SendHostname, config_parse_bool,
DHCP.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname)
DHCP.RequestBroadcast, config_parse_tristate, 0, offsetof(Network, dhcp_broadcast)
DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
DHCP.VendorClassIdentifier, config_parse_safe_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
DHCP.VendorClassIdentifier, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_vendor_class_identifier)
DHCP.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class)
DHCP.IAID, config_parse_iaid, AF_INET, 0
DHCP.DUIDType, config_parse_network_duid_type, 0, 0

View File

@ -702,7 +702,8 @@ static Network *network_free(Network *network) {
free(network->dhcp_server_relay_agent_circuit_id);
free(network->dhcp_server_relay_agent_remote_id);
free(network->dhcp_server_filename);
free(network->dhcp_server_boot_server_name);
free(network->dhcp_server_boot_filename);
free(network->description);
free(network->dhcp_vendor_class_identifier);
@ -982,52 +983,6 @@ int config_parse_domains(
}
}
int config_parse_hostname(
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) {
char **hostname = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
*hostname = mfree(*hostname);
return 0;
}
if (!hostname_is_valid(rvalue, 0)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Hostname is not valid, ignoring assignment: %s", rvalue);
return 0;
}
r = dns_name_is_valid(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to check validity of hostname '%s', ignoring assignment: %m", rvalue);
return 0;
}
if (r == 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Hostname is not a valid DNS domain name, ignoring assignment: %s", rvalue);
return 0;
}
return free_and_strdup_warn(hostname, rvalue);
}
int config_parse_timezone(
const char *unit,
const char *filename,

View File

@ -200,8 +200,9 @@ struct Network {
uint32_t dhcp_server_pool_size;
OrderedHashmap *dhcp_server_send_options;
OrderedHashmap *dhcp_server_send_vendor_options;
struct in_addr dhcp_server_next_server;
char *dhcp_server_filename;
struct in_addr dhcp_server_boot_server_address;
char *dhcp_server_boot_server_name;
char *dhcp_server_boot_filename;
/* link local addressing support */
AddressFamily link_local;
@ -374,7 +375,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_stacked_netdev);
CONFIG_PARSER_PROTOTYPE(config_parse_tunnel);
CONFIG_PARSER_PROTOTYPE(config_parse_domains);
CONFIG_PARSER_PROTOTYPE(config_parse_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_hostname);
CONFIG_PARSER_PROTOTYPE(config_parse_timezone);
CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors);
CONFIG_PARSER_PROTOTYPE(config_parse_ntp);

View File

@ -104,7 +104,7 @@ static int nexthop_new_static(Network *network, const char *filename, unsigned s
return 0;
}
void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
assert(nexthop);
siphash24_compress(&nexthop->protocol, sizeof(nexthop->protocol), state);
@ -124,7 +124,7 @@ void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
}
}
int nexthop_compare_func(const NextHop *a, const NextHop *b) {
static int nexthop_compare_func(const NextHop *a, const NextHop *b) {
int r;
r = CMP(a->protocol, b->protocol);
@ -425,11 +425,7 @@ static int nexthop_remove(NextHop *nexthop) {
return 0;
}
static int nexthop_configure(
NextHop *nexthop,
Link *link,
link_netlink_message_handler_t callback) {
static int nexthop_configure(NextHop *nexthop, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -439,7 +435,7 @@ static int nexthop_configure(
assert(link->manager);
assert(link->manager->rtnl);
assert(link->ifindex > 0);
assert(callback);
assert(req);
log_nexthop_debug(nexthop, "Configuring", link);
@ -489,25 +485,14 @@ static int nexthop_configure(
}
}
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, NextHop *nexthop) {
int r;
assert(m);
assert(link);
assert(link->static_nexthop_messages > 0);
link->static_nexthop_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -561,7 +546,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
ORDERED_SET_FOREACH(req, link->manager->request_queue) {
if (req->type != REQUEST_TYPE_NEXTHOP)
continue;
if (req->nexthop->id != 0)
if (((NextHop*) req->userdata)->id != 0)
return false; /* first configure nexthop with id. */
}
}
@ -569,21 +554,17 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw);
}
int request_process_nexthop(Request *req) {
NextHop *nexthop;
Link *link;
static int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) {
int r;
assert(req);
assert(req->type == REQUEST_TYPE_NEXTHOP);
nexthop = ASSERT_PTR(req->nexthop);
link = ASSERT_PTR(req->link);
assert(link);
assert(nexthop);
if (!nexthop_is_ready_to_configure(link, nexthop))
return 0;
r = nexthop_configure(nexthop, link, req->netlink_handler);
r = nexthop_configure(nexthop, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure nexthop");
@ -591,13 +572,7 @@ int request_process_nexthop(Request *req) {
return 1;
}
static int link_request_nexthop(
Link *link,
NextHop *nexthop,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
Request **ret) {
static int link_request_nexthop(Link *link, NextHop *nexthop) {
NextHop *existing;
int r;
@ -625,8 +600,14 @@ static int link_request_nexthop(
existing->source = nexthop->source;
log_nexthop_debug(existing, "Requesting", link);
r = link_queue_request(link, REQUEST_TYPE_NEXTHOP, existing, false,
message_counter, netlink_handler, ret);
r = link_queue_request_safe(link, REQUEST_TYPE_NEXTHOP,
existing, NULL,
nexthop_hash_func,
nexthop_compare_func,
nexthop_process_request,
&link->static_nexthop_messages,
static_nexthop_handler,
NULL);
if (r <= 0)
return r;
@ -647,8 +628,7 @@ int link_request_static_nexthops(Link *link, bool only_ipv4) {
if (only_ipv4 && nh->family != AF_INET)
continue;
r = link_request_nexthop(link, nh, &link->static_nexthop_messages,
static_nexthop_handler, NULL);
r = link_request_nexthop(link, nh);
if (r < 0)
return log_link_warning_errno(link, r, "Could not request nexthop: %m");
}

View File

@ -16,7 +16,6 @@
typedef struct Link Link;
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef struct NextHop {
Network *network;
@ -39,9 +38,6 @@ typedef struct NextHop {
NextHop *nexthop_free(NextHop *nexthop);
void nexthop_hash_func(const NextHop *nexthop, struct siphash *state);
int nexthop_compare_func(const NextHop *a, const NextHop *b);
void network_drop_invalid_nexthops(Network *network);
int link_drop_managed_nexthops(Link *link);
@ -49,7 +45,6 @@ int link_drop_foreign_nexthops(Link *link);
void link_foreignize_nexthops(Link *link);
int link_request_static_nexthops(Link *link, bool only_ipv4);
int request_process_nexthop(Request *req);
int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret);
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);

View File

@ -1,107 +1,47 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "networkd-address.h"
#include "networkd-address-label.h"
#include "networkd-bridge-fdb.h"
#include "networkd-bridge-mdb.h"
#include "networkd-dhcp-server.h"
#include "networkd-dhcp4.h"
#include "networkd-dhcp6.h"
#include "networkd-ipv6-proxy-ndp.h"
#include "netdev.h"
#include "netlink-util.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-ndisc.h"
#include "networkd-neighbor.h"
#include "networkd-nexthop.h"
#include "networkd-route.h"
#include "networkd-routing-policy-rule.h"
#include "networkd-queue.h"
#include "networkd-setlink.h"
#include "qdisc.h"
#include "tclass.h"
static void request_free_object(RequestType type, void *object) {
switch (type) {
case REQUEST_TYPE_ACTIVATE_LINK:
break;
case REQUEST_TYPE_ADDRESS:
address_free(object);
break;
case REQUEST_TYPE_ADDRESS_LABEL:
address_label_free(object);
break;
case REQUEST_TYPE_BRIDGE_FDB:
bridge_fdb_free(object);
break;
case REQUEST_TYPE_BRIDGE_MDB:
bridge_mdb_free(object);
break;
case REQUEST_TYPE_DHCP_SERVER:
case REQUEST_TYPE_DHCP4_CLIENT:
case REQUEST_TYPE_DHCP6_CLIENT:
break;
case REQUEST_TYPE_IPV6_PROXY_NDP:
free(object);
break;
case REQUEST_TYPE_NDISC:
break;
case REQUEST_TYPE_NEIGHBOR:
neighbor_free(object);
break;
case REQUEST_TYPE_NETDEV_INDEPENDENT:
case REQUEST_TYPE_NETDEV_STACKED:
netdev_unref(object);
break;
case REQUEST_TYPE_NEXTHOP:
nexthop_free(object);
break;
case REQUEST_TYPE_RADV:
break;
case REQUEST_TYPE_ROUTE:
route_free(object);
break;
case REQUEST_TYPE_ROUTING_POLICY_RULE:
routing_policy_rule_free(object);
break;
case REQUEST_TYPE_SET_LINK:
break;
case REQUEST_TYPE_TC_QDISC:
qdisc_free(object);
break;
case REQUEST_TYPE_TC_CLASS:
tclass_free(object);
break;
case REQUEST_TYPE_UP_DOWN:
break;
default:
assert_not_reached();
}
}
#include "string-table.h"
static Request *request_free(Request *req) {
if (!req)
return NULL;
if (req->link && req->link->manager)
/* To prevent from triggering assertions in hash functions, remove this request before
* freeing object below. */
ordered_set_remove(req->link->manager->request_queue, req);
if (req->consume_object)
request_free_object(req->type, req->object);
link_unref(req->link);
/* To prevent from triggering assertions in the hash and compare functions, remove this request
* before freeing userdata below. */
if (req->manager)
ordered_set_remove(req->manager->request_queue, req);
if (req->free_func)
req->free_func(req->userdata);
if (req->counter)
(*req->counter)--;
link_unref(req->link); /* link may be NULL, but link_unref() can handle it gracefully. */
return mfree(req);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_free);
DEFINE_TRIVIAL_REF_UNREF_FUNC(Request, request, request_free);
DEFINE_TRIVIAL_DESTRUCTOR(request_destroy_callback, Request, request_unref);
void request_detach(Manager *manager, Request *req) {
assert(manager);
void request_drop(Request *req) {
if (!req)
return;
if (req->message_counter)
(*req->message_counter)--;
req = ordered_set_remove(manager->request_queue, req);
if (!req)
return;
request_free(req);
req->manager = NULL;
request_unref(req);
}
static void request_hash_func(const Request *req, struct siphash *state) {
@ -114,61 +54,11 @@ static void request_hash_func(const Request *req, struct siphash *state) {
siphash24_compress(&req->type, sizeof(req->type), state);
switch (req->type) {
case REQUEST_TYPE_ACTIVATE_LINK:
break;
case REQUEST_TYPE_ADDRESS:
address_hash_func(req->address, state);
break;
case REQUEST_TYPE_ADDRESS_LABEL:
case REQUEST_TYPE_BRIDGE_FDB:
case REQUEST_TYPE_BRIDGE_MDB:
case REQUEST_TYPE_NETDEV_INDEPENDENT:
case REQUEST_TYPE_NETDEV_STACKED:
/* TODO: Currently, these types do not have any specific hash and compare functions.
* Fortunately, all these objects are 'static', thus we can use the trivial functions. */
trivial_hash_func(req->object, state);
break;
case REQUEST_TYPE_DHCP_SERVER:
case REQUEST_TYPE_DHCP4_CLIENT:
case REQUEST_TYPE_DHCP6_CLIENT:
/* These types do not have an object. */
break;
case REQUEST_TYPE_IPV6_PROXY_NDP:
in6_addr_hash_func(req->ipv6_proxy_ndp, state);
break;
case REQUEST_TYPE_NDISC:
/* This type does not have an object. */
break;
case REQUEST_TYPE_NEIGHBOR:
neighbor_hash_func(req->neighbor, state);
break;
case REQUEST_TYPE_NEXTHOP:
nexthop_hash_func(req->nexthop, state);
break;
case REQUEST_TYPE_RADV:
/* This type does not have an object. */
break;
case REQUEST_TYPE_ROUTE:
route_hash_func(req->route, state);
break;
case REQUEST_TYPE_ROUTING_POLICY_RULE:
routing_policy_rule_hash_func(req->rule, state);
break;
case REQUEST_TYPE_SET_LINK:
trivial_hash_func(req->set_link_operation_ptr, state);
break;
case REQUEST_TYPE_TC_QDISC:
qdisc_hash_func(req->qdisc, state);
break;
case REQUEST_TYPE_TC_CLASS:
tclass_hash_func(req->tclass, state);
break;
case REQUEST_TYPE_UP_DOWN:
break;
default:
assert_not_reached();
}
siphash24_compress(&req->hash_func, sizeof(req->hash_func), state);
siphash24_compress(&req->compare_func, sizeof(req->compare_func), state);
if (req->hash_func)
req->hash_func(req->userdata, state);
}
static int request_compare_func(const struct Request *a, const struct Request *b) {
@ -191,46 +81,18 @@ static int request_compare_func(const struct Request *a, const struct Request *b
if (r != 0)
return r;
switch (a->type) {
case REQUEST_TYPE_ACTIVATE_LINK:
r = CMP(PTR_TO_UINT64(a->hash_func), PTR_TO_UINT64(b->hash_func));
if (r != 0)
return r;
r = CMP(PTR_TO_UINT64(a->compare_func), PTR_TO_UINT64(b->compare_func));
if (r != 0)
return r;
if (a->compare_func)
return a->compare_func(a->userdata, b->userdata);
return 0;
case REQUEST_TYPE_ADDRESS:
return address_compare_func(a->address, b->address);
case REQUEST_TYPE_ADDRESS_LABEL:
case REQUEST_TYPE_BRIDGE_FDB:
case REQUEST_TYPE_BRIDGE_MDB:
case REQUEST_TYPE_NETDEV_INDEPENDENT:
case REQUEST_TYPE_NETDEV_STACKED:
return trivial_compare_func(a->object, b->object);
case REQUEST_TYPE_DHCP_SERVER:
case REQUEST_TYPE_DHCP4_CLIENT:
case REQUEST_TYPE_DHCP6_CLIENT:
return 0;
case REQUEST_TYPE_IPV6_PROXY_NDP:
return in6_addr_compare_func(a->ipv6_proxy_ndp, b->ipv6_proxy_ndp);
case REQUEST_TYPE_NDISC:
return 0;
case REQUEST_TYPE_NEIGHBOR:
return neighbor_compare_func(a->neighbor, b->neighbor);
case REQUEST_TYPE_NEXTHOP:
return nexthop_compare_func(a->nexthop, b->nexthop);
case REQUEST_TYPE_ROUTE:
return route_compare_func(a->route, b->route);
case REQUEST_TYPE_RADV:
return 0;
case REQUEST_TYPE_ROUTING_POLICY_RULE:
return routing_policy_rule_compare_func(a->rule, b->rule);
case REQUEST_TYPE_SET_LINK:
return trivial_compare_func(a->set_link_operation_ptr, b->set_link_operation_ptr);
case REQUEST_TYPE_TC_QDISC:
return qdisc_compare_func(a->qdisc, b->qdisc);
case REQUEST_TYPE_TC_CLASS:
return tclass_compare_func(a->tclass, b->tclass);
case REQUEST_TYPE_UP_DOWN:
return 0;
default:
assert_not_reached();
}
}
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
@ -238,217 +100,204 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
Request,
request_hash_func,
request_compare_func,
request_free);
request_unref);
int netdev_queue_request(
NetDev *netdev,
Request **ret) {
_cleanup_(request_freep) Request *req = NULL;
Request *existing;
int r;
assert(netdev);
assert(netdev->manager);
req = new(Request, 1);
if (!req)
return -ENOMEM;
*req = (Request) {
.netdev = netdev_ref(netdev),
.type = REQUEST_TYPE_NETDEV_INDEPENDENT,
.consume_object = true,
};
existing = ordered_set_get(netdev->manager->request_queue, req);
if (existing) {
/* To prevent from removing the existing request. */
req->netdev = netdev_unref(req->netdev);
if (ret)
*ret = existing;
return 0;
}
r = ordered_set_ensure_put(&netdev->manager->request_queue, &request_hash_ops, req);
if (r < 0)
return r;
if (ret)
*ret = req;
TAKE_PTR(req);
return 1;
}
int link_queue_request(
static int request_new(
Manager *manager,
Link *link,
RequestType type,
void *object,
bool consume_object,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
void *userdata,
mfree_func_t free_func,
hash_func_t hash_func,
compare_func_t compare_func,
request_process_func_t process,
unsigned *counter,
request_netlink_handler_t netlink_handler,
Request **ret) {
_cleanup_(request_freep) Request *req = NULL;
_cleanup_(request_unrefp) Request *req = NULL;
Request *existing;
int r;
assert(link);
assert(link->manager);
assert(type >= 0 && type < _REQUEST_TYPE_MAX);
assert(IN_SET(type,
REQUEST_TYPE_ACTIVATE_LINK,
REQUEST_TYPE_DHCP_SERVER,
REQUEST_TYPE_DHCP4_CLIENT,
REQUEST_TYPE_DHCP6_CLIENT,
REQUEST_TYPE_NDISC,
REQUEST_TYPE_RADV,
REQUEST_TYPE_SET_LINK,
REQUEST_TYPE_UP_DOWN) ||
object);
assert(IN_SET(type,
REQUEST_TYPE_DHCP_SERVER,
REQUEST_TYPE_DHCP4_CLIENT,
REQUEST_TYPE_DHCP6_CLIENT,
REQUEST_TYPE_NDISC,
REQUEST_TYPE_RADV,
REQUEST_TYPE_TC_QDISC,
REQUEST_TYPE_TC_CLASS) ||
netlink_handler);
req = new(Request, 1);
if (!req) {
if (consume_object)
request_free_object(type, object);
return -ENOMEM;
}
*req = (Request) {
.link = link_ref(link),
.type = type,
.object = object,
.consume_object = consume_object,
.message_counter = message_counter,
.netlink_handler = netlink_handler,
};
existing = ordered_set_get(link->manager->request_queue, req);
if (existing) {
/* To prevent from removing the existing request. */
req->link = link_unref(req->link);
if (ret)
*ret = existing;
return 0;
}
r = ordered_set_ensure_put(&link->manager->request_queue, &request_hash_ops, req);
if (r < 0)
return r;
if (req->message_counter)
(*req->message_counter)++;
if (ret)
*ret = req;
TAKE_PTR(req);
return 1;
}
int manager_process_requests(sd_event_source *s, void *userdata) {
Manager *manager = userdata;
int r;
assert(manager);
assert(process);
req = new(Request, 1);
if (!req) {
if (free_func)
free_func(userdata);
return -ENOMEM;
}
*req = (Request) {
.n_ref = 1,
.link = link_ref(link), /* link may be NULL, but link_ref() handles it gracefully. */
.type = type,
.userdata = userdata,
.free_func = free_func,
.hash_func = hash_func,
.compare_func = compare_func,
.process = process,
.netlink_handler = netlink_handler,
};
existing = ordered_set_get(manager->request_queue, req);
if (existing) {
if (ret)
*ret = existing;
return 0;
}
r = ordered_set_ensure_put(&manager->request_queue, &request_hash_ops, req);
if (r < 0)
return r;
req->manager = manager;
req->counter = counter;
if (req->counter)
(*req->counter)++;
if (ret)
*ret = req;
TAKE_PTR(req);
return 1;
}
int netdev_queue_request(
NetDev *netdev,
request_process_func_t process,
Request **ret) {
assert(netdev);
return request_new(netdev->manager, NULL, REQUEST_TYPE_NETDEV_INDEPENDENT,
netdev_ref(netdev), (mfree_func_t) netdev_unref,
trivial_hash_func, trivial_compare_func,
process, NULL, NULL, ret);
}
int link_queue_request_full(
Link *link,
RequestType type,
void *userdata,
mfree_func_t free_func,
hash_func_t hash_func,
compare_func_t compare_func,
request_process_func_t process,
unsigned *counter,
request_netlink_handler_t netlink_handler,
Request **ret) {
assert(link);
return request_new(link->manager, link, type,
userdata, free_func, hash_func, compare_func,
process, counter, netlink_handler, ret);
}
int manager_process_requests(sd_event_source *s, void *userdata) {
Manager *manager = ASSERT_PTR(userdata);
int r;
for (;;) {
bool processed = false;
Request *req;
ORDERED_SET_FOREACH(req, manager->request_queue) {
switch (req->type) {
case REQUEST_TYPE_ACTIVATE_LINK:
r = request_process_activation(req);
break;
case REQUEST_TYPE_ADDRESS:
r = request_process_address(req);
break;
case REQUEST_TYPE_ADDRESS_LABEL:
r = request_process_address_label(req);
break;
case REQUEST_TYPE_BRIDGE_FDB:
r = request_process_bridge_fdb(req);
break;
case REQUEST_TYPE_BRIDGE_MDB:
r = request_process_bridge_mdb(req);
break;
case REQUEST_TYPE_DHCP_SERVER:
r = request_process_dhcp_server(req);
break;
case REQUEST_TYPE_DHCP4_CLIENT:
r = request_process_dhcp4_client(req);
break;
case REQUEST_TYPE_DHCP6_CLIENT:
r = request_process_dhcp6_client(req);
break;
case REQUEST_TYPE_IPV6_PROXY_NDP:
r = request_process_ipv6_proxy_ndp_address(req);
break;
case REQUEST_TYPE_NDISC:
r = request_process_ndisc(req);
break;
case REQUEST_TYPE_NEIGHBOR:
r = request_process_neighbor(req);
break;
case REQUEST_TYPE_NETDEV_INDEPENDENT:
r = request_process_independent_netdev(req);
break;
case REQUEST_TYPE_NETDEV_STACKED:
r = request_process_stacked_netdev(req);
break;
case REQUEST_TYPE_NEXTHOP:
r = request_process_nexthop(req);
break;
case REQUEST_TYPE_RADV:
r = request_process_radv(req);
break;
case REQUEST_TYPE_ROUTE:
r = request_process_route(req);
break;
case REQUEST_TYPE_ROUTING_POLICY_RULE:
r = request_process_routing_policy_rule(req);
break;
case REQUEST_TYPE_SET_LINK:
r = request_process_set_link(req);
break;
case REQUEST_TYPE_TC_QDISC:
r = request_process_qdisc(req);
break;
case REQUEST_TYPE_TC_CLASS:
r = request_process_tclass(req);
break;
case REQUEST_TYPE_UP_DOWN:
r = request_process_link_up_or_down(req);
break;
default:
return -EINVAL;
}
if (r < 0) {
if (req->link)
link_enter_failed(req->link);
} else if (r > 0) {
ordered_set_remove(manager->request_queue, req);
request_free(req);
_unused_ _cleanup_(request_unrefp) Request *ref = request_ref(req);
_cleanup_(link_unrefp) Link *link = link_ref(req->link);
assert(req->process);
r = req->process(req, link, req->userdata);
if (r == 0)
continue;
processed = true;
request_detach(manager, req);
if (r < 0 && link) {
link_enter_failed(link);
/* link_enter_failed() may remove multiple requests,
* hence we need to exit from the loop. */
break;
}
}
/* When at least one request is processed, then another request may be ready now. */
if (!processed)
break;
}
return 0;
}
static int request_netlink_handler(sd_netlink *nl, sd_netlink_message *m, Request *req) {
assert(req);
if (req->counter) {
assert(*req->counter > 0);
(*req->counter)--;
req->counter = NULL; /* To prevent double decrement on free. */
}
if (req->link && IN_SET(req->link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
if (req->netlink_handler)
return req->netlink_handler(nl, m, req, req->link, req->userdata);
return 0;
}
int request_call_netlink_async(sd_netlink *nl, sd_netlink_message *m, Request *req) {
int r;
assert(nl);
assert(m);
assert(req);
r = netlink_call_async(nl, NULL, m, request_netlink_handler, request_destroy_callback, req);
if (r < 0)
return r;
request_ref(req);
return 0;
}
static const char *const request_type_table[_REQUEST_TYPE_MAX] = {
[REQUEST_TYPE_ACTIVATE_LINK] = "activate link",
[REQUEST_TYPE_ADDRESS] = "address",
[REQUEST_TYPE_ADDRESS_LABEL] = "address label",
[REQUEST_TYPE_BRIDGE_FDB] = "bridge FDB",
[REQUEST_TYPE_BRIDGE_MDB] = "bridge MDB",
[REQUEST_TYPE_DHCP_SERVER] = "DHCP server",
[REQUEST_TYPE_DHCP4_CLIENT] = "DHCPv4 client",
[REQUEST_TYPE_DHCP6_CLIENT] = "DHCPv6 client",
[REQUEST_TYPE_IPV6_PROXY_NDP] = "IPv6 proxy NDP",
[REQUEST_TYPE_NDISC] = "NDisc",
[REQUEST_TYPE_NEIGHBOR] = "neighbor",
[REQUEST_TYPE_NETDEV_INDEPENDENT] = "independent netdev",
[REQUEST_TYPE_NETDEV_STACKED] = "stacked netdev",
[REQUEST_TYPE_NEXTHOP] = "nexthop",
[REQUEST_TYPE_RADV] = "RADV",
[REQUEST_TYPE_ROUTE] = "route",
[REQUEST_TYPE_ROUTING_POLICY_RULE] = "routing policy rule",
[REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE] = "IPv6LL address generation mode",
[REQUEST_TYPE_SET_LINK_BOND] = "bond configurations",
[REQUEST_TYPE_SET_LINK_BRIDGE] = "bridge configurations",
[REQUEST_TYPE_SET_LINK_BRIDGE_VLAN] = "bridge VLAN configurations",
[REQUEST_TYPE_SET_LINK_CAN] = "CAN interface configurations",
[REQUEST_TYPE_SET_LINK_FLAGS] = "link flags",
[REQUEST_TYPE_SET_LINK_GROUP] = "interface group",
[REQUEST_TYPE_SET_LINK_IPOIB] = "IPoIB configurations",
[REQUEST_TYPE_SET_LINK_MAC] = "MAC address",
[REQUEST_TYPE_SET_LINK_MASTER] = "master interface",
[REQUEST_TYPE_SET_LINK_MTU] = "MTU",
[REQUEST_TYPE_TC_QDISC] = "QDisc",
[REQUEST_TYPE_TC_CLASS] = "TClass",
[REQUEST_TYPE_UP_DOWN] = "bring link up or down",
};
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(request_type, RequestType);

View File

@ -2,20 +2,18 @@
#pragma once
#include "sd-event.h"
#include "sd-netlink.h"
#include "networkd-link.h"
#include "alloc-util.h"
#include "hash-funcs.h"
typedef struct Address Address;
typedef struct AddressLabel AddressLabel;
typedef struct BridgeFDB BridgeFDB;
typedef struct BridgeMDB BridgeMDB;
typedef struct Neighbor Neighbor;
typedef struct Link Link;
typedef struct NetDev NetDev;
typedef struct NextHop NextHop;
typedef struct Route Route;
typedef struct RoutingPolicyRule RoutingPolicyRule;
typedef struct QDisc QDisc;
typedef struct TClass TClass;
typedef struct Manager Manager;
typedef struct Request Request;
typedef int (*request_process_func_t)(Request *req, Link *link, void *userdata);
typedef int (*request_netlink_handler_t)(sd_netlink *nl, sd_netlink_message *m, Request *req, Link *link, void *userdata);
typedef enum RequestType {
REQUEST_TYPE_ACTIVATE_LINK,
@ -35,7 +33,17 @@ typedef enum RequestType {
REQUEST_TYPE_RADV,
REQUEST_TYPE_ROUTE,
REQUEST_TYPE_ROUTING_POLICY_RULE,
REQUEST_TYPE_SET_LINK,
REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE, /* Setting IPv6LL address generation mode. */
REQUEST_TYPE_SET_LINK_BOND, /* Setting bond configs. */
REQUEST_TYPE_SET_LINK_BRIDGE, /* Setting bridge configs. */
REQUEST_TYPE_SET_LINK_BRIDGE_VLAN, /* Setting bridge VLAN configs. */
REQUEST_TYPE_SET_LINK_CAN, /* Setting CAN interface configs. */
REQUEST_TYPE_SET_LINK_FLAGS, /* Setting IFF_NOARP or friends. */
REQUEST_TYPE_SET_LINK_GROUP, /* Setting interface group. */
REQUEST_TYPE_SET_LINK_IPOIB, /* Setting IPoIB configs. */
REQUEST_TYPE_SET_LINK_MAC, /* Setting MAC address. */
REQUEST_TYPE_SET_LINK_MASTER, /* Setting IFLA_MASTER. */
REQUEST_TYPE_SET_LINK_MTU, /* Setting MTU. */
REQUEST_TYPE_TC_CLASS,
REQUEST_TYPE_TC_QDISC,
REQUEST_TYPE_UP_DOWN,
@ -43,44 +51,88 @@ typedef enum RequestType {
_REQUEST_TYPE_INVALID = -EINVAL,
} RequestType;
typedef struct Request {
Link *link;
RequestType type;
bool consume_object;
union {
Address *address;
AddressLabel *label;
BridgeFDB *fdb;
BridgeMDB *mdb;
struct in6_addr *ipv6_proxy_ndp;
Neighbor *neighbor;
NextHop *nexthop;
Route *route;
RoutingPolicyRule *rule;
void *set_link_operation_ptr;
NetDev *netdev;
QDisc *qdisc;
TClass *tclass;
void *object;
};
void *userdata;
unsigned *message_counter;
link_netlink_message_handler_t netlink_handler;
} Request;
struct Request {
unsigned n_ref;
void request_drop(Request *req);
Manager *manager; /* must be non-NULL */
Link *link; /* can be NULL */
RequestType type;
/* Target object, e.g. Address, Route, NetDev, and so on. */
void *userdata;
/* freeing userdata when the request is completed or failed. */
mfree_func_t free_func;
/* hash and compare functions for userdata, used for dedup requests. */
hash_func_t hash_func;
compare_func_t compare_func;
/* Checks the request dependencies, and then processes this request, e.g. call address_configure().
* Return 1 when processed, 0 when its dependencies not resolved, and negative errno on failure. */
request_process_func_t process;
/* incremented when requested, decremented when request is completed or failed. */
unsigned *counter;
/* called in netlink handler, the 'counter' is decremented before this is called.
* If this is specified, then the 'process' function must increment the reference of this
* request, and pass this request to the netlink_call_async(), and set the destroy function
* to the slot. */
request_netlink_handler_t netlink_handler;
};
Request *request_ref(Request *req);
Request *request_unref(Request *req);
DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_unref);
void request_detach(Manager *manager, Request *req);
int netdev_queue_request(
NetDev *netdev,
request_process_func_t process,
Request **ret);
int link_queue_request(
int link_queue_request_full(
Link *link,
RequestType type,
void *object,
bool consume_object,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
void *userdata,
mfree_func_t free_func,
hash_func_t hash_func,
compare_func_t compare_func,
request_process_func_t process,
unsigned *counter,
request_netlink_handler_t netlink_handler,
Request **ret);
static inline int link_queue_request(
Link *link,
RequestType type,
request_process_func_t process,
Request **ret) {
return link_queue_request_full(link, type, NULL, NULL, NULL, NULL,
process, NULL, NULL, ret);
}
#define link_queue_request_safe(link, type, userdata, free_func, hash_func, compare_func, process, counter, netlink_handler, ret) \
({ \
typeof(userdata) (*_f)(typeof(userdata)) = (free_func); \
void (*_h)(const typeof(*userdata)*, struct siphash*) = (hash_func); \
int (*_c)(const typeof(*userdata)*, const typeof(*userdata)*) = (compare_func); \
int (*_p)(Request*, Link*, typeof(userdata)) = (process); \
int (*_n)(sd_netlink*, sd_netlink_message*, Request*, Link*, typeof(userdata)) = (netlink_handler); \
\
link_queue_request_full(link, type, userdata, \
(mfree_func_t) _f, \
(hash_func_t) _h, \
(compare_func_t) _c, \
(request_process_func_t) _p, \
counter, \
(request_netlink_handler_t) _n, \
ret); \
})
int manager_process_requests(sd_event_source *s, void *userdata);
int request_call_netlink_async(sd_netlink *nl, sd_netlink_message *m, Request *req);
const char* request_type_to_string(RequestType t) _const_;

View File

@ -582,15 +582,10 @@ static int radv_is_ready_to_configure(Link *link) {
return true;
}
int request_process_radv(Request *req) {
Link *link;
static int radv_process_request(Request *req, Link *link, void *userdata) {
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_RADV);
link = req->link;
assert(link);
r = radv_is_ready_to_configure(link);
if (r <= 0)
@ -622,7 +617,7 @@ int link_request_radv(Link *link) {
if (link->radv)
return 0;
r = link_queue_request(link, REQUEST_TYPE_RADV, NULL, false, NULL, NULL, NULL);
r = link_queue_request(link, REQUEST_TYPE_RADV, radv_process_request, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request configuring of the IPv6 Router Advertisement engine: %m");

View File

@ -16,7 +16,6 @@
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef enum RADVPrefixDelegation {
RADV_PREFIX_DELEGATION_NONE = 0,
@ -68,7 +67,6 @@ int radv_update_mac(Link *link);
int radv_add_prefix(Link *link, const struct in6_addr *prefix, uint8_t prefix_len,
usec_t lifetime_preferred_usec, usec_t lifetime_valid_usec);
int request_process_radv(Request *req);
int link_request_radv(Link *link);
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;

View File

@ -110,7 +110,7 @@ Route *route_free(Route *route) {
return mfree(route);
}
void route_hash_func(const Route *route, struct siphash *state) {
static void route_hash_func(const Route *route, struct siphash *state) {
assert(route);
siphash24_compress(&route->family, sizeof(route->family), state);
@ -152,7 +152,7 @@ void route_hash_func(const Route *route, struct siphash *state) {
}
}
int route_compare_func(const Route *a, const Route *b) {
static int route_compare_func(const Route *a, const Route *b) {
int r;
r = CMP(a->family, b->family);
@ -1141,9 +1141,6 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
assert(link);
assert(error_msg);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_warning_errno(link, m, r, "Could not set route");
@ -1154,11 +1151,7 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
return 1;
}
static int route_configure(
const Route *route,
Link *link,
link_netlink_message_handler_t callback) {
static int route_configure(const Route *route, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -1168,7 +1161,7 @@ static int route_configure(
assert(link->manager);
assert(link->manager->rtnl);
assert(link->ifindex > 0);
assert(callback);
assert(req);
log_route_debug(route, "Configuring", link, link->manager);
@ -1250,13 +1243,7 @@ static int route_configure(
return r;
}
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static int route_is_ready_to_configure(const Route *route, Link *link) {
@ -1323,19 +1310,13 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
return true;
}
int request_process_route(Request *req) {
static int route_process_request(Request *req, Link *link, Route *route) {
_cleanup_(converted_routes_freep) ConvertedRoutes *converted = NULL;
Route *route;
Link *link;
int r;
assert(req);
assert(req->link);
assert(req->route);
assert(req->type == REQUEST_TYPE_ROUTE);
link = req->link;
route = req->route;
assert(link);
assert(route);
r = route_is_ready_to_configure(route, link);
if (r < 0)
@ -1373,7 +1354,7 @@ int request_process_route(Request *req) {
}
}
r = route_configure(route, link, req->netlink_handler);
r = route_configure(route, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure route: %m");
@ -1395,7 +1376,7 @@ int link_request_route(
Route *route,
bool consume_object,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
route_netlink_handler_t netlink_handler,
Request **ret) {
Route *existing;
@ -1442,7 +1423,11 @@ int link_request_route(
}
log_route_debug(existing, "Requesting", link, link->manager);
r = link_queue_request(link, REQUEST_TYPE_ROUTE, existing, false,
r = link_queue_request_safe(link, REQUEST_TYPE_ROUTE,
existing, NULL,
route_hash_func,
route_compare_func,
route_process_request,
message_counter, netlink_handler, ret);
if (r <= 0)
return r;
@ -1451,13 +1436,10 @@ int link_request_route(
return 1;
}
static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
int r;
assert(link);
assert(link->static_route_messages > 0);
link->static_route_messages--;
r = route_configure_handler_internal(rtnl, m, link, "Could not set route");
if (r <= 0)
@ -1482,7 +1464,9 @@ static int link_request_static_route(Link *link, Route *route) {
static_route_handler, NULL);
log_route_debug(route, "Requesting", link, link->manager);
return link_queue_request(link, REQUEST_TYPE_ROUTE, route, false,
return link_queue_request_safe(link, REQUEST_TYPE_ROUTE,
route, NULL, route_hash_func, route_compare_func,
route_process_request,
&link->static_route_messages, static_route_handler, NULL);
}
@ -1567,10 +1551,12 @@ void route_cancel_request(Route *route, Link *link) {
req = (Request) {
.link = link,
.type = REQUEST_TYPE_ROUTE,
.route = route,
.userdata = route,
.hash_func = (hash_func_t) route_hash_func,
.compare_func = (compare_func_t) route_compare_func,
};
request_drop(ordered_set_get(link->manager->request_queue, &req));
request_detach(link->manager, &req);
route_cancel_requesting(route);
}

View File

@ -14,8 +14,15 @@
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef struct Route Route;
typedef int (*route_netlink_handler_t)(
sd_netlink *rtnl,
sd_netlink_message *m,
Request *req,
Link *link,
Route *route);
typedef struct Route {
struct Route {
Link *link;
Manager *manager;
Network *network;
@ -66,10 +73,8 @@ typedef struct Route {
usec_t lifetime_usec;
/* Used when kernel does not support RTA_EXPIRES attribute. */
sd_event_source *expire;
} Route;
};
void route_hash_func(const Route *route, struct siphash *state);
int route_compare_func(const Route *a, const Route *b);
extern const struct hash_ops route_hash_ops;
int route_new(Route **ret);
@ -92,10 +97,9 @@ int link_request_route(
Route *route,
bool consume_object,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
route_netlink_handler_t netlink_handler,
Request **ret);
int link_request_static_routes(Link *link, bool only_ipv4);
int request_process_route(Request *req);
int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);

View File

@ -153,7 +153,7 @@ static int routing_policy_rule_dup(const RoutingPolicyRule *src, RoutingPolicyRu
return 0;
}
void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state) {
static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state) {
assert(rule);
siphash24_compress(&rule->family, sizeof(rule->family), state);
@ -194,7 +194,7 @@ void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash
}
}
int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPolicyRule *b) {
static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPolicyRule *b) {
int r;
r = CMP(a->family, b->family);
@ -604,11 +604,7 @@ static int routing_policy_rule_remove(RoutingPolicyRule *rule) {
return 0;
}
static int routing_policy_rule_configure(
RoutingPolicyRule *rule,
Link *link,
link_netlink_message_handler_t callback) {
static int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -618,7 +614,7 @@ static int routing_policy_rule_configure(
assert(link->ifindex > 0);
assert(link->manager);
assert(link->manager->rtnl);
assert(callback);
assert(req);
log_routing_policy_rule_debug(rule, "Configuring", link, link->manager);
@ -630,13 +626,7 @@ static int routing_policy_rule_configure(
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static void manager_mark_routing_policy_rules(Manager *m, bool foreign, const Link *except) {
@ -728,21 +718,17 @@ void link_foreignize_routing_policy_rules(Link *link) {
}
}
int request_process_routing_policy_rule(Request *req) {
RoutingPolicyRule *rule;
Link *link;
static int routing_policy_rule_process_request(Request *req, Link *link, RoutingPolicyRule *rule) {
int r;
assert(req);
assert(req->type == REQUEST_TYPE_ROUTING_POLICY_RULE);
link = ASSERT_PTR(req->link);
rule = ASSERT_PTR(req->rule);
assert(link);
assert(rule);
if (!link_is_ready_to_configure(link, false))
return 0;
r = routing_policy_rule_configure(rule, link, req->netlink_handler);
r = routing_policy_rule_configure(rule, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure routing policy rule: %m");
@ -750,19 +736,17 @@ int request_process_routing_policy_rule(Request *req) {
return 1;
}
static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int static_routing_policy_rule_configure_handler(
sd_netlink *rtnl,
sd_netlink_message *m,
Request *req,
Link *link,
RoutingPolicyRule *rule) {
int r;
assert(rtnl);
assert(m);
assert(link);
assert(link->ifname);
assert(link->static_routing_policy_rule_messages > 0);
link->static_routing_policy_rule_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -780,13 +764,7 @@ static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_net
return 1;
}
static int link_request_routing_policy_rule(
Link *link,
RoutingPolicyRule *rule,
unsigned *message_counter,
link_netlink_message_handler_t netlink_handler,
Request **ret) {
static int link_request_routing_policy_rule(Link *link, RoutingPolicyRule *rule) {
RoutingPolicyRule *existing;
int r;
@ -815,8 +793,14 @@ static int link_request_routing_policy_rule(
existing->source = rule->source;
log_routing_policy_rule_debug(existing, "Requesting", link, link->manager);
r = link_queue_request(link, REQUEST_TYPE_ROUTING_POLICY_RULE, existing, false,
message_counter, netlink_handler, ret);
r = link_queue_request_safe(link, REQUEST_TYPE_ROUTING_POLICY_RULE,
existing, NULL,
routing_policy_rule_hash_func,
routing_policy_rule_compare_func,
routing_policy_rule_process_request,
&link->static_routing_policy_rule_messages,
static_routing_policy_rule_configure_handler,
NULL);
if (r <= 0)
return r;
@ -828,26 +812,17 @@ static int link_request_static_routing_policy_rule(Link *link, RoutingPolicyRule
int r;
if (IN_SET(rule->family, AF_INET, AF_INET6))
return link_request_routing_policy_rule(link, rule,
&link->static_routing_policy_rule_messages,
static_routing_policy_rule_configure_handler,
NULL);
return link_request_routing_policy_rule(link, rule);
rule->family = AF_INET;
r = link_request_routing_policy_rule(link, rule,
&link->static_routing_policy_rule_messages,
static_routing_policy_rule_configure_handler,
NULL);
r = link_request_routing_policy_rule(link, rule);
if (r < 0) {
rule->family = AF_UNSPEC;
return r;
}
rule->family = AF_INET6;
r = link_request_routing_policy_rule(link, rule,
&link->static_routing_policy_rule_messages,
static_routing_policy_rule_configure_handler,
NULL);
r = link_request_routing_policy_rule(link, rule);
rule->family = AF_UNSPEC;
return r;
}

View File

@ -12,7 +12,6 @@
typedef struct Link Link;
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef struct RoutingPolicyRule {
Manager *manager;
@ -58,13 +57,9 @@ const char *fr_act_type_full_to_string(int t) _const_;
RoutingPolicyRule *routing_policy_rule_free(RoutingPolicyRule *rule);
void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state);
int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPolicyRule *b);
void network_drop_invalid_routing_policy_rules(Network *network);
int link_request_static_routing_policy_rules(Link *link);
int request_process_routing_policy_rule(Request *req);
int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except);

View File

@ -14,23 +14,6 @@
#include "networkd-manager.h"
#include "networkd-queue.h"
#include "networkd-setlink.h"
#include "string-table.h"
static const char *const set_link_operation_table[_SET_LINK_OPERATION_MAX] = {
[SET_LINK_ADDRESS_GENERATION_MODE] = "IPv6LL address generation mode",
[SET_LINK_BOND] = "bond configurations",
[SET_LINK_BRIDGE] = "bridge configurations",
[SET_LINK_BRIDGE_VLAN] = "bridge VLAN configurations",
[SET_LINK_CAN] = "CAN interface configurations",
[SET_LINK_FLAGS] = "link flags",
[SET_LINK_GROUP] = "interface group",
[SET_LINK_IPOIB] = "IPoIB configurations",
[SET_LINK_MAC] = "MAC address",
[SET_LINK_MASTER] = "master interface",
[SET_LINK_MTU] = "MTU",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(set_link_operation, SetLinkOperation);
static int get_link_default_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return link_getlink_handler_internal(rtnl, m, link, "Failed to sync link information");
@ -54,42 +37,36 @@ static int get_link_update_flag_handler(sd_netlink *rtnl, sd_netlink_message *m,
static int set_link_handler_internal(
sd_netlink *rtnl,
sd_netlink_message *m,
Request *req,
Link *link,
SetLinkOperation op,
bool ignore,
link_netlink_message_handler_t get_link_handler) {
int r;
assert(m);
assert(req);
assert(link);
assert(link->set_link_messages > 0);
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
link->set_link_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
goto on_error;
r = sd_netlink_message_get_errno(m);
if (r < 0) {
const char *error_msg;
error_msg = strjoina("Failed to set ", set_link_operation_to_string(op), ignore ? ", ignoring" : "");
error_msg = strjoina("Failed to set ", request_type_to_string(req->type), ignore ? ", ignoring" : "");
log_link_message_warning_errno(link, m, r, error_msg);
if (!ignore)
link_enter_failed(link);
goto on_error;
return 0;
}
log_link_debug(link, "%s set.", set_link_operation_to_string(op));
log_link_debug(link, "%s set.", request_type_to_string(req->type));
if (get_link_handler) {
r = link_call_getlink(link, get_link_handler);
if (r < 0) {
link_enter_failed(link);
goto on_error;
return 0;
}
}
@ -97,27 +74,12 @@ static int set_link_handler_internal(
link_check_ready(link);
return 1;
on_error:
switch (op) {
case SET_LINK_FLAGS:
assert(link->set_flags_messages > 0);
link->set_flags_messages--;
break;
case SET_LINK_MASTER:
link->master_set = true;
break;
default:
break;
}
return 0;
}
static int link_set_addrgen_mode_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int link_set_addrgen_mode_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
int r;
r = set_link_handler_internal(rtnl, m, link, SET_LINK_ADDRESS_GENERATION_MODE, /* ignore = */ true, NULL);
r = set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, NULL);
if (r <= 0)
return r;
@ -130,49 +92,43 @@ static int link_set_addrgen_mode_handler(sd_netlink *rtnl, sd_netlink_message *m
return 0;
}
static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_BOND, /* ignore = */ false, NULL);
static int link_set_bond_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL);
}
static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_BRIDGE, /* ignore = */ true, NULL);
static int link_set_bridge_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, NULL);
}
static int link_set_bridge_vlan_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_BRIDGE_VLAN, /* ignore = */ false, NULL);
static int link_set_bridge_vlan_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL);
}
static int link_set_can_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_CAN, /* ignore = */ false, NULL);
static int link_set_can_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL);
}
static int link_set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_FLAGS, /* ignore = */ false, get_link_update_flag_handler);
static int link_set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, get_link_default_handler);
}
static int link_set_group_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_GROUP, /* ignore = */ false, NULL);
static int link_set_group_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, NULL);
}
static int link_set_ipoib_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_IPOIB, /* ignore = */ true, NULL);
static int link_set_ipoib_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, NULL);
}
static int link_set_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_MAC, /* ignore = */ true, get_link_default_handler);
static int link_set_mac_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, get_link_default_handler);
}
static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
int r;
assert(m);
assert(link);
assert(link->set_link_messages > 0);
link->set_link_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 0;
r = sd_netlink_message_get_errno(m);
if (r == -EBUSY) {
@ -189,24 +145,22 @@ static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message
return 0;
}
/* set_link_mac_handler() also decrements set_link_messages, so increment the value once. */
link->set_link_messages++;
return link_set_mac_handler(rtnl, m, link);
return link_set_mac_handler(rtnl, m, req, link, userdata);
}
static int link_set_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return set_link_handler_internal(rtnl, m, link, SET_LINK_MASTER, /* ignore = */ false, get_link_master_handler);
static int link_set_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ false, get_link_master_handler);
}
static int link_unset_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int link_unset_master_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
/* Some devices do not support setting master ifindex. Let's ignore error on unsetting master ifindex. */
return set_link_handler_internal(rtnl, m, link, SET_LINK_MASTER, /* ignore = */ true, get_link_master_handler);
return set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, get_link_master_handler);
}
static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
int r;
r = set_link_handler_internal(rtnl, m, link, SET_LINK_MTU, /* ignore = */ true, get_link_default_handler);
r = set_link_handler_internal(rtnl, m, req, link, /* ignore = */ true, get_link_default_handler);
if (r <= 0)
return r;
@ -222,17 +176,17 @@ static int link_set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *l
static int link_configure_fill_message(
Link *link,
sd_netlink_message *req,
SetLinkOperation op,
RequestType type,
void *userdata) {
int r;
switch (op) {
case SET_LINK_ADDRESS_GENERATION_MODE:
switch (type) {
case REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE:
r = ipv6ll_addrgen_mode_fill_message(req, PTR_TO_UINT8(userdata));
if (r < 0)
return r;
break;
case SET_LINK_BOND:
case REQUEST_TYPE_SET_LINK_BOND:
r = sd_netlink_message_set_flags(req, NLM_F_REQUEST | NLM_F_ACK);
if (r < 0)
return r;
@ -266,7 +220,7 @@ static int link_configure_fill_message(
return r;
break;
case SET_LINK_BRIDGE:
case REQUEST_TYPE_SET_LINK_BRIDGE:
r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
if (r < 0)
return r;
@ -369,7 +323,7 @@ static int link_configure_fill_message(
if (r < 0)
return r;
break;
case SET_LINK_BRIDGE_VLAN:
case REQUEST_TYPE_SET_LINK_BRIDGE_VLAN:
r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
if (r < 0)
return r;
@ -394,12 +348,12 @@ static int link_configure_fill_message(
return r;
break;
case SET_LINK_CAN:
case REQUEST_TYPE_SET_LINK_CAN:
r = can_set_netlink_message(link, req);
if (r < 0)
return r;
break;
case SET_LINK_FLAGS: {
case REQUEST_TYPE_SET_LINK_FLAGS: {
unsigned ifi_change = 0, ifi_flags = 0;
if (link->network->arp >= 0) {
@ -428,27 +382,27 @@ static int link_configure_fill_message(
break;
}
case SET_LINK_GROUP:
case REQUEST_TYPE_SET_LINK_GROUP:
r = sd_netlink_message_append_u32(req, IFLA_GROUP, (uint32_t) link->network->group);
if (r < 0)
return r;
break;
case SET_LINK_MAC:
case REQUEST_TYPE_SET_LINK_MAC:
r = netlink_message_append_hw_addr(req, IFLA_ADDRESS, &link->requested_hw_addr);
if (r < 0)
return r;
break;
case SET_LINK_IPOIB:
case REQUEST_TYPE_SET_LINK_IPOIB:
r = ipoib_set_netlink_message(link, req);
if (r < 0)
return r;
break;
case SET_LINK_MASTER:
case REQUEST_TYPE_SET_LINK_MASTER:
r = sd_netlink_message_append_u32(req, IFLA_MASTER, PTR_TO_UINT32(userdata));
if (r < 0)
return r;
break;
case SET_LINK_MTU:
case REQUEST_TYPE_SET_LINK_MTU:
r = sd_netlink_message_append_u32(req, IFLA_MTU, PTR_TO_UINT32(userdata));
if (r < 0)
return r;
@ -460,44 +414,30 @@ static int link_configure_fill_message(
return 0;
}
static int link_configure(
Link *link,
SetLinkOperation op,
void *userdata,
link_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
static int link_configure(Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
assert(link);
assert(link->manager);
assert(link->manager->rtnl);
assert(link->network);
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
assert(callback);
assert(req);
log_link_debug(link, "Setting %s", set_link_operation_to_string(op));
log_link_debug(link, "Setting %s", request_type_to_string(req->type));
if (op == SET_LINK_BOND)
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->master_ifindex);
else if (IN_SET(op, SET_LINK_CAN, SET_LINK_IPOIB))
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->ifindex);
if (req->type == REQUEST_TYPE_SET_LINK_BOND)
r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->master_ifindex);
else if (IN_SET(req->type, REQUEST_TYPE_SET_LINK_CAN, REQUEST_TYPE_SET_LINK_IPOIB))
r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_NEWLINK, link->ifindex);
else
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_SETLINK, link->ifindex);
if (r < 0)
return log_link_debug_errno(link, r, "Could not allocate netlink message: %m");
return r;
r = link_configure_fill_message(link, req, op, userdata);
r = link_configure_fill_message(link, m, req->type, req->userdata);
if (r < 0)
return log_link_debug_errno(link, r, "Could not create netlink message: %m");
return r;
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_debug_errno(link, r, "Could not send netlink message: %m");
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool netdev_is_ready(NetDev *netdev) {
@ -511,66 +451,63 @@ static bool netdev_is_ready(NetDev *netdev) {
return true;
}
static bool link_is_ready_to_call_set_link(Request *req) {
SetLinkOperation op;
Link *link;
static int link_is_ready_to_set_link(Link *link, Request *req) {
int r;
assert(link);
assert(link->manager);
assert(link->network);
assert(req);
assert(req->link);
assert(req->link->manager);
assert(req->link->network);
link = req->link;
op = PTR_TO_INT(req->set_link_operation_ptr);
if (!IN_SET(link->state, LINK_STATE_INITIALIZED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return false;
switch (op) {
case SET_LINK_BOND:
case SET_LINK_BRIDGE:
switch (req->type) {
case REQUEST_TYPE_SET_LINK_BOND:
case REQUEST_TYPE_SET_LINK_BRIDGE:
if (!link->master_set)
return false;
if (link->network->keep_master && link->master_ifindex <= 0)
return false;
break;
case SET_LINK_BRIDGE_VLAN:
case REQUEST_TYPE_SET_LINK_BRIDGE_VLAN:
if (!link->master_set)
return false;
if (link->network->keep_master && link->master_ifindex <= 0 && !streq_ptr(link->kind, "bridge"))
return false;
break;
case SET_LINK_CAN:
case REQUEST_TYPE_SET_LINK_CAN:
/* Do not check link->set_flgas_messages here, as it is ok even if link->flags
* is outdated, and checking the counter causes a deadlock. */
if (FLAGS_SET(link->flags, IFF_UP)) {
/* The CAN interface must be down to configure bitrate, etc... */
r = link_down_now(link);
if (r < 0) {
link_enter_failed(link);
return false;
}
if (r < 0)
return r;
}
break;
case SET_LINK_MAC:
case REQUEST_TYPE_SET_LINK_MAC:
if (req->netlink_handler == link_set_mac_handler) {
/* This is the second attempt to set hardware address. On the first attempt
* req->netlink_handler points to link_set_mac_allow_retry_handler().
* The first attempt failed as the interface was up. */
r = link_down_now(link);
if (r < 0) {
link_enter_failed(link);
return false;
}
if (r < 0)
return r;
}
break;
case SET_LINK_MASTER: {
case REQUEST_TYPE_SET_LINK_MASTER: {
uint32_t m = 0;
Request req_mac = {
.link = link,
.type = REQUEST_TYPE_SET_LINK,
.set_link_operation_ptr = INT_TO_PTR(SET_LINK_MAC),
.type = REQUEST_TYPE_SET_LINK_MAC,
};
if (link->network->batadv) {
@ -589,10 +526,8 @@ static bool link_is_ready_to_call_set_link(Request *req) {
if (FLAGS_SET(link->flags, IFF_UP)) {
/* link must be down when joining to bond master. */
r = link_down_now(link);
if (r < 0) {
link_enter_failed(link);
return false;
}
if (r < 0)
return r;
}
} else if (link->network->bridge) {
if (ordered_set_contains(link->manager->request_queue, &req_mac))
@ -609,11 +544,10 @@ static bool link_is_ready_to_call_set_link(Request *req) {
req->userdata = UINT32_TO_PTR(m);
break;
}
case SET_LINK_MTU: {
case REQUEST_TYPE_SET_LINK_MTU: {
Request req_ipoib = {
.link = link,
.type = REQUEST_TYPE_SET_LINK,
.set_link_operation_ptr = INT_TO_PTR(SET_LINK_IPOIB),
.type = REQUEST_TYPE_SET_LINK_IPOIB,
};
return !ordered_set_contains(link->manager->request_queue, &req_ipoib);
@ -625,53 +559,44 @@ static bool link_is_ready_to_call_set_link(Request *req) {
return true;
}
int request_process_set_link(Request *req) {
SetLinkOperation op;
static int link_process_set_link(Request *req, Link *link, void *userdata) {
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_SET_LINK);
assert(req->netlink_handler);
assert(link);
op = PTR_TO_INT(req->set_link_operation_ptr);
r = link_is_ready_to_set_link(link, req);
if (r <= 0)
return r;
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
if (!link_is_ready_to_call_set_link(req))
return 0;
r = link_configure(req->link, op, req->userdata, req->netlink_handler);
r = link_configure(link, req);
if (r < 0)
return log_link_error_errno(req->link, r, "Failed to set %s: %m",
set_link_operation_to_string(op));
if (op == SET_LINK_FLAGS)
req->link->set_flags_messages++;
return log_link_warning_errno(link, r, "Failed to set %s", request_type_to_string(req->type));
return 1;
}
static int link_request_set_link(
Link *link,
SetLinkOperation op,
link_netlink_message_handler_t netlink_handler,
RequestType type,
request_netlink_handler_t netlink_handler,
Request **ret) {
Request *req;
int r;
assert(link);
assert(op >= 0 && op < _SET_LINK_OPERATION_MAX);
assert(netlink_handler);
r = link_queue_request(link, REQUEST_TYPE_SET_LINK, INT_TO_PTR(op), false,
&link->set_link_messages, netlink_handler, &req);
r = link_queue_request_full(link, type, NULL, NULL, NULL, NULL,
link_process_set_link,
&link->set_link_messages,
netlink_handler,
&req);
if (r < 0)
return log_link_error_errno(link, r, "Failed to request to set %s: %m",
set_link_operation_to_string(op));
return log_link_warning_errno(link, r, "Failed to request to set %s: %m",
request_type_to_string(type));
log_link_debug(link, "Requested to set %s", set_link_operation_to_string(op));
log_link_debug(link, "Requested to set %s", request_type_to_string(type));
if (ret)
*ret = req;
@ -707,7 +632,9 @@ int link_request_to_set_addrgen_mode(Link *link) {
return 0;
}
r = link_request_set_link(link, SET_LINK_ADDRESS_GENERATION_MODE, link_set_addrgen_mode_handler, &req);
r = link_request_set_link(link, REQUEST_TYPE_SET_LINK_ADDRESS_GENERATION_MODE,
link_set_addrgen_mode_handler,
&req);
if (r < 0)
return r;
@ -732,7 +659,8 @@ int link_request_to_set_bond(Link *link) {
return 0;
}
return link_request_set_link(link, SET_LINK_BOND, link_set_bond_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_BOND,
link_set_bond_handler, NULL);
}
int link_request_to_set_bridge(Link *link) {
@ -752,7 +680,9 @@ int link_request_to_set_bridge(Link *link) {
return 0;
}
return link_request_set_link(link, SET_LINK_BRIDGE, link_set_bridge_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_BRIDGE,
link_set_bridge_handler,
NULL);
}
int link_request_to_set_bridge_vlan(Link *link) {
@ -775,7 +705,9 @@ int link_request_to_set_bridge_vlan(Link *link) {
return 0;
}
return link_request_set_link(link, SET_LINK_BRIDGE_VLAN, link_set_bridge_vlan_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_BRIDGE_VLAN,
link_set_bridge_vlan_handler,
NULL);
}
int link_request_to_set_can(Link *link) {
@ -788,7 +720,9 @@ int link_request_to_set_can(Link *link) {
if (!streq_ptr(link->kind, "can"))
return 0;
return link_request_set_link(link, SET_LINK_CAN, link_set_can_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_CAN,
link_set_can_handler,
NULL);
}
int link_request_to_set_flags(Link *link) {
@ -801,7 +735,9 @@ int link_request_to_set_flags(Link *link) {
link->network->promiscuous < 0)
return 0;
return link_request_set_link(link, SET_LINK_FLAGS, link_set_flags_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_FLAGS,
link_set_flags_handler,
NULL);
}
int link_request_to_set_group(Link *link) {
@ -811,7 +747,9 @@ int link_request_to_set_group(Link *link) {
if (link->network->group < 0)
return 0;
return link_request_set_link(link, SET_LINK_GROUP, link_set_group_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_GROUP,
link_set_group_handler,
NULL);
}
int link_request_to_set_mac(Link *link, bool allow_retry) {
@ -832,7 +770,7 @@ int link_request_to_set_mac(Link *link, bool allow_retry) {
if (hw_addr_equal(&link->hw_addr, &link->requested_hw_addr))
return 0;
return link_request_set_link(link, SET_LINK_MAC,
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_MAC,
allow_retry ? link_set_mac_allow_retry_handler : link_set_mac_handler,
NULL);
}
@ -848,7 +786,9 @@ int link_request_to_set_ipoib(Link *link) {
link->network->ipoib_umcast < 0)
return 0;
return link_request_set_link(link, SET_LINK_IPOIB, link_set_ipoib_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_IPOIB,
link_set_ipoib_handler,
NULL);
}
int link_request_to_set_master(Link *link) {
@ -863,15 +803,19 @@ int link_request_to_set_master(Link *link) {
link->master_set = false;
if (link->network->batadv || link->network->bond || link->network->bridge || link->network->vrf)
return link_request_set_link(link, SET_LINK_MASTER, link_set_master_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_MASTER,
link_set_master_handler,
NULL);
else
return link_request_set_link(link, SET_LINK_MASTER, link_unset_master_handler, NULL);
return link_request_set_link(link, REQUEST_TYPE_SET_LINK_MASTER,
link_unset_master_handler,
NULL);
}
int link_request_to_set_mtu(Link *link, uint32_t mtu) {
Request *req;
const char *origin;
uint32_t min_mtu;
Request *req;
int r;
assert(link);
@ -907,7 +851,9 @@ int link_request_to_set_mtu(Link *link, uint32_t mtu) {
if (link->mtu == mtu)
return 0;
r = link_request_set_link(link, SET_LINK_MTU, link_set_mtu_handler, &req);
r = link_request_set_link(link, REQUEST_TYPE_SET_LINK_MTU,
link_set_mtu_handler,
&req);
if (r < 0)
return r;
@ -991,14 +937,16 @@ static int link_up_dsa_slave(Link *link) {
return 1;
}
static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, bool up, bool on_activate) {
static int link_up_or_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
bool on_activate, up;
int r;
assert(m);
assert(req);
assert(link);
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
goto on_error;
on_activate = req->type == REQUEST_TYPE_ACTIVATE_LINK;
up = PTR_TO_INT(req->userdata);
r = sd_netlink_message_get_errno(m);
if (r == -ENETDOWN && up && link_up_dsa_slave(link) > 0)
@ -1012,82 +960,55 @@ static int link_up_or_down_handler_internal(sd_netlink *rtnl, sd_netlink_message
log_link_message_warning_errno(link, m, r, error_msg);
if (on_activate)
goto on_error;
return 0;
}
r = link_call_getlink(link, get_link_update_flag_handler);
if (r < 0) {
link_enter_failed(link);
goto on_error;
return 0;
}
link->set_flags_messages++;
if (on_activate) {
link->activated = true;
link_check_ready(link);
}
return 1;
on_error:
assert(link->set_flags_messages > 0);
link->set_flags_messages--;
return 0;
}
static int link_activate_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ true, /* on_activate = */ true);
}
static int link_activate_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ false, /* on_activate = */ true);
}
static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ true, /* on_activate = */ false);
}
static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return link_up_or_down_handler_internal(rtnl, m, link, /* up = */ false, /* on_activate = */ false);
}
static const char *up_or_down(bool up) {
return up ? "up" : "down";
}
static int link_up_or_down(Link *link, bool up, link_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
static int link_up_or_down(Link *link, bool up, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
assert(link);
assert(link->manager);
assert(link->manager->rtnl);
assert(callback);
assert(req);
log_link_debug(link, "Bringing link %s", up_or_down(up));
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_SETLINK, link->ifindex);
if (r < 0)
return r;
r = sd_rtnl_message_link_set_flags(req, up ? IFF_UP : 0, IFF_UP);
r = sd_rtnl_message_link_set_flags(m, up ? IFF_UP : 0, IFF_UP);
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool link_is_ready_to_activate(Link *link) {
assert(link);
if (!IN_SET(link->state, LINK_STATE_INITIALIZED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return false;
if (link->set_link_messages > 0)
@ -1096,23 +1017,17 @@ static bool link_is_ready_to_activate(Link *link) {
return true;
}
int request_process_activation(Request *req) {
Link *link;
bool up;
static int link_process_activation(Request *req, Link *link, void *userdata) {
bool up = PTR_TO_INT(userdata);
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_ACTIVATE_LINK);
assert(req->netlink_handler);
link = req->link;
up = PTR_TO_INT(req->userdata);
assert(link);
if (!link_is_ready_to_activate(link))
return 0;
r = link_up_or_down(link, up, req->netlink_handler);
r = link_up_or_down(link, up, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to activate link: %m");
@ -1120,7 +1035,6 @@ int request_process_activation(Request *req) {
}
int link_request_to_activate(Link *link) {
Request *req;
bool up;
int r;
@ -1151,13 +1065,14 @@ int link_request_to_activate(Link *link) {
link->activated = false;
r = link_queue_request(link, REQUEST_TYPE_ACTIVATE_LINK, NULL, false, &link->set_flags_messages,
up ? link_activate_up_handler : link_activate_down_handler, &req);
r = link_queue_request_full(link, REQUEST_TYPE_ACTIVATE_LINK,
INT_TO_PTR(up), NULL, NULL, NULL,
link_process_activation,
&link->set_flags_messages,
link_up_or_down_handler, NULL);
if (r < 0)
return log_link_error_errno(link, r, "Failed to request to activate link: %m");
req->userdata = INT_TO_PTR(up);
log_link_debug(link, "Requested to activate link");
return 0;
}
@ -1192,22 +1107,17 @@ static bool link_is_ready_to_bring_up_or_down(Link *link, bool up) {
return true;
}
int request_process_link_up_or_down(Request *req) {
Link *link;
bool up;
static int link_process_up_or_down(Request *req, Link *link, void *userdata) {
bool up = PTR_TO_INT(userdata);
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_UP_DOWN);
link = req->link;
up = PTR_TO_INT(req->userdata);
assert(link);
if (!link_is_ready_to_bring_up_or_down(link, up))
return 0;
r = link_up_or_down(link, up, req->netlink_handler);
r = link_up_or_down(link, up, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to bring link %s: %m", up_or_down(up));
@ -1215,19 +1125,19 @@ int request_process_link_up_or_down(Request *req) {
}
int link_request_to_bring_up_or_down(Link *link, bool up) {
Request *req;
int r;
assert(link);
r = link_queue_request(link, REQUEST_TYPE_UP_DOWN, NULL, false, &link->set_flags_messages,
up ? link_up_handler : link_down_handler, &req);
r = link_queue_request_full(link, REQUEST_TYPE_UP_DOWN,
INT_TO_PTR(up), NULL, NULL, NULL,
link_process_up_or_down,
&link->set_flags_messages,
link_up_or_down_handler, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request to bring link %s: %m",
up_or_down(up));
req->userdata = INT_TO_PTR(up);
log_link_debug(link, "Requested to bring link %s", up_or_down(up));
return 0;
}

View File

@ -2,29 +2,9 @@
#pragma once
#include <inttypes.h>
#include <stdbool.h>
typedef struct Link Link;
typedef struct Request Request;
typedef enum SetLinkOperation {
SET_LINK_ADDRESS_GENERATION_MODE, /* Setting IPv6LL address generation mode. */
SET_LINK_BOND, /* Setting bond configs. */
SET_LINK_BRIDGE, /* Setting bridge configs. */
SET_LINK_BRIDGE_VLAN, /* Setting bridge VLAN configs. */
SET_LINK_CAN, /* Setting CAN interface configs. */
SET_LINK_FLAGS, /* Setting IFF_NOARP or friends. */
SET_LINK_GROUP, /* Setting interface group. */
SET_LINK_IPOIB, /* Setting IPoIB configs. */
SET_LINK_MAC, /* Setting MAC address. */
SET_LINK_MASTER, /* Setting IFLA_MASTER. */
SET_LINK_MTU, /* Setting MTU. */
_SET_LINK_OPERATION_MAX,
_SET_LINK_OPERATION_INVALID = -EINVAL,
} SetLinkOperation;
/* SetLinkOperation is casted to int, then stored in void* with INT_TO_PTR(). */
assert_cc(sizeof(SetLinkOperation) <= sizeof(void*));
assert_cc(sizeof(SetLinkOperation) <= sizeof(int));
int link_request_to_set_addrgen_mode(Link *link);
int link_request_to_set_bond(Link *link);
@ -40,12 +20,8 @@ int link_request_to_set_mtu(Link *link, uint32_t mtu);
int link_configure_mtu(Link *link);
int request_process_set_link(Request *req);
int request_process_activation(Request *req);
int link_request_to_activate(Link *link);
int request_process_link_up_or_down(Request *req);
int link_request_to_bring_up_or_down(Link *link, bool up);
int link_down_now(Link *link);

View File

@ -151,7 +151,7 @@ static const char *qdisc_get_tca_kind(const QDisc *qdisc) {
QDISC_VTABLE(qdisc)->tca_kind : qdisc->tca_kind;
}
void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
static void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
assert(qdisc);
assert(state);
@ -160,7 +160,7 @@ void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
siphash24_compress_string(qdisc_get_tca_kind(qdisc), state);
}
int qdisc_compare_func(const QDisc *a, const QDisc *b) {
static int qdisc_compare_func(const QDisc *a, const QDisc *b) {
int r;
assert(a);
@ -293,15 +293,11 @@ int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *ki
return -ENOENT;
}
static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, QDisc *qdisc) {
int r;
assert(m);
assert(link);
assert(link->tc_messages > 0);
link->tc_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -319,7 +315,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return 1;
}
static int qdisc_configure(QDisc *qdisc, Link *link) {
static int qdisc_configure(QDisc *qdisc, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -328,6 +324,7 @@ static int qdisc_configure(QDisc *qdisc, Link *link) {
assert(link->manager);
assert(link->manager->rtnl);
assert(link->ifindex > 0);
assert(req);
log_qdisc_debug(qdisc, link, "Configuring");
@ -346,12 +343,7 @@ static int qdisc_configure(QDisc *qdisc, Link *link) {
return r;
}
r = netlink_call_async(link->manager->rtnl, NULL, m, qdisc_handler, link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) {
@ -367,19 +359,17 @@ static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) {
return link_find_tclass(link, qdisc->parent, NULL) >= 0;
}
int request_process_qdisc(Request *req) {
QDisc *qdisc;
Link *link;
static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) {
int r;
assert(req);
assert_se(link = req->link);
assert_se(qdisc = req->qdisc);
assert(link);
assert(qdisc);
if (!qdisc_is_ready_to_configure(qdisc, link))
return 0;
r = qdisc_configure(qdisc, link);
r = qdisc_configure(qdisc, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure QDisc: %m");
@ -410,8 +400,14 @@ int link_request_qdisc(Link *link, QDisc *qdisc) {
existing->source = qdisc->source;
log_qdisc_debug(existing, link, "Requesting");
r = link_queue_request(link, REQUEST_TYPE_TC_QDISC, existing, false,
&link->tc_messages, NULL, NULL);
r = link_queue_request_safe(link, REQUEST_TYPE_TC_QDISC,
existing, NULL,
qdisc_hash_func,
qdisc_compare_func,
qdisc_process_request,
&link->tc_messages,
qdisc_handler,
NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request QDisc: %m");
if (r == 0)

View File

@ -8,7 +8,6 @@
typedef struct Link Link;
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef enum QDiscKind {
QDISC_KIND_BFIFO,
@ -77,12 +76,8 @@ DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(QDisc, qdisc);
QDisc* qdisc_free(QDisc *qdisc);
int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret);
void qdisc_hash_func(const QDisc *qdisc, struct siphash *state);
int qdisc_compare_func(const QDisc *a, const QDisc *b);
int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *kind, QDisc **qdisc);
int request_process_qdisc(Request *req);
int link_request_qdisc(Link *link, QDisc *qdisc);
void network_drop_invalid_qdisc(Network *network);

View File

@ -121,7 +121,7 @@ static const char *tclass_get_tca_kind(const TClass *tclass) {
TCLASS_VTABLE(tclass)->tca_kind : tclass->tca_kind;
}
void tclass_hash_func(const TClass *tclass, struct siphash *state) {
static void tclass_hash_func(const TClass *tclass, struct siphash *state) {
assert(tclass);
assert(state);
@ -130,7 +130,7 @@ void tclass_hash_func(const TClass *tclass, struct siphash *state) {
siphash24_compress_string(tclass_get_tca_kind(tclass), state);
}
int tclass_compare_func(const TClass *a, const TClass *b) {
static int tclass_compare_func(const TClass *a, const TClass *b) {
int r;
assert(a);
@ -255,15 +255,11 @@ static void log_tclass_debug(TClass *tclass, Link *link, const char *str) {
strna(tclass_get_tca_kind(tclass)));
}
static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, TClass *tclass) {
int r;
assert(m);
assert(link);
assert(link->tc_messages > 0);
link->tc_messages--;
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
return 1;
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
@ -281,7 +277,7 @@ static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
return 1;
}
static int tclass_configure(TClass *tclass, Link *link) {
static int tclass_configure(TClass *tclass, Link *link, Request *req) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
@ -290,6 +286,7 @@ static int tclass_configure(TClass *tclass, Link *link) {
assert(link->manager);
assert(link->manager->rtnl);
assert(link->ifindex > 0);
assert(req);
log_tclass_debug(tclass, link, "Configuring");
@ -308,12 +305,7 @@ static int tclass_configure(TClass *tclass, Link *link) {
return r;
}
r = netlink_call_async(link->manager->rtnl, NULL, m, tclass_handler, link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
return request_call_netlink_async(link->manager->rtnl, m, req);
}
static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) {
@ -326,19 +318,17 @@ static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) {
return link_find_qdisc(link, tclass->classid, tclass->parent, tclass_get_tca_kind(tclass), NULL) >= 0;
}
int request_process_tclass(Request *req) {
TClass *tclass;
Link *link;
static int tclass_process_request(Request *req, Link *link, TClass *tclass) {
int r;
assert(req);
assert_se(link = req->link);
assert_se(tclass = req->tclass);
assert(link);
assert(tclass);
if (!tclass_is_ready_to_configure(tclass, link))
return 0;
r = tclass_configure(tclass, link);
r = tclass_configure(tclass, link, req);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure TClass: %m");
@ -369,8 +359,14 @@ int link_request_tclass(Link *link, TClass *tclass) {
existing->source = tclass->source;
log_tclass_debug(existing, link, "Requesting");
r = link_queue_request(link, REQUEST_TYPE_TC_CLASS, existing, false,
&link->tc_messages, NULL, NULL);
r = link_queue_request_safe(link, REQUEST_TYPE_TC_CLASS,
existing, NULL,
tclass_hash_func,
tclass_compare_func,
tclass_process_request,
&link->tc_messages,
tclass_handler,
NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request TClass: %m");
if (r == 0)

View File

@ -8,7 +8,6 @@
typedef struct Link Link;
typedef struct Manager Manager;
typedef struct Network Network;
typedef struct Request Request;
typedef enum TClassKind {
TCLASS_KIND_DRR,
@ -59,12 +58,8 @@ DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(TClass, tclass);
TClass* tclass_free(TClass *tclass);
int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret);
void tclass_hash_func(const TClass *qdisc, struct siphash *state);
int tclass_compare_func(const TClass *a, const TClass *b);
int link_find_tclass(Link *link, uint32_t classid, TClass **ret);
int request_process_tclass(Request *req);
int link_request_tclass(Link *link, TClass *tclass);
void network_drop_invalid_tclass(Network *network);

View File

@ -24,7 +24,7 @@ Exec.Ephemeral, config_parse_tristate, 0, of
Exec.ProcessTwo, config_parse_pid2, 0, 0
Exec.Parameters, config_parse_strv, 0, offsetof(Settings, parameters)
Exec.Environment, config_parse_strv, 0, offsetof(Settings, environment)
Exec.User, config_parse_safe_string, 0, offsetof(Settings, user)
Exec.User, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Settings, user)
Exec.Capability, config_parse_capability, 0, offsetof(Settings, capability)
Exec.AmbientCapability, config_parse_capability, 0, offsetof(Settings, ambient_capability)
Exec.DropCapability, config_parse_capability, 0, offsetof(Settings, drop_capability)
@ -35,7 +35,7 @@ Exec.WorkingDirectory, config_parse_path, 0, of
Exec.PivotRoot, config_parse_pivot_root, 0, 0
Exec.PrivateUsers, config_parse_private_users, 0, 0
Exec.NotifyReady, config_parse_tristate, 0, offsetof(Settings, notify_ready)
Exec.SystemCallFilter, config_parse_syscall_filter, 0, 0,
Exec.SystemCallFilter, config_parse_syscall_filter, 0, 0
Exec.LimitCPU, config_parse_rlimit, RLIMIT_CPU, offsetof(Settings, rlimit)
Exec.LimitFSIZE, config_parse_rlimit, RLIMIT_FSIZE, offsetof(Settings, rlimit)
Exec.LimitDATA, config_parse_rlimit, RLIMIT_DATA, offsetof(Settings, rlimit)

View File

@ -710,31 +710,6 @@ int config_parse_syscall_filter(
}
}
int config_parse_hostname(
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) {
char **s = data;
assert(rvalue);
assert(s);
if (!hostname_is_valid(rvalue, 0)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue);
return 0;
}
return free_and_strdup_warn(s, empty_to_null(rvalue));
}
int config_parse_oom_score_adjust(
const char *unit,
const char *filename,

View File

@ -264,7 +264,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_boot);
CONFIG_PARSER_PROTOTYPE(config_parse_pid2);
CONFIG_PARSER_PROTOTYPE(config_parse_private_users);
CONFIG_PARSER_PROTOTYPE(config_parse_syscall_filter);
CONFIG_PARSER_PROTOTYPE(config_parse_hostname);
CONFIG_PARSER_PROTOTYPE(config_parse_oom_score_adjust);
CONFIG_PARSER_PROTOTYPE(config_parse_cpu_affinity);
CONFIG_PARSER_PROTOTYPE(config_parse_resolv_conf);

View File

@ -11,11 +11,14 @@
#include "conf-files.h"
#include "conf-parser.h"
#include "def.h"
#include "dns-domain.h"
#include "escape.h"
#include "ether-addr-util.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "in-addr-util.h"
#include "log.h"
#include "macro.h"
@ -873,17 +876,39 @@ int config_parse_string(
void *data,
void *userdata) {
char **s = data;
char **s = ASSERT_PTR(data);
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
*s = mfree(*s);
return 0;
}
if (FLAGS_SET(ltype, CONFIG_PARSE_STRING_SAFE) && !string_is_safe(rvalue)) {
_cleanup_free_ char *escaped = NULL;
escaped = cescape(rvalue);
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Specified string contains unsafe characters, ignoring: %s", strna(escaped));
return 0;
}
if (FLAGS_SET(ltype, CONFIG_PARSE_STRING_ASCII) && !ascii_is_valid(rvalue)) {
_cleanup_free_ char *escaped = NULL;
escaped = cescape(rvalue);
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Specified string contains invalid ASCII characters, ignoring: %s", strna(escaped));
return 0;
}
return free_and_strdup_warn(s, empty_to_null(rvalue));
}
int config_parse_safe_string(
int config_parse_dns_name(
const char *unit,
const char *filename,
unsigned line,
@ -895,19 +920,64 @@ int config_parse_safe_string(
void *data,
void *userdata) {
char **s = data;
char **hostname = ASSERT_PTR(data);
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (!string_is_safe(rvalue)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Specified string contains unsafe characters, ignoring: %s", rvalue);
if (isempty(rvalue)) {
*hostname = mfree(*hostname);
return 0;
}
return free_and_strdup_warn(s, empty_to_null(rvalue));
r = dns_name_is_valid(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to check validity of DNS domain name '%s', ignoring assignment: %m", rvalue);
return 0;
}
if (r == 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Specified invalid DNS domain name, ignoring assignment: %s", rvalue);
return 0;
}
return free_and_strdup_warn(hostname, rvalue);
}
int config_parse_hostname(
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) {
char **hostname = ASSERT_PTR(data);
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
*hostname = mfree(*hostname);
return 0;
}
if (!hostname_is_valid(rvalue, 0)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Specified invalid hostname, ignoring assignment: %s", rvalue);
return 0;
}
return config_parse_dns_name(unit, filename, line, section, section_line,
lvalue, ltype, rvalue, data, userdata);
}
int config_parse_path(

View File

@ -168,7 +168,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_bool);
CONFIG_PARSER_PROTOTYPE(config_parse_id128);
CONFIG_PARSER_PROTOTYPE(config_parse_tristate);
CONFIG_PARSER_PROTOTYPE(config_parse_string);
CONFIG_PARSER_PROTOTYPE(config_parse_safe_string);
CONFIG_PARSER_PROTOTYPE(config_parse_dns_name);
CONFIG_PARSER_PROTOTYPE(config_parse_hostname);
CONFIG_PARSER_PROTOTYPE(config_parse_path);
CONFIG_PARSER_PROTOTYPE(config_parse_strv);
CONFIG_PARSER_PROTOTYPE(config_parse_sec);
@ -203,6 +204,13 @@ typedef enum Disabled {
DISABLED_EXPERIMENTAL,
} Disabled;
typedef enum ConfigParseStringFlags {
CONFIG_PARSE_STRING_SAFE = 1 << 0,
CONFIG_PARSE_STRING_ASCII = 1 << 1,
CONFIG_PARSE_STRING_SAFE_AND_ASCII = CONFIG_PARSE_STRING_SAFE | CONFIG_PARSE_STRING_ASCII,
} ConfigParseStringFlags;
#define DEFINE_CONFIG_PARSE(function, parser, msg) \
CONFIG_PARSER_PROTOTYPE(function) { \
int *i = data, r; \

View File

@ -44,71 +44,175 @@ enum {
* The client may want to start acquiring link-local addresses. */
};
/* https://www.iana.org/assignments/bootp-dhcp-parameters/bootp-dhcp-parameters.xhtml#options */
enum {
SD_DHCP_OPTION_PAD = 0,
SD_DHCP_OPTION_SUBNET_MASK = 1,
SD_DHCP_OPTION_TIME_OFFSET = 2,
SD_DHCP_OPTION_ROUTER = 3,
SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
SD_DHCP_OPTION_LPR_SERVER = 9,
SD_DHCP_OPTION_HOST_NAME = 12,
SD_DHCP_OPTION_BOOT_FILE_SIZE = 13,
SD_DHCP_OPTION_DOMAIN_NAME = 15,
SD_DHCP_OPTION_ROOT_PATH = 17,
SD_DHCP_OPTION_ENABLE_IP_FORWARDING = 19,
SD_DHCP_OPTION_ENABLE_IP_FORWARDING_NL = 20,
SD_DHCP_OPTION_POLICY_FILTER = 21,
SD_DHCP_OPTION_INTERFACE_MDR = 22,
SD_DHCP_OPTION_INTERFACE_TTL = 23,
SD_DHCP_OPTION_INTERFACE_MTU_AGING_TIMEOUT = 24,
SD_DHCP_OPTION_INTERFACE_MTU = 26,
SD_DHCP_OPTION_BROADCAST = 28,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_ROUTER_DISCOVER = 31,
SD_DHCP_OPTION_STATIC_ROUTE = 33,
SD_DHCP_OPTION_NTP_SERVER = 42,
SD_DHCP_OPTION_VENDOR_SPECIFIC = 43,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_NETBIOS_NAMESERVER = 44,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_NETBIOS_NODETYPE = 46,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_NETBIOS_SCOPE = 47,
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50,
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51,
SD_DHCP_OPTION_OVERLOAD = 52,
SD_DHCP_OPTION_MESSAGE_TYPE = 53,
SD_DHCP_OPTION_SERVER_IDENTIFIER = 54,
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST = 55,
SD_DHCP_OPTION_ERROR_MESSAGE = 56,
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57,
SD_DHCP_OPTION_RENEWAL_T1_TIME = 58,
SD_DHCP_OPTION_REBINDING_T2_TIME = 59,
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61,
SD_DHCP_OPTION_SMTP_SERVER = 69,
SD_DHCP_OPTION_POP3_SERVER = 70,
SD_DHCP_OPTION_USER_CLASS = 77,
SD_DHCP_OPTION_FQDN = 81,
SD_DHCP_OPTION_RELAY_AGENT_INFORMATION = 82,
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
SD_DHCP_OPTION_SIP_SERVER = 120,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_MUD_URL = 161,
SD_DHCP_OPTION_PXELINUX_MAGIC = 208, /* deprecated */
SD_DHCP_OPTION_CONFIGURATION_FILE = 209,
SD_DHCP_OPTION_PATH_PREFIX = 210,
SD_DHCP_OPTION_REBOOT_TIME = 211,
SD_DHCP_OPTION_6RD = 212,
SD_DHCP_OPTION_PAD = 0, /* [RFC2132] */
SD_DHCP_OPTION_SUBNET_MASK = 1, /* [RFC2132] */
SD_DHCP_OPTION_TIME_OFFSET = 2, /* [RFC2132], deprecated by 100 and 101 */
SD_DHCP_OPTION_ROUTER = 3, /* [RFC2132] */
SD_DHCP_OPTION_TIME_SERVER = 4, /* [RFC2132] */
SD_DHCP_OPTION_NAME_SERVER = 5, /* [RFC2132] */
SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6, /* [RFC2132] */
SD_DHCP_OPTION_LOG_SERVER = 7, /* [RFC2132] */
SD_DHCP_OPTION_QUOTES_SERVER = 8, /* [RFC2132] */
SD_DHCP_OPTION_LPR_SERVER = 9, /* [RFC2132] */
SD_DHCP_OPTION_IMPRESS_SERVER = 10, /* [RFC2132] */
SD_DHCP_OPTION_RLP_SERVER = 11, /* [RFC2132] */
SD_DHCP_OPTION_HOST_NAME = 12, /* [RFC2132] */
SD_DHCP_OPTION_BOOT_FILE_SIZE = 13, /* [RFC2132] */
SD_DHCP_OPTION_MERIT_DUMP_FILE = 14, /* [RFC2132] */
SD_DHCP_OPTION_DOMAIN_NAME = 15, /* [RFC2132] */
SD_DHCP_OPTION_SWAP_SERVER = 16, /* [RFC2132] */
SD_DHCP_OPTION_ROOT_PATH = 17, /* [RFC2132] */
SD_DHCP_OPTION_EXTENSION_FILE = 18, /* [RFC2132] */
SD_DHCP_OPTION_FORWARD = 19, /* [RFC2132] */
SD_DHCP_OPTION_SOURCE_ROUTE = 20, /* [RFC2132] */
SD_DHCP_OPTION_POLICY_FILTER = 21, /* [RFC2132] */
SD_DHCP_OPTION_MAX_DATAGRAM_ASSEMBLY = 22, /* [RFC2132] */
SD_DHCP_OPTION_DEFAULT_IP_TTL = 23, /* [RFC2132] */
SD_DHCP_OPTION_MTU_TIMEOUT = 24, /* [RFC2132] */
SD_DHCP_OPTION_MTU_PLATEAU = 25, /* [RFC2132] */
SD_DHCP_OPTION_MTU_INTERFACE = 26, /* [RFC2132] */
SD_DHCP_OPTION_MTU_SUBNET = 27, /* [RFC2132] */
SD_DHCP_OPTION_BROADCAST = 28, /* [RFC2132] */
SD_DHCP_OPTION_MASK_DISCOVERY = 29, /* [RFC2132] */
SD_DHCP_OPTION_MASK_SUPPLIER = 30, /* [RFC2132] */
SD_DHCP_OPTION_ROUTER_DISCOVERY = 31, /* [RFC2132] */
SD_DHCP_OPTION_ROUTER_REQUEST = 32, /* [RFC2132] */
SD_DHCP_OPTION_STATIC_ROUTE = 33, /* [RFC2132] */
SD_DHCP_OPTION_TRAILERS = 34, /* [RFC2132] */
SD_DHCP_OPTION_ARP_TIMEOUT = 35, /* [RFC2132] */
SD_DHCP_OPTION_ETHERNET = 36, /* [RFC2132] */
SD_DHCP_OPTION_DEFAULT_TCP_TTL = 37, /* [RFC2132] */
SD_DHCP_OPTION_KEEPALIVE_TIME = 38, /* [RFC2132] */
SD_DHCP_OPTION_KEEPALIVE_DATA = 39, /* [RFC2132] */
SD_DHCP_OPTION_NIS_DOMAIN = 40, /* [RFC2132] */
SD_DHCP_OPTION_NIS_SERVER = 41, /* [RFC2132] */
SD_DHCP_OPTION_NTP_SERVER = 42, /* [RFC2132] */
SD_DHCP_OPTION_VENDOR_SPECIFIC = 43, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_NAME_SERVER = 44, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_DIST_SERVER = 45, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_NODE_TYPE = 46, /* [RFC2132] */
SD_DHCP_OPTION_NETBIOS_SCOPE = 47, /* [RFC2132] */
SD_DHCP_OPTION_X_WINDOW_FONT = 48, /* [RFC2132] */
SD_DHCP_OPTION_X_WINDOW_MANAGER = 49, /* [RFC2132] */
SD_DHCP_OPTION_REQUESTED_IP_ADDRESS = 50, /* [RFC2132] */
SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME = 51, /* [RFC2132] */
SD_DHCP_OPTION_OVERLOAD = 52, /* [RFC2132] */
SD_DHCP_OPTION_MESSAGE_TYPE = 53, /* [RFC2132] */
SD_DHCP_OPTION_SERVER_IDENTIFIER = 54, /* [RFC2132] */
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST = 55, /* [RFC2132] */
SD_DHCP_OPTION_ERROR_MESSAGE = 56, /* [RFC2132] */
SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE = 57, /* [RFC2132] */
SD_DHCP_OPTION_RENEWAL_TIME = 58, /* [RFC2132] */
SD_DHCP_OPTION_REBINDING_TIME = 59, /* [RFC2132] */
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, /* [RFC2132] */
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61, /* [RFC2132] */
SD_DHCP_OPTION_NETWARE_IP_DOMAIN = 62, /* [RFC2242] */
SD_DHCP_OPTION_NETWARE_IP_OPTION = 63, /* [RFC2242] */
SD_DHCP_OPTION_NIS_DOMAIN_NAME = 64, /* [RFC2132] */
SD_DHCP_OPTION_NIS_SERVER_ADDR = 65, /* [RFC2132] */
SD_DHCP_OPTION_BOOT_SERVER_NAME = 66, /* [RFC2132] */
SD_DHCP_OPTION_BOOT_FILENAME = 67, /* [RFC2132] */
SD_DHCP_OPTION_HOME_AGENT_ADDRESSES = 68, /* [RFC2132] */
SD_DHCP_OPTION_SMTP_SERVER = 69, /* [RFC2132] */
SD_DHCP_OPTION_POP3_SERVER = 70, /* [RFC2132] */
SD_DHCP_OPTION_NNTP_SERVER = 71, /* [RFC2132] */
SD_DHCP_OPTION_WWW_SERVER = 72, /* [RFC2132] */
SD_DHCP_OPTION_FINGER_SERVER = 73, /* [RFC2132] */
SD_DHCP_OPTION_IRC_SERVER = 74, /* [RFC2132] */
SD_DHCP_OPTION_STREETTALK_SERVER = 75, /* [RFC2132] */
SD_DHCP_OPTION_STDA_SERVER = 76, /* [RFC2132] */
SD_DHCP_OPTION_USER_CLASS = 77, /* [RFC3004] */
SD_DHCP_OPTION_DIRECTORY_AGENT = 78, /* [RFC2610] */
SD_DHCP_OPTION_SERVICE_SCOPE = 79, /* [RFC2610] */
SD_DHCP_OPTION_RAPID_COMMIT = 80, /* [RFC4039] */
SD_DHCP_OPTION_FQDN = 81, /* [RFC4702] */
SD_DHCP_OPTION_RELAY_AGENT_INFORMATION = 82, /* [RFC3046] */
SD_DHCP_OPTION_ISNS = 83, /* [RFC4174] */
/* option code 84 is unassigned [RFC3679] */
SD_DHCP_OPTION_NDS_SERVER = 85, /* [RFC2241] */
SD_DHCP_OPTION_NDS_TREE_NAME = 86, /* [RFC2241] */
SD_DHCP_OPTION_NDS_CONTEXT = 87, /* [RFC2241] */
SD_DHCP_OPTION_BCMCS_CONTROLLER_DOMAIN_NAM = 88, /* [RFC4280] */
SD_DHCP_OPTION_BCMCS_CONTROLLER_ADDRESS = 89, /* [RFC4280] */
SD_DHCP_OPTION_AUTHENTICATION = 90, /* [RFC3118] */
SD_DHCP_OPTION_CLIENT_LAST_TRANSACTION_TIME = 91, /* [RFC4388] */
SD_DHCP_OPTION_ASSOCIATED_IP = 92, /* [RFC4388] */
SD_DHCP_OPTION_CLIENT_SYSTEM = 93, /* [RFC4578] */
SD_DHCP_OPTION_CLIENT_NDI = 94, /* [RFC4578] */
SD_DHCP_OPTION_LDAP = 95, /* [RFC3679] */
/* option code 96 is unassigned [RFC3679] */
SD_DHCP_OPTION_UUID = 97, /* [RFC4578] */
SD_DHCP_OPTION_USER_AUTHENTICATION = 98, /* [RFC2485] */
SD_DHCP_OPTION_GEOCONF_CIVIC = 99, /* [RFC4776] */
SD_DHCP_OPTION_POSIX_TIMEZONE = 100, /* [RFC4833] */
SD_DHCP_OPTION_TZDB_TIMEZONE = 101, /* [RFC4833] */
/* option codes 102-107 are unassigned [RFC3679] */
SD_DHCP_OPTION_IPV6_ONLY_PREFERRED = 108, /* [RFC8925] */
SD_DHCP_OPTION_DHCP4O6_SOURCE_ADDRESS = 109, /* [RFC8539] */
/* option codes 110-111 are unassigned [RFC3679] */
SD_DHCP_OPTION_NETINFO_ADDRESS = 112, /* [RFC3679] */
SD_DHCP_OPTION_NETINFO_TAG = 113, /* [RFC3679] */
SD_DHCP_OPTION_DHCP_CAPTIVE_PORTAL = 114, /* [RFC8910] */
/* option code 115 is unassigned [RFC3679] */
SD_DHCP_OPTION_AUTO_CONFIG = 116, /* [RFC2563] */
SD_DHCP_OPTION_NAME_SERVICE_SEARCH = 117, /* [RFC2937] */
SD_DHCP_OPTION_SUBNET_SELECTION = 118, /* [RFC3011] */
SD_DHCP_OPTION_DOMAIN_SEARCH = 119, /* [RFC3397] */
SD_DHCP_OPTION_SIP_SERVER = 120, /* [RFC3361] */
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, /* [RFC3442] */
SD_DHCP_OPTION_CABLELABS_CLIENT_CONFIGURATION = 122, /* [RFC3495] */
SD_DHCP_OPTION_GEOCONF = 123, /* [RFC6225] */
SD_DHCP_OPTION_VENDOR_CLASS = 124, /* [RFC3925] */
SD_DHCP_OPTION_VENDOR_SPECIFIC_INFORMATION = 125, /* [RFC3925] */
/* option codes 126-127 are unassigned [RFC3679] */
/* option codes 128-135 are assigned to use by PXE, but they are vendor specific [RFC4578] */
SD_DHCP_OPTION_PANA_AGENT = 136, /* [RFC5192] */
SD_DHCP_OPTION_LOST_SERVER_FQDN = 137, /* [RFC5223] */
SD_DHCP_OPTION_CAPWAP_AC_ADDRESS = 138, /* [RFC5417] */
SD_DHCP_OPTION_MOS_ADDRESS = 139, /* [RFC5678] */
SD_DHCP_OPTION_MOS_FQDN = 140, /* [RFC5678] */
SD_DHCP_OPTION_SIP_SERVICE_DOMAINS = 141, /* [RFC6011] */
SD_DHCP_OPTION_ANDSF_ADDRESS = 142, /* [RFC6153] */
SD_DHCP_OPTION_SZTP_REDIRECT = 143, /* [RFC8572] */
SD_DHCP_OPTION_GEOLOC = 144, /* [RFC6225] */
SD_DHCP_OPTION_FORCERENEW_NONCE_CAPABLE = 145, /* [RFC6704] */
SD_DHCP_OPTION_RDNSS_SELECTION = 146, /* [RFC6731] */
SD_DHCP_OPTION_DOTS_RI = 147, /* [RFC8973] */
SD_DHCP_OPTION_DOTS_ADDRESS = 148, /* [RFC8973] */
/* option code 149 is unassigned [RFC3942] */
SD_DHCP_OPTION_TFTP_SERVER_ADDRESS = 150, /* [RFC5859] */
SD_DHCP_OPTION_STATUS_CODE = 151, /* [RFC6926] */
SD_DHCP_OPTION_BASE_TIME = 152, /* [RFC6926] */
SD_DHCP_OPTION_START_TIME_OF_STATE = 153, /* [RFC6926] */
SD_DHCP_OPTION_QUERY_START_TIME = 154, /* [RFC6926] */
SD_DHCP_OPTION_QUERY_END_TIME = 155, /* [RFC6926] */
SD_DHCP_OPTION_DHCP_STATE = 156, /* [RFC6926] */
SD_DHCP_OPTION_DATA_SOURCE = 157, /* [RFC6926] */
SD_DHCP_OPTION_PCP_SERVER = 158, /* [RFC7291] */
SD_DHCP_OPTION_PORT_PARAMS = 159, /* [RFC7618] */
/* option code 160 is unassigned [RFC7710][RFC8910] */
SD_DHCP_OPTION_MUD_URL = 161, /* [RFC8520] */
/* option codes 162-174 are unassigned [RFC3942] */
/* option codes 175-177 are temporary assigned. */
/* option codes 178-207 are unassigned [RFC3942] */
SD_DHCP_OPTION_PXELINUX_MAGIC = 208, /* [RFC5071] Deprecated */
SD_DHCP_OPTION_CONFIGURATION_FILE = 209, /* [RFC5071] */
SD_DHCP_OPTION_PATH_PREFIX = 210, /* [RFC5071] */
SD_DHCP_OPTION_REBOOT_TIME = 211, /* [RFC5071] */
SD_DHCP_OPTION_6RD = 212, /* [RFC5969] */
SD_DHCP_OPTION_ACCESS_DOMAIN = 213, /* [RFC5986] */
/* option codes 214-219 are unassigned */
SD_DHCP_OPTION_SUBNET_ALLOCATION = 220, /* [RFC6656] */
SD_DHCP_OPTION_VIRTUAL_SUBNET_SELECTION = 221, /* [RFC6607] */
/* option codes 222-223 are unassigned [RFC3942] */
/* option codes 224-254 are reserved for private use */
SD_DHCP_OPTION_PRIVATE_BASE = 224,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252,
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249, /* [RFC7844] */
SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY = 252, /* [RFC7844] */
SD_DHCP_OPTION_PRIVATE_LAST = 254,
SD_DHCP_OPTION_END = 255,
SD_DHCP_OPTION_END = 255, /* [RFC2132] */
};
/* Suboptions for SD_DHCP_OPTION_RELAY_AGENT_INFORMATION option */

View File

@ -58,8 +58,9 @@ int sd_dhcp_server_stop(sd_dhcp_server *server);
int sd_dhcp_server_configure_pool(sd_dhcp_server *server, const struct in_addr *address, unsigned char prefixlen, uint32_t offset, uint32_t size);
int sd_dhcp_server_set_next_server(sd_dhcp_server *server, const struct in_addr *next_server);
int sd_dhcp_server_set_filename(sd_dhcp_server *server, const char *filename);
int sd_dhcp_server_set_boot_server_address(sd_dhcp_server *server, const struct in_addr *address);
int sd_dhcp_server_set_boot_server_name(sd_dhcp_server *server, const char *name);
int sd_dhcp_server_set_boot_filename(sd_dhcp_server *server, const char *filename);
int sd_dhcp_server_set_bind_to_interface(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
int sd_dhcp_server_set_router(sd_dhcp_server *server, const struct in_addr *address);

View File

@ -81,8 +81,8 @@ enum {
SD_DHCP6_OPTION_SUBSCRIBER_ID = 38, /* RFC 4580 */
SD_DHCP6_OPTION_CLIENT_FQDN = 39, /* RFC 4704 */
SD_DHCP6_OPTION_PANA_AGENT = 40, /* RFC 5192 */
SD_DHCP6_OPTION_NEW_POSIX_TIMEZONE = 41, /* RFC 4833 */
SD_DHCP6_OPTION_NEW_TZDB_TIMEZONE = 42, /* RFC 4833 */
SD_DHCP6_OPTION_POSIX_TIMEZONE = 41, /* RFC 4833 */
SD_DHCP6_OPTION_TZDB_TIMEZONE = 42, /* RFC 4833 */
SD_DHCP6_OPTION_ERO = 43, /* RFC 4994 */
SD_DHCP6_OPTION_LQ_QUERY = 44, /* RFC 5007 */
SD_DHCP6_OPTION_CLIENT_DATA = 45, /* RFC 5007 */

View File

@ -177,7 +177,7 @@ static int process_one_password_file(const char *filename) {
pid_t pid = 0;
const ConfigTableItem items[] = {
{ "Ask", "Socket", config_parse_safe_string, 0, &socket_name },
{ "Ask", "Socket", config_parse_string, CONFIG_PARSE_STRING_SAFE, &socket_name },
{ "Ask", "NotAfter", config_parse_uint64, 0, &not_after },
{ "Ask", "Message", config_parse_string, 0, &message },
{ "Ask", "PID", config_parse_pid, 0, &pid },

View File

@ -409,8 +409,9 @@ RelayAgentCircuitId=
RelayAgentRemoteId=
ServerAddress=
UplinkInterface=
NextServer=
Filename=
BootServerAddress=
BootServerName=
BootFilename=
[DHCPServerStaticLease]
MACAddress=
Address=