mirror of
https://github.com/systemd/systemd
synced 2025-10-01 17:54:45 +02:00
Compare commits
10 Commits
fa98c99ea7
...
27edd36eaa
Author | SHA1 | Date | |
---|---|---|---|
![]() |
27edd36eaa | ||
![]() |
aa3069977e | ||
![]() |
045db4fa0d | ||
![]() |
832583ada8 | ||
![]() |
7f37ecf7e5 | ||
![]() |
6c41cf4459 | ||
![]() |
cee0f719d8 | ||
![]() |
e918b3c12a | ||
![]() |
324e342219 | ||
![]() |
69e244e321 |
5
NEWS
5
NEWS
@ -123,8 +123,9 @@ CHANGES WITH 248:
|
|||||||
|
|
||||||
systemctl --user -M lennart@ start quux
|
systemctl --user -M lennart@ start quux
|
||||||
|
|
||||||
* sd-bus also gained a convenience function sd_bus_reply() to call
|
* sd-bus also gained a convenience function sd_bus_message_send() to
|
||||||
sd_bus_send() with an existing reply message.
|
simplify invocations of sd_bus_send(), taking only a single
|
||||||
|
parameter: the message to send.
|
||||||
|
|
||||||
* sd-event allows rate limits to be set on event sources, for dealing
|
* sd-event allows rate limits to be set on event sources, for dealing
|
||||||
with high-priority event sources that might starve out others. See
|
with high-priority event sources that might starve out others. See
|
||||||
|
@ -405,17 +405,14 @@ manpages = [
|
|||||||
'sd_bus_reply_method_errorf',
|
'sd_bus_reply_method_errorf',
|
||||||
'sd_bus_reply_method_errorfv'],
|
'sd_bus_reply_method_errorfv'],
|
||||||
''],
|
''],
|
||||||
['sd_bus_reply_method_return',
|
['sd_bus_reply_method_return', '3', ['sd_bus_reply_method_returnv'], ''],
|
||||||
'3',
|
|
||||||
['sd_bus_reply', 'sd_bus_reply_method_returnv'],
|
|
||||||
''],
|
|
||||||
['sd_bus_request_name',
|
['sd_bus_request_name',
|
||||||
'3',
|
'3',
|
||||||
['sd_bus_release_name',
|
['sd_bus_release_name',
|
||||||
'sd_bus_release_name_async',
|
'sd_bus_release_name_async',
|
||||||
'sd_bus_request_name_async'],
|
'sd_bus_request_name_async'],
|
||||||
''],
|
''],
|
||||||
['sd_bus_send', '3', ['sd_bus_send_to'], ''],
|
['sd_bus_send', '3', ['sd_bus_message_send', 'sd_bus_send_to'], ''],
|
||||||
['sd_bus_set_address', '3', ['sd_bus_get_address', 'sd_bus_set_exec'], ''],
|
['sd_bus_set_address', '3', ['sd_bus_get_address', 'sd_bus_set_exec'], ''],
|
||||||
['sd_bus_set_close_on_exit', '3', ['sd_bus_get_close_on_exit'], ''],
|
['sd_bus_set_close_on_exit', '3', ['sd_bus_get_close_on_exit'], ''],
|
||||||
['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''],
|
['sd_bus_set_connected_signal', '3', ['sd_bus_get_connected_signal'], ''],
|
||||||
|
@ -54,9 +54,9 @@
|
|||||||
<citerefentry><refentrytitle>sd_bus_call_method</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_call_method</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_call_method_async</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_call_method_async</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_can_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_can_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_creds_get_pid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_creds_get_pid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_creds_new_from_pid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_creds_new_from_pid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_close</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry><refentrytitle>sd_bus_default</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_default</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_emit_interfaces_added</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_emit_interfaces_added</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_emit_interfaces_added_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_emit_interfaces_added_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
@ -83,19 +83,19 @@
|
|||||||
<citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_n_queued_read</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_n_queued_read</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_name_machine_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry><refentrytitle>sd_bus_get_name_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_name_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_get_name_machine_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_owner_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_owner_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_property</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_property</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_property_trivial</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry><refentrytitle>sd_bus_get_property_string</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_property_string</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_property_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_property_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_get_property_trivial</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_scope</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_scope</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_tid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_tid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_get_unique_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_get_unique_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_interface_name_is_valid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_interface_name_is_valid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_is_monitor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry><refentrytitle>sd_bus_is_bus_client</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_is_bus_client</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_is_monitor</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_is_server</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_is_server</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_list_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_list_names</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
@ -128,12 +128,13 @@
|
|||||||
<citerefentry><refentrytitle>sd_bus_message_read_array</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_read_array</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_read_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_read_basic</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_read_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_read_strv</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_message_reply</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_rewind</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_rewind</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_seal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_seal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_set_allow_interactive_authorization</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_set_allow_interactive_authorization</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry><refentrytitle>sd_bus_message_set_expect_reply</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_set_expect_reply</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_bus_message_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_skip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_skip</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_message_verify_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_message_verify_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_negotiate_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_negotiate_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
@ -142,9 +143,8 @@
|
|||||||
<citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_query_sender_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_query_sender_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_query_sender_privilege</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_query_sender_privilege</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry><refentrytitle>sd_bus_reply_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_reply_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_reply</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_request_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_request_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_bus_send_to</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_bus_send_to</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>sd_bus_reply_method_return</refname>
|
<refname>sd_bus_reply_method_return</refname>
|
||||||
<refname>sd_bus_reply_method_returnv</refname>
|
<refname>sd_bus_reply_method_returnv</refname>
|
||||||
<refname>sd_bus_reply</refname>
|
|
||||||
|
|
||||||
<refpurpose>Reply to a D-Bus method call</refpurpose>
|
<refpurpose>Reply to a D-Bus method call</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
@ -41,12 +40,6 @@
|
|||||||
<paramdef>const char *<parameter>types</parameter></paramdef>
|
<paramdef>const char *<parameter>types</parameter></paramdef>
|
||||||
<paramdef>va_list <parameter>ap</parameter></paramdef>
|
<paramdef>va_list <parameter>ap</parameter></paramdef>
|
||||||
</funcprototype>
|
</funcprototype>
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int sd_bus_reply</funcdef>
|
|
||||||
<paramdef>const sd_bus_message *<parameter>call</parameter></paramdef>
|
|
||||||
<paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
</funcsynopsis>
|
</funcsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -59,12 +52,6 @@
|
|||||||
<citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
<citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||||
If no reply is expected to <parameter>call</parameter>, this function succeeds without sending a
|
If no reply is expected to <parameter>call</parameter>, this function succeeds without sending a
|
||||||
reply.</para>
|
reply.</para>
|
||||||
|
|
||||||
<para><function>sd_bus_reply()</function> takes a complete bus message object created with either
|
|
||||||
<citerefentry><refentrytitle>sd_bus_message_new_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
|
||||||
or
|
|
||||||
<citerefentry><refentrytitle>sd_bus_message_new_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
|
||||||
and sends it as a reply to the <parameter>call</parameter> message.</para>
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>sd_bus_send</refname>
|
<refname>sd_bus_send</refname>
|
||||||
<refname>sd_bus_send_to</refname>
|
<refname>sd_bus_send_to</refname>
|
||||||
|
<refname>sd_bus_message_send</refname>
|
||||||
|
|
||||||
<refpurpose>Queue a D-Bus message for transfer</refpurpose>
|
<refpurpose>Queue a D-Bus message for transfer</refpurpose>
|
||||||
</refnamediv>
|
</refnamediv>
|
||||||
@ -41,6 +42,11 @@
|
|||||||
<paramdef>const char *<parameter>destination</parameter></paramdef>
|
<paramdef>const char *<parameter>destination</parameter></paramdef>
|
||||||
<paramdef>uint64_t *<parameter>cookie</parameter></paramdef>
|
<paramdef>uint64_t *<parameter>cookie</parameter></paramdef>
|
||||||
</funcprototype>
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int sd_bus_message_send</funcdef>
|
||||||
|
<paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
</funcsynopsis>
|
</funcsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -76,6 +82,10 @@
|
|||||||
call fails.
|
call fails.
|
||||||
<citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry> should
|
<citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry> should
|
||||||
be invoked to write out any queued message data to the transport.</para>
|
be invoked to write out any queued message data to the transport.</para>
|
||||||
|
|
||||||
|
<para><function>sd_bus_message_send()</function> is the same as <function>sd_bus_send()</function> but
|
||||||
|
without the first and last argument. It's equivalent to
|
||||||
|
<function>sd_bus_message_send(sd_bus_message_get_bus(m), m, NULL)</function>.</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -1044,12 +1044,12 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Broadcast=</varname></term>
|
<term><varname>Broadcast=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The broadcast address, which must be in the format
|
<para>Takes an IPv4 address or boolean value. The address must be in the format described in
|
||||||
described in
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
<citerefentry project='man-pages'><refentrytitle>inet_pton</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||||
This key only applies to IPv4 addresses. If it is not
|
If set to true, then the IPv4 broadcast address will be derived from the
|
||||||
given, it is derived from the <varname>Address=</varname>
|
<varname>Address=</varname> setting. If set to false, then the broadcast address will not
|
||||||
key.</para>
|
be set. Defaults to true, except for wireguard interfaces, where it default to false.
|
||||||
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -1554,6 +1554,13 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
times. If an empty string is assigned, then the all previous assignments are cleared.</para>
|
times. If an empty string is assigned, then the all previous assignments are cleared.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>NextHop=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Specifies the nexthop id. Takes an unsigned integer in the range 1…4294967295.
|
||||||
|
If set, the corresponding [NextHop] section must be configured. Defaults to unset.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -740,7 +740,7 @@ global:
|
|||||||
LIBSYSTEMD_248 {
|
LIBSYSTEMD_248 {
|
||||||
global:
|
global:
|
||||||
sd_bus_open_user_machine;
|
sd_bus_open_user_machine;
|
||||||
sd_bus_reply;
|
sd_bus_message_send;
|
||||||
|
|
||||||
sd_event_source_set_ratelimit;
|
sd_event_source_set_ratelimit;
|
||||||
sd_event_source_get_ratelimit;
|
sd_event_source_get_ratelimit;
|
||||||
|
@ -9,6 +9,14 @@
|
|||||||
#include "bus-type.h"
|
#include "bus-type.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
|
||||||
|
_public_ int sd_bus_message_send(sd_bus_message *reply) {
|
||||||
|
assert_return(reply, -EINVAL);
|
||||||
|
assert_return(reply->bus, -EINVAL);
|
||||||
|
assert_return(!bus_pid_changed(reply->bus), -ECHILD);
|
||||||
|
|
||||||
|
return sd_bus_send(reply->bus, reply, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
_public_ int sd_bus_emit_signalv(
|
_public_ int sd_bus_emit_signalv(
|
||||||
sd_bus *bus,
|
sd_bus *bus,
|
||||||
const char *path,
|
const char *path,
|
||||||
@ -198,7 +206,7 @@ _public_ int sd_bus_reply_method_returnv(
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sd_bus_reply(call, m);
|
return sd_bus_message_send(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_bus_reply_method_return(
|
_public_ int sd_bus_reply_method_return(
|
||||||
@ -239,7 +247,7 @@ _public_ int sd_bus_reply_method_error(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return sd_bus_reply(call, m);
|
return sd_bus_message_send(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_bus_reply_method_errorfv(
|
_public_ int sd_bus_reply_method_errorfv(
|
||||||
|
@ -2604,20 +2604,6 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_bus_reply(const sd_bus_message *call, sd_bus_message *reply) {
|
|
||||||
assert_return(call, -EINVAL);
|
|
||||||
assert_return(call->sealed, -EPERM);
|
|
||||||
assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
|
|
||||||
assert_return(call->bus, -EINVAL);
|
|
||||||
assert_return(!bus_pid_changed(call->bus), -ECHILD);
|
|
||||||
assert_return(reply, -EINVAL);
|
|
||||||
assert_return(
|
|
||||||
IN_SET(reply->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR),
|
|
||||||
-EINVAL);
|
|
||||||
|
|
||||||
return sd_bus_send(call->bus, reply, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int process_timeout(sd_bus *bus) {
|
static int process_timeout(sd_bus *bus) {
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
|
_cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
|
||||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
|
_cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
|
||||||
|
@ -57,6 +57,7 @@ int address_new(Address **ret) {
|
|||||||
.scope = RT_SCOPE_UNIVERSE,
|
.scope = RT_SCOPE_UNIVERSE,
|
||||||
.cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME,
|
.cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME,
|
||||||
.cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME,
|
.cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME,
|
||||||
|
.set_broadcast = -1,
|
||||||
.duplicate_address_detection = ADDRESS_FAMILY_IPV6,
|
.duplicate_address_detection = ADDRESS_FAMILY_IPV6,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,6 +154,20 @@ static bool address_may_have_broadcast(const Address *a) {
|
|||||||
a->prefixlen <= 30;
|
a->prefixlen <= 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool address_may_set_broadcast(const Address *a, const Link *link) {
|
||||||
|
assert(a);
|
||||||
|
assert(link);
|
||||||
|
|
||||||
|
if (!address_may_have_broadcast(a))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (a->set_broadcast >= 0)
|
||||||
|
return a->set_broadcast;
|
||||||
|
|
||||||
|
/* Typical configuration for wireguard does not set broadcast. */
|
||||||
|
return !streq_ptr(link->kind, "wireguard");
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t address_prefix(const Address *a) {
|
static uint32_t address_prefix(const Address *a) {
|
||||||
assert(a);
|
assert(a);
|
||||||
|
|
||||||
@ -887,7 +902,7 @@ int address_configure(
|
|||||||
r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
|
r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
|
return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
|
||||||
} else if (address_may_have_broadcast(address)) {
|
} else if (address_may_set_broadcast(address, link)) {
|
||||||
r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
|
r = sd_netlink_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append IFA_BROADCAST attribute: %m");
|
return log_link_error_errno(link, r, "Could not append IFA_BROADCAST attribute: %m");
|
||||||
@ -1467,6 +1482,25 @@ int config_parse_broadcast(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
/* The broadcast address will be calculated based on Address=, and set if the link is
|
||||||
|
* not a wireguard interface. Here, we do not check or set n->family. */
|
||||||
|
n->broadcast = (struct in_addr) {};
|
||||||
|
n->set_broadcast = -1;
|
||||||
|
TAKE_PTR(n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = parse_boolean(rvalue);
|
||||||
|
if (r >= 0) {
|
||||||
|
/* The broadcast address will be calculated based on Address=. Here, we do not check or
|
||||||
|
* set n->family. */
|
||||||
|
n->broadcast = (struct in_addr) {};
|
||||||
|
n->set_broadcast = r;
|
||||||
|
TAKE_PTR(n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (n->family == AF_INET6) {
|
if (n->family == AF_INET6) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
"Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
|
"Broadcast is not valid for IPv6 addresses, ignoring assignment: %s", rvalue);
|
||||||
@ -1479,8 +1513,14 @@ int config_parse_broadcast(
|
|||||||
"Broadcast is invalid, ignoring assignment: %s", rvalue);
|
"Broadcast is invalid, ignoring assignment: %s", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (in4_addr_is_null(&u.in)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Broadcast cannot be ANY address, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
n->broadcast = u.in;
|
n->broadcast = u.in;
|
||||||
|
n->set_broadcast = true;
|
||||||
n->family = AF_INET;
|
n->family = AF_INET;
|
||||||
TAKE_PTR(n);
|
TAKE_PTR(n);
|
||||||
|
|
||||||
@ -1835,7 +1875,7 @@ static int address_section_verify(Address *address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (address_may_have_broadcast(address)) {
|
if (address_may_have_broadcast(address)) {
|
||||||
if (address->broadcast.s_addr == 0)
|
if (address->broadcast.s_addr == 0 && address->set_broadcast != 0)
|
||||||
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(0xfffffffflu >> address->prefixlen);
|
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(0xfffffffflu >> address->prefixlen);
|
||||||
} else if (address->broadcast.s_addr != 0) {
|
} else if (address->broadcast.s_addr != 0) {
|
||||||
log_warning("%s: broadcast address is set for IPv6 address or IPv4 address with prefixlength larger than 30. "
|
log_warning("%s: broadcast address is set for IPv6 address or IPv4 address with prefixlength larger than 30. "
|
||||||
|
@ -30,6 +30,7 @@ typedef struct Address {
|
|||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
char *label;
|
char *label;
|
||||||
|
|
||||||
|
int set_broadcast;
|
||||||
struct in_addr broadcast;
|
struct in_addr broadcast;
|
||||||
struct ifa_cacheinfo cinfo;
|
struct ifa_cacheinfo cinfo;
|
||||||
|
|
||||||
|
@ -894,6 +894,8 @@ Manager* manager_free(Manager *m) {
|
|||||||
m->routes = set_free(m->routes);
|
m->routes = set_free(m->routes);
|
||||||
m->routes_foreign = set_free(m->routes_foreign);
|
m->routes_foreign = set_free(m->routes_foreign);
|
||||||
|
|
||||||
|
m->nexthops_by_id = hashmap_free(m->nexthops_by_id);
|
||||||
|
|
||||||
sd_event_source_unref(m->speed_meter_event_source);
|
sd_event_source_unref(m->speed_meter_event_source);
|
||||||
sd_event_unref(m->event);
|
sd_event_unref(m->event);
|
||||||
|
|
||||||
|
@ -61,6 +61,9 @@ struct Manager {
|
|||||||
Set *rules;
|
Set *rules;
|
||||||
Set *rules_foreign;
|
Set *rules_foreign;
|
||||||
|
|
||||||
|
/* Manage nexthops by id. */
|
||||||
|
Hashmap *nexthops_by_id;
|
||||||
|
|
||||||
/* Manager stores routes without RTA_OIF attribute. */
|
/* Manager stores routes without RTA_OIF attribute. */
|
||||||
Set *routes;
|
Set *routes;
|
||||||
Set *routes_foreign;
|
Set *routes_foreign;
|
||||||
|
@ -185,6 +185,7 @@ Route.QuickAck, config_parse_route_boolean,
|
|||||||
Route.FastOpenNoCookie, config_parse_route_boolean, 0, 0
|
Route.FastOpenNoCookie, config_parse_route_boolean, 0, 0
|
||||||
Route.TTLPropagate, config_parse_route_boolean, 0, 0
|
Route.TTLPropagate, config_parse_route_boolean, 0, 0
|
||||||
Route.MultiPathRoute, config_parse_multipath_route, 0, 0
|
Route.MultiPathRoute, config_parse_multipath_route, 0, 0
|
||||||
|
Route.NextHop, config_parse_route_nexthop, 0, 0
|
||||||
NextHop.Id, config_parse_nexthop_id, 0, 0
|
NextHop.Id, config_parse_nexthop_id, 0, 0
|
||||||
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
||||||
NextHop.Family, config_parse_nexthop_family, 0, 0
|
NextHop.Family, config_parse_nexthop_family, 0, 0
|
||||||
|
@ -28,6 +28,9 @@ NextHop *nexthop_free(NextHop *nexthop) {
|
|||||||
if (nexthop->link) {
|
if (nexthop->link) {
|
||||||
set_remove(nexthop->link->nexthops, nexthop);
|
set_remove(nexthop->link->nexthops, nexthop);
|
||||||
set_remove(nexthop->link->nexthops_foreign, nexthop);
|
set_remove(nexthop->link->nexthops_foreign, nexthop);
|
||||||
|
|
||||||
|
if (nexthop->link->manager && nexthop->id > 0)
|
||||||
|
hashmap_remove(nexthop->link->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mfree(nexthop);
|
return mfree(nexthop);
|
||||||
@ -129,6 +132,23 @@ DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|||||||
nexthop_compare_func,
|
nexthop_compare_func,
|
||||||
nexthop_free);
|
nexthop_free);
|
||||||
|
|
||||||
|
int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret) {
|
||||||
|
NextHop *nh;
|
||||||
|
|
||||||
|
assert(manager);
|
||||||
|
|
||||||
|
if (id == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
nh = hashmap_get(manager->nexthops_by_id, UINT32_TO_PTR(id));
|
||||||
|
if (!nh)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*ret = nh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int nexthop_get(Link *link, const NextHop *in, NextHop **ret) {
|
static int nexthop_get(Link *link, const NextHop *in, NextHop **ret) {
|
||||||
NextHop *existing;
|
NextHop *existing;
|
||||||
|
|
||||||
@ -221,14 +241,18 @@ static int nexthop_update(Link *link, NextHop *nexthop, const NextHop *in) {
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
|
assert(link->manager);
|
||||||
assert(nexthop);
|
assert(nexthop);
|
||||||
assert(in);
|
assert(in);
|
||||||
assert(in->id > 0);
|
assert(in->id > 0);
|
||||||
|
|
||||||
/* Currently, this only updates ID. */
|
/* This updates nexthop ID if necessary, and register the nexthop to Manager. */
|
||||||
|
|
||||||
if (nexthop->id > 0)
|
if (nexthop->id > 0) {
|
||||||
return nexthop->id == in->id ? 0 : -EINVAL;
|
if (nexthop->id == in->id)
|
||||||
|
goto set_manager;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
nexthop = set_remove(link->nexthops, nexthop);
|
nexthop = set_remove(link->nexthops, nexthop);
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
@ -251,7 +275,8 @@ static int nexthop_update(Link *link, NextHop *nexthop, const NextHop *in) {
|
|||||||
return r < 0 ? r : -EEXIST;
|
return r < 0 ? r : -EEXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
set_manager:
|
||||||
|
return hashmap_ensure_put(&link->manager->nexthops_by_id, NULL, UINT32_TO_PTR(nexthop->id), nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *str, const Link *link) {
|
static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *str, const Link *link) {
|
||||||
@ -384,7 +409,7 @@ int link_set_nexthops(Link *link) {
|
|||||||
|
|
||||||
if (link->nexthop_messages == 0) {
|
if (link->nexthop_messages == 0) {
|
||||||
link->static_nexthops_configured = true;
|
link->static_nexthops_configured = true;
|
||||||
/* Finaly, configure routes with gateways. */
|
/* Finally, configure routes with gateways. */
|
||||||
return link_set_routes_with_gateway(link);
|
return link_set_routes_with_gateway(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ void network_drop_invalid_nexthops(Network *network);
|
|||||||
|
|
||||||
int link_set_nexthops(Link *link);
|
int link_set_nexthops(Link *link);
|
||||||
|
|
||||||
|
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);
|
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||||
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_id);
|
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_id);
|
||||||
|
@ -328,6 +328,7 @@ void route_hash_func(const Route *route, struct siphash *state) {
|
|||||||
siphash24_compress(&route->initrwnd, sizeof(route->initrwnd), state);
|
siphash24_compress(&route->initrwnd, sizeof(route->initrwnd), state);
|
||||||
|
|
||||||
siphash24_compress(&route->advmss, sizeof(route->advmss), state);
|
siphash24_compress(&route->advmss, sizeof(route->advmss), state);
|
||||||
|
siphash24_compress(&route->nexthop_id, sizeof(route->nexthop_id), state);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -416,6 +417,10 @@ int route_compare_func(const Route *a, const Route *b) {
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = CMP(a->nexthop_id, b->nexthop_id);
|
||||||
|
if (r != 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
/* treat any other address family as AF_UNSPEC */
|
/* treat any other address family as AF_UNSPEC */
|
||||||
@ -479,7 +484,7 @@ static int route_get(const Manager *manager, const Link *link, const Route *in,
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void route_copy(Route *dest, const Route *src, const MultipathRoute *m) {
|
static void route_copy(Route *dest, const Route *src, const MultipathRoute *m, const NextHop *nh) {
|
||||||
assert(dest);
|
assert(dest);
|
||||||
assert(src);
|
assert(src);
|
||||||
|
|
||||||
@ -499,8 +504,13 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m) {
|
|||||||
dest->initrwnd = src->initrwnd;
|
dest->initrwnd = src->initrwnd;
|
||||||
dest->lifetime = src->lifetime;
|
dest->lifetime = src->lifetime;
|
||||||
dest->advmss = src->advmss;
|
dest->advmss = src->advmss;
|
||||||
|
dest->nexthop_id = src->nexthop_id;
|
||||||
|
|
||||||
if (m) {
|
if (nh) {
|
||||||
|
dest->gw_family = nh->family;
|
||||||
|
dest->gw = nh->gw;
|
||||||
|
dest->gw_weight = src->gw_weight;
|
||||||
|
} else if (m) {
|
||||||
dest->gw_family = m->gateway.family;
|
dest->gw_family = m->gateway.family;
|
||||||
dest->gw = m->gateway.address;
|
dest->gw = m->gateway.address;
|
||||||
dest->gw_weight = m->weight;
|
dest->gw_weight = m->weight;
|
||||||
@ -523,7 +533,7 @@ static int route_add_internal(Manager *manager, Link *link, Set **routes, const
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
route_copy(route, in, NULL);
|
route_copy(route, in, NULL, NULL);
|
||||||
|
|
||||||
r = set_ensure_put(routes, &route_hash_ops, route);
|
r = set_ensure_put(routes, &route_hash_ops, route);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -547,7 +557,7 @@ static int route_add_foreign(Manager *manager, Link *link, const Route *in, Rout
|
|||||||
return route_add_internal(manager, link, link ? &link->routes_foreign : &manager->routes_foreign, in, ret);
|
return route_add_internal(manager, link, link ? &link->routes_foreign : &manager->routes_foreign, in, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int route_add(Manager *manager, Link *link, const Route *in, const MultipathRoute *m, Route **ret) {
|
static int route_add(Manager *manager, Link *link, const Route *in, const MultipathRoute *m, const NextHop *nh, Route **ret) {
|
||||||
_cleanup_(route_freep) Route *tmp = NULL;
|
_cleanup_(route_freep) Route *tmp = NULL;
|
||||||
bool is_new = false;
|
bool is_new = false;
|
||||||
Route *route;
|
Route *route;
|
||||||
@ -556,14 +566,21 @@ static int route_add(Manager *manager, Link *link, const Route *in, const Multip
|
|||||||
assert(manager || link);
|
assert(manager || link);
|
||||||
assert(in);
|
assert(in);
|
||||||
|
|
||||||
if (m) {
|
if (nh) {
|
||||||
|
r = route_new(&tmp);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
route_copy(tmp, in, NULL, nh);
|
||||||
|
in = tmp;
|
||||||
|
} else if (m) {
|
||||||
assert(link && (m->ifindex == 0 || m->ifindex == link->ifindex));
|
assert(link && (m->ifindex == 0 || m->ifindex == link->ifindex));
|
||||||
|
|
||||||
r = route_new(&tmp);
|
r = route_new(&tmp);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
route_copy(tmp, in, m);
|
route_copy(tmp, in, m, NULL);
|
||||||
in = tmp;
|
in = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -630,10 +647,11 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
|
|||||||
(void) route_protocol_full_to_string_alloc(route->protocol, &proto);
|
(void) route_protocol_full_to_string_alloc(route->protocol, &proto);
|
||||||
|
|
||||||
log_link_debug(link,
|
log_link_debug(link,
|
||||||
"%s route: dst: %s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
|
"%s route: dst: %s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s, nexthop: %"PRIu32,
|
||||||
str, strna(dst), strna(src), strna(gw), strna(prefsrc),
|
str, strna(dst), strna(src), strna(gw), strna(prefsrc),
|
||||||
strna(scope), strna(table), strna(proto),
|
strna(scope), strna(table), strna(proto),
|
||||||
strna(route_type_to_string(route->type)));
|
strna(route_type_to_string(route->type)),
|
||||||
|
route->nexthop_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,7 +740,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not set route type: %m");
|
return log_link_error_errno(link, r, "Could not set route type: %m");
|
||||||
|
|
||||||
if (!route_type_is_reject(route)) {
|
if (!route_type_is_reject(route) && route->nexthop_id == 0) {
|
||||||
assert(link); /* Those routes must be attached to a specific link */
|
assert(link); /* Those routes must be attached to a specific link */
|
||||||
|
|
||||||
r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
|
r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
|
||||||
@ -730,6 +748,12 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
|||||||
return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
|
return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (route->nexthop_id > 0) {
|
||||||
|
r = sd_netlink_message_append_u32(req, RTA_NH_ID, route->nexthop_id);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_error_errno(link, r, "Could not append RTA_NH_ID attribute: %m");
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_append_u8(req, RTA_PREF, route->pref);
|
r = sd_netlink_message_append_u8(req, RTA_PREF, route->pref);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append RTA_PREF attribute: %m");
|
return log_link_error_errno(link, r, "Could not append RTA_PREF attribute: %m");
|
||||||
@ -893,7 +917,7 @@ int link_drop_foreign_routes(Link *link) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (link_has_route(link, route))
|
if (link_has_route(link, route))
|
||||||
k = route_add(NULL, link, route, NULL, NULL);
|
k = route_add(NULL, link, route, NULL, NULL, NULL);
|
||||||
else
|
else
|
||||||
k = route_remove(route, NULL, link, NULL);
|
k = route_remove(route, NULL, link, NULL);
|
||||||
if (k < 0 && r >= 0)
|
if (k < 0 && r >= 0)
|
||||||
@ -947,16 +971,20 @@ static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdat
|
|||||||
|
|
||||||
static int route_add_and_setup_timer(Link *link, const Route *route, const MultipathRoute *m, Route **ret) {
|
static int route_add_and_setup_timer(Link *link, const Route *route, const MultipathRoute *m, Route **ret) {
|
||||||
_cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
|
_cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
|
||||||
|
NextHop *nh = NULL;
|
||||||
Route *nr;
|
Route *nr;
|
||||||
int r, k;
|
int r, k;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
|
assert(link->manager);
|
||||||
assert(route);
|
assert(route);
|
||||||
|
|
||||||
|
(void) manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh);
|
||||||
|
|
||||||
if (route_type_is_reject(route))
|
if (route_type_is_reject(route))
|
||||||
k = route_add(link->manager, NULL, route, NULL, &nr);
|
k = route_add(link->manager, NULL, route, NULL, NULL, &nr);
|
||||||
else if (!m || m->ifindex == 0 || m->ifindex == link->ifindex)
|
else if (!m || m->ifindex == 0 || m->ifindex == link->ifindex)
|
||||||
k = route_add(NULL, link, route, m, &nr);
|
k = route_add(NULL, link, route, m, nh, &nr);
|
||||||
else {
|
else {
|
||||||
Link *link_gw;
|
Link *link_gw;
|
||||||
|
|
||||||
@ -964,7 +992,7 @@ static int route_add_and_setup_timer(Link *link, const Route *route, const Multi
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Failed to get link with ifindex %d: %m", m->ifindex);
|
return log_link_error_errno(link, r, "Failed to get link with ifindex %d: %m", m->ifindex);
|
||||||
|
|
||||||
k = route_add(NULL, link_gw, route, m, &nr);
|
k = route_add(NULL, link_gw, route, m, NULL, &nr);
|
||||||
}
|
}
|
||||||
if (k < 0)
|
if (k < 0)
|
||||||
return log_link_error_errno(link, k, "Could not add route: %m");
|
return log_link_error_errno(link, k, "Could not add route: %m");
|
||||||
@ -1258,6 +1286,9 @@ static bool route_has_gateway(const Route *route) {
|
|||||||
if (!ordered_set_isempty(route->multipath_routes))
|
if (!ordered_set_isempty(route->multipath_routes))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (route->nexthop_id > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1296,7 +1327,7 @@ int link_set_routes_with_gateway(Link *link) {
|
|||||||
* the addresses now, let's not configure the routes either. */
|
* the addresses now, let's not configure the routes either. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Finaly, add routes that needs a gateway. */
|
/* Finally, add routes that needs a gateway. */
|
||||||
r = link_set_routes_internal(link, true);
|
r = link_set_routes_internal(link, true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1356,13 +1387,30 @@ int link_set_routes(Link *link) {
|
|||||||
static int process_route_one(Manager *manager, Link *link, uint16_t type, const Route *tmp, const MultipathRoute *m) {
|
static int process_route_one(Manager *manager, Link *link, uint16_t type, const Route *tmp, const MultipathRoute *m) {
|
||||||
_cleanup_(route_freep) Route *nr = NULL;
|
_cleanup_(route_freep) Route *nr = NULL;
|
||||||
Route *route = NULL;
|
Route *route = NULL;
|
||||||
|
NextHop *nh = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(manager);
|
assert(manager);
|
||||||
assert(tmp);
|
assert(tmp);
|
||||||
assert(IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE));
|
assert(IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE));
|
||||||
|
|
||||||
if (m) {
|
(void) manager_get_nexthop_by_id(manager, tmp->nexthop_id, &nh);
|
||||||
|
|
||||||
|
if (nh) {
|
||||||
|
if (link && link != nh->link)
|
||||||
|
return log_link_warning_errno(link, SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"rtnl: received RTA_OIF and ifindex of nexthop corresponding to RTA_NH_ID do not match, ignoring.");
|
||||||
|
|
||||||
|
link = nh->link;
|
||||||
|
|
||||||
|
r = route_new(&nr);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
route_copy(nr, tmp, NULL, nh);
|
||||||
|
|
||||||
|
tmp = nr;
|
||||||
|
} else if (m) {
|
||||||
if (link)
|
if (link)
|
||||||
return log_link_warning_errno(link, SYNTHETIC_ERRNO(EINVAL),
|
return log_link_warning_errno(link, SYNTHETIC_ERRNO(EINVAL),
|
||||||
"rtnl: received route contains both RTA_OIF and RTA_MULTIPATH, ignoring.");
|
"rtnl: received route contains both RTA_OIF and RTA_MULTIPATH, ignoring.");
|
||||||
@ -1381,7 +1429,7 @@ static int process_route_one(Manager *manager, Link *link, uint16_t type, const
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
route_copy(nr, tmp, m);
|
route_copy(nr, tmp, m, NULL);
|
||||||
|
|
||||||
tmp = nr;
|
tmp = nr;
|
||||||
}
|
}
|
||||||
@ -1573,6 +1621,12 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r = sd_netlink_message_read_u32(message, RTA_NH_ID, &tmp->nexthop_id);
|
||||||
|
if (r < 0 && r != -ENODATA) {
|
||||||
|
log_link_warning_errno(link, r, "rtnl: received route message with invalid nexthop id, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_enter_container(message, RTA_METRICS);
|
r = sd_netlink_message_enter_container(message, RTA_METRICS);
|
||||||
if (r < 0 && r != -ENODATA) {
|
if (r < 0 && r != -ENODATA) {
|
||||||
log_link_error_errno(link, r, "rtnl: Could not enter RTA_METRICS container: %m");
|
log_link_error_errno(link, r, "rtnl: Could not enter RTA_METRICS container: %m");
|
||||||
@ -1966,6 +2020,59 @@ int config_parse_route_scope(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_route_nexthop(
|
||||||
|
const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
unsigned section_line,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
Network *network = userdata;
|
||||||
|
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||||
|
uint32_t id;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(section);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
r = route_new_static(network, filename, section_line, &n);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"Failed to allocate route, ignoring assignment: %m");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
n->nexthop_id = 0;
|
||||||
|
TAKE_PTR(n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = safe_atou32(rvalue, &id);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse nexthop ID, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (id == 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid nexthop ID, ignoring assignment: %s", rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
n->nexthop_id = id;
|
||||||
|
TAKE_PTR(n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_route_table(
|
int config_parse_route_table(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@ -2656,6 +2763,14 @@ static int route_section_verify(Route *route, Network *network) {
|
|||||||
route->section->filename, route->section->line);
|
route->section->filename, route->section->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (route->nexthop_id > 0 &&
|
||||||
|
(in_addr_is_set(route->gw_family, &route->gw) ||
|
||||||
|
!ordered_set_isempty(route->multipath_routes)))
|
||||||
|
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. "
|
||||||
|
"Ignoring [Route] section from line %u.",
|
||||||
|
route->section->filename, route->section->line);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ typedef struct Route {
|
|||||||
unsigned char pref;
|
unsigned char pref;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
int gateway_onlink;
|
int gateway_onlink;
|
||||||
|
uint32_t nexthop_id;
|
||||||
|
|
||||||
bool scope_set:1;
|
bool scope_set:1;
|
||||||
bool table_set:1;
|
bool table_set:1;
|
||||||
@ -105,3 +106,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
|
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
|
CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop);
|
||||||
|
@ -201,7 +201,6 @@ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie);
|
|||||||
int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie);
|
int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie);
|
||||||
int sd_bus_call(sd_bus *bus, sd_bus_message *m, uint64_t usec, sd_bus_error *ret_error, sd_bus_message **reply);
|
int sd_bus_call(sd_bus *bus, sd_bus_message *m, uint64_t usec, sd_bus_error *ret_error, sd_bus_message **reply);
|
||||||
int sd_bus_call_async(sd_bus *bus, sd_bus_slot **slot, sd_bus_message *m, sd_bus_message_handler_t callback, void *userdata, uint64_t usec);
|
int sd_bus_call_async(sd_bus *bus, sd_bus_slot **slot, sd_bus_message *m, sd_bus_message_handler_t callback, void *userdata, uint64_t usec);
|
||||||
int sd_bus_reply(const sd_bus_message *call, sd_bus_message *reply);
|
|
||||||
|
|
||||||
int sd_bus_get_fd(sd_bus *bus);
|
int sd_bus_get_fd(sd_bus *bus);
|
||||||
int sd_bus_get_events(sd_bus *bus);
|
int sd_bus_get_events(sd_bus *bus);
|
||||||
@ -355,6 +354,7 @@ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machin
|
|||||||
|
|
||||||
/* Convenience calls */
|
/* Convenience calls */
|
||||||
|
|
||||||
|
int sd_bus_message_send(sd_bus_message *m);
|
||||||
int sd_bus_call_methodv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, va_list ap);
|
int sd_bus_call_methodv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, va_list ap);
|
||||||
int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...);
|
int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...);
|
||||||
int sd_bus_call_method_asyncv(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, va_list ap);
|
int sd_bus_call_method_asyncv(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, va_list ap);
|
||||||
|
@ -166,6 +166,7 @@ Metric=
|
|||||||
TTLPropagate=
|
TTLPropagate=
|
||||||
MultiPathRoute=
|
MultiPathRoute=
|
||||||
TCPAdvertisedMaximumSegmentSize=
|
TCPAdvertisedMaximumSegmentSize=
|
||||||
|
NextHop=
|
||||||
[Network]
|
[Network]
|
||||||
IPv6DuplicateAddressDetection=
|
IPv6DuplicateAddressDetection=
|
||||||
IPMasquerade=
|
IPMasquerade=
|
||||||
|
@ -61,6 +61,10 @@ Scope=link
|
|||||||
Address=2001:0db8:1:f101::1/64
|
Address=2001:0db8:1:f101::1/64
|
||||||
PreferredLifetime=0
|
PreferredLifetime=0
|
||||||
|
|
||||||
|
[Address]
|
||||||
|
Address=10.8.8.1/16
|
||||||
|
Broadcast=no
|
||||||
|
|
||||||
# test for ENOBUFS issue #17012
|
# test for ENOBUFS issue #17012
|
||||||
[Network]
|
[Network]
|
||||||
Address=10.3.3.1/16
|
Address=10.3.3.1/16
|
||||||
|
@ -25,3 +25,15 @@ Family=ipv4
|
|||||||
|
|
||||||
[NextHop]
|
[NextHop]
|
||||||
Gateway=192.168.5.2
|
Gateway=192.168.5.2
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
NextHop=1
|
||||||
|
Destination=10.10.10.10
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
NextHop=2
|
||||||
|
Destination=10.10.10.11
|
||||||
|
|
||||||
|
[Route]
|
||||||
|
NextHop=2
|
||||||
|
Destination=2001:1234:5:8f62::1
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Name=wg98
|
Name=wg98
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
|
Address=192.168.123.123/24
|
||||||
Address=fd8d:4d6d:3ccb:0500::1/64
|
Address=fd8d:4d6d:3ccb:0500::1/64
|
||||||
|
|
||||||
# nat64 via 1
|
# nat64 via 1
|
||||||
|
@ -1220,6 +1220,14 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
start_networkd()
|
start_networkd()
|
||||||
self.wait_online(['wg99:carrier', 'wg98:routable', 'wg97:carrier'])
|
self.wait_online(['wg99:carrier', 'wg98:routable', 'wg97:carrier'])
|
||||||
|
|
||||||
|
output = check_output('ip -4 address show dev wg98')
|
||||||
|
print(output)
|
||||||
|
self.assertIn('inet 192.168.123.123/24 scope global wg98', output)
|
||||||
|
|
||||||
|
output = check_output('ip -6 address show dev wg98')
|
||||||
|
print(output)
|
||||||
|
self.assertIn('inet6 fd8d:4d6d:3ccb:500::1/64 scope global', output)
|
||||||
|
|
||||||
if shutil.which('wg'):
|
if shutil.which('wg'):
|
||||||
call('wg')
|
call('wg')
|
||||||
|
|
||||||
@ -1833,6 +1841,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
self.assertIn('inet 10.1.2.4/16 brd 10.1.255.255 scope global secondary dummy98', output)
|
self.assertIn('inet 10.1.2.4/16 brd 10.1.255.255 scope global secondary dummy98', output)
|
||||||
self.assertIn('inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98', output)
|
self.assertIn('inet 10.2.2.4/16 brd 10.2.255.255 scope global dummy98', output)
|
||||||
self.assertIn('inet 10.7.8.9/16 brd 10.7.255.255 scope link deprecated dummy98', output)
|
self.assertIn('inet 10.7.8.9/16 brd 10.7.255.255 scope link deprecated dummy98', output)
|
||||||
|
self.assertIn('inet 10.8.8.1/16 scope global dummy98', output)
|
||||||
|
|
||||||
# test for ENOBUFS issue #17012
|
# test for ENOBUFS issue #17012
|
||||||
for i in range(1,254):
|
for i in range(1,254):
|
||||||
@ -2805,6 +2814,18 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
self.assertIn('id 4 dev veth99', output)
|
self.assertIn('id 4 dev veth99', output)
|
||||||
self.assertRegex(output, r'id [0-9]* via 192.168.5.2 dev veth99')
|
self.assertRegex(output, r'id [0-9]* via 192.168.5.2 dev veth99')
|
||||||
|
|
||||||
|
output = check_output('ip route show dev veth99 10.10.10.10')
|
||||||
|
print(output)
|
||||||
|
self.assertEqual('10.10.10.10 nhid 1 via 192.168.5.1 proto static', output)
|
||||||
|
|
||||||
|
output = check_output('ip route show dev veth99 10.10.10.11')
|
||||||
|
print(output)
|
||||||
|
self.assertEqual('10.10.10.11 nhid 2 via inet6 2001:1234:5:8f63::2 proto static', output)
|
||||||
|
|
||||||
|
output = check_output('ip -6 route show dev veth99 2001:1234:5:8f62::1')
|
||||||
|
print(output)
|
||||||
|
self.assertEqual('2001:1234:5:8f62::1 nhid 2 via 2001:1234:5:8f63::2 proto static metric 1024 pref medium', output)
|
||||||
|
|
||||||
def test_qdisc(self):
|
def test_qdisc(self):
|
||||||
copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
|
copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
|
||||||
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
|
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user