Compare commits

...

18 Commits

Author SHA1 Message Date
Yu Watanabe 397288e3eb
Merge pull request #15991 from keszybz/uids-gids-only-decimal
Only use base 10 for numeric uids/gids
2020-06-01 17:04:57 +09:00
Norbert Lange 63e2d1714e udev: single binary replacing udevd and udevadm
Since the separate binaries contain mostly the same code,
this almost halves the size of the installation.

before:
398K /bin/udevadm
391K /lib/systemd/systemd-udevd

after:
431K /bin/udevadm
0    /lib/systemd/systemd-udevd -> ../../bin/udevadm

Fixes: #14200
2020-06-01 09:41:21 +02:00
Yu Watanabe 0e77fc66bc network: fix double free in macsec_receive_channel_free()
Fixes #15941.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22547
2020-06-01 09:39:46 +02:00
Zbigniew Jędrzejewski-Szmek b9d19abd38
Merge pull request #16029 from yuwata/network-wireguard-without-peers-15786
network: configure wireguard without no peers
2020-06-01 09:34:04 +02:00
Zbigniew Jędrzejewski-Szmek 6597cb324a
Merge pull request #15990 from jwrdegoede/hwdb-accel-quirks
Hwdb accel quirks
2020-06-01 08:44:07 +02:00
Yu Watanabe da3509f0f5 test-network: add test for wireguard without peers 2020-06-01 14:23:03 +09:00
Yu Watanabe 50254f5500 network: wireguard: set ListenPort= when no peers are configured
Closes #15786.
2020-06-01 14:22:08 +09:00
Yu Watanabe dc851c00c3
Merge pull request #15982 from keszybz/shell-completion-and-help
Shell completion and udevd help update
2020-06-01 13:50:50 +09:00
Yu Watanabe f3e4b1e07c
Merge pull request #15884 from ssahani/dhcpv6-vendor
DHCPv6: Introduce vendor specific
2020-06-01 12:25:54 +09:00
Zbigniew Jędrzejewski-Szmek 156a5fd297 basic/user-util: always use base 10 for user/group numbers
We would parse numbers with base prefixes as user identifiers. For example,
"0x2b3bfa0" would be interpreted as UID==45334432 and "01750" would be
interpreted as UID==1000. This parsing was used also in cases where either a
user/group name or number may be specified. This means that names like
0x2b3bfa0 would be ambiguous: they are a valid user name according to our
documented relaxed rules, but they would also be parsed as numeric uids.

This behaviour is definitely not expected by users, since tools generally only
accept decimal numbers (e.g. id, getent passwd), while other tools only accept
user names and thus will interpret such strings as user names without even
attempting to convert them to numbers (su, ssh). So let's follow suit and only
accept numbers in decimal notation. Effectively this means that we will reject
such strings as a username/uid/groupname/gid where strict mode is used, and try
to look up a user/group with such a name in relaxed mode.

Since the function changed is fairly low-level and fairly widely used, this
affects multiple tools: loginctl show-user/enable-linger/disable-linger foo',
the third argument in sysusers.d, fourth and fifth arguments in tmpfiles.d,
etc.

Fixes #15985.
2020-05-31 18:38:16 +02:00
Zbigniew Jędrzejewski-Szmek f7091f458e loginctl: define loop iterators in the loop header 2020-05-31 18:38:16 +02:00
Hans de Goede a7a8dcffc2 hwdb: Add accel orientation quirk for Trekstor Surftab Twin 10.1 ST10432-8
The Trekstor Surftab Twin 10.1 ST10432-8 accelerometer has its x-axis
inverted, add a quirk for this.
2020-05-31 16:21:36 +02:00
Hans de Goede b5f829a2da hwdb: Add accel orientation quirk for Toshiba Encore WT10A tablet
Add a quirk to correct the accelerometer orientation on
Toshiba Encore WT10A tablets.
2020-05-31 10:27:00 +02:00
Zbigniew Jędrzejewski-Szmek d1109e12c0 udevd: update snippet string
Repeating the unit name in the description is not useful, and "manages devices"
is too cryptic.
2020-05-30 17:15:20 +02:00
Zbigniew Jędrzejewski-Szmek 8f0a346a29 shell-completions: update bootctl
Entries in the completion lists are reordered to follow --help output:
this makes it much easier to see what is missing.
2020-05-30 16:04:43 +02:00
Susant Sahani 1c3ec1cd45 network: dhcp6 - fix memory leak 2020-05-29 13:37:58 +02:00
Susant Sahani b4ccc5de7d network: Inroduce DHCP6- send vendor options
network: Inroduce DHCP6- send vendor options

```
 0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |      OPTION_VENDOR_OPTS       |           option-len          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       enterprise-number                       |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      .                                                               .
      .                       vendor-option-data                      .
      .                                                               .
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

```
  0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |          sub-opt-code         |         sub-option-len        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      .                                                               .
      .                        sub-option-data                        .
      .                                                               .
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                 Figure 31: Vendor-specific Options Format

      sub-opt-code         The code for the sub-option.  A 2-octet
                           field.

      sub-option-len       An unsigned integer giving the length of the
                           sub-option-data field in this sub-option in
                           octets.  A 2-octet field.

      sub-option-data      The data area for the sub-option.  The
                           length, in octets, is specified by
                           sub-option-len.

```
2020-05-29 13:37:57 +02:00
Susant Sahani 99ccb8ff89 sd-dhcp6: Introduce vendor specific information
RFC: 8415
21.17.  Vendor-specific Information Option

   This option is used by clients and servers to exchange vendor-
   specific information.

   The format of the Vendor-specific Information option is:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |      OPTION_VENDOR_OPTS       |           option-len          |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       enterprise-number                       |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      .                                                               .
      .                       vendor-option-data                      .
      .                                                               .
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

           Figure 30: Vendor-specific Information Option Format

      option-code          OPTION_VENDOR_OPTS (17).

      option-len           4 + length of vendor-option-data field.

      enterprise-number    The vendor's registered Enterprise Number as
                           maintained by IANA [IANA-PEN].  A 4-octet
                           field containing an unsigned integer.

      vendor-option-data   Vendor options, interpreted by
                           vendor-specific code on the clients and
                           servers.  A variable-length field (4 octets
                           less than the value in the option-len field).

 The definition of the information carried in this option is vendor
   specific.  The vendor is indicated in the enterprise-number field.
   Use of vendor-specific information allows enhanced operation,
   utilizing additional features in a vendor's DHCP implementation.  A
   DHCP client that does not receive requested vendor-specific
   information will still configure the node's IPv6 stack to be
   functional.

   The vendor-option-data field MUST be encoded as a sequence of
   code/length/value fields of format identical to the DHCP options (see
   Section 21.1).  The sub-option codes are defined by the vendor
   identified in the enterprise-number field and are not managed by
   IANA.  Each of the sub-options is formatted as follows:

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |          sub-opt-code         |         sub-option-len        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      .                                                               .
      .                        sub-option-data                        .
      .                                                               .
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                 Figure 31: Vendor-specific Options Format

      sub-opt-code         The code for the sub-option.  A 2-octet
                           field.

      sub-option-len       An unsigned integer giving the length of the
                           sub-option-data field in this sub-option in
                           octets.  A 2-octet field.

      sub-option-data      The data area for the sub-option.  The
                           length, in octets, is specified by
                           sub-option-len.

   Multiple instances of the Vendor-specific Information option may
   appear in a DHCP message.  Each instance of the option is interpreted
   according to the option codes defined by the vendor identified by the
   Enterprise Number in that option.  Servers and clients MUST NOT send
   more than one instance of the Vendor-specific Information option with
   the same Enterprise Number.  Each instance of the Vendor-specific
   Information option MAY contain multiple sub-options.

A client that is interested in receiving a Vendor-specific
   Information option:

   -  MUST specify the Vendor-specific Information option in an Option
      Request option.

   -  MAY specify an associated Vendor Class option (see Section 21.16).

   -  MAY specify the Vendor-specific Information option with
      appropriate data.

   Servers only return the Vendor-specific Information options if
   specified in Option Request options from clients and:

   -  MAY use the Enterprise Numbers in the associated Vendor Class
      options to restrict the set of Enterprise Numbers in the
      Vendor-specific Information options returned.

   -  MAY return all configured Vendor-specific Information options.

   -  MAY use other information in the packet or in its configuration to
      determine which set of Enterprise Numbers in the Vendor-specific
      Information options to return.
2020-05-29 13:36:42 +02:00
31 changed files with 249 additions and 60 deletions

View File

@ -643,6 +643,14 @@ sensor:modalias:acpi:KIOX000A*:dmi:*:svnTECLAST:pnX98PlusII:*
sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd04/15/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.: sensor:modalias:acpi:BMA250E*:dmi:bvnAmericanMegatrendsInc.:bvr5.6.5:bd04/15/2014:svnTobefilledbyO.E.M.:pnTobefilledbyO.E.M.:pvrTobefilledbyO.E.M.:rvnAMICorporation:rnAptioCRB:rvrTobefilledbyO.E.M.:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
#########################################
# Toshiba
#########################################
# Toshiba Encore WT10A tablet
sensor:modalias:acpi:INVN6500*:dmi:*:svnTOSHIBA:pnTOSHIBAWT10-A-103:*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
######################################### #########################################
# Trekstor # Trekstor
######################################### #########################################
@ -650,6 +658,9 @@ sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnInsyde:pnST7041
sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnTrekStor:pnSurfTabwintron7.0ST70416-6:* sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnTrekStor:pnSurfTabwintron7.0ST70416-6:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
sensor:modalias:acpi:KIOX000A*:dmi:*:svnTrekStor:pnSurfTabtwin10.1:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR*:pnPrimetabS11B:* sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR*:pnPrimetabS11B:*
sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR:pnPrimetabT13B:* sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR:pnPrimetabT13B:*
sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabtwin11.6:* sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabtwin11.6:*

View File

@ -1765,6 +1765,22 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>SendVendorOption=</varname></term>
<listitem>
<para>Send an arbitrary vendor option in the DHCPv6 request. Takes an enterprise identifier, DHCP option number,
data type, and data separated with a colon
(<literal><replaceable>enterprise identifier</replaceable>:<replaceable>option</replaceable>:<replaceable>type</replaceable>:
<replaceable>value</replaceable></literal>). Enterprise identifier is an unsigned integer ranges 1..4294967294.
The option number must be an integer in the range 1..254. Data type takes one of <literal>uint8</literal>,
<literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, <literal>ipv6address</literal>, or
<literal>string</literal>. Special characters in the data string may be escaped using
<ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
escapes</ulink>. This setting can be specified multiple times. If an empty string is specified,
then all options specified earlier are cleared. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>ForceDHCPv6PDOtherInformation=</varname></term> <term><varname>ForceDHCPv6PDOtherInformation=</varname></term>
<listitem> <listitem>

View File

@ -2198,6 +2198,10 @@ foreach alias : (['halt', 'poweroff', 'reboot', 'shutdown'] +
join_paths(rootsbindir, alias)) join_paths(rootsbindir, alias))
endforeach endforeach
meson.add_install_script(meson_make_symlink,
join_paths(rootbindir, 'udevadm'),
join_paths(rootlibexecdir, 'systemd-udevd'))
if conf.get('ENABLE_BACKLIGHT') == 1 if conf.get('ENABLE_BACKLIGHT') == 1
executable( executable(
'systemd-backlight', 'systemd-backlight',
@ -2983,24 +2987,6 @@ public_programs += executable(
install : true, install : true,
install_dir : rootlibexecdir) install_dir : rootlibexecdir)
public_programs += executable(
'systemd-udevd',
systemd_udevd_sources,
include_directories : includes,
c_args : '-DLOG_REALM=LOG_REALM_UDEV',
link_with : [libudev_core,
libsystemd_network,
libudev_static],
dependencies : [versiondep,
threads,
libkmod,
libidn,
libacl,
libblkid],
install_rpath : udev_rpath,
install : true,
install_dir : rootlibexecdir)
public_programs += executable( public_programs += executable(
'udevadm', 'udevadm',
udevadm_sources, udevadm_sources,

View File

@ -31,7 +31,7 @@ _bootctl() {
local i verb comps local i verb comps
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
local -A OPTS=( local -A OPTS=(
[STANDALONE]='-h --help --no-variables -p --print-esp-path -x --print-boot-path --version --no-pager' [STANDALONE]='-h --help -p --print-esp-path -x --print-boot-path --version --no-variables --no-pager --graceful'
[ARG]='--esp-path --boot-path' [ARG]='--esp-path --boot-path'
) )
@ -56,8 +56,10 @@ _bootctl() {
fi fi
local -A VERBS=( local -A VERBS=(
[STANDALONE]='help install list remove status update' # systemd-efi-options takes an argument, but it is free-form, so we cannot complete it
[STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list'
[BOOTENTRY]='set-default set-oneshot' [BOOTENTRY]='set-default set-oneshot'
[BOOLEAN]='reboot-to-firmware'
) )
for ((i=0; i < COMP_CWORD; i++)); do for ((i=0; i < COMP_CWORD; i++)); do
@ -86,6 +88,8 @@ _bootctl() {
else else
comps='' comps=''
fi fi
elif __contains_word "$verb" ${VERBS[BOOLEAN]}; then
comps="yes no"
fi fi
COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) COMPREPLY=( $(compgen -W '$comps' -- "$cur") )

View File

@ -24,6 +24,13 @@ _bootctl_set-oneshot() {
_bootctl_comp_ids _bootctl_comp_ids
} }
_bootctl_reboot-to-firmware() {
local -a _completions
_completions=( yes no )
typeset -U _completions
_describe 'possible values' _completions
}
(( $+functions[_bootctl_commands] )) || _bootctl_commands() (( $+functions[_bootctl_commands] )) || _bootctl_commands()
{ {
local -a _bootctl_cmds local -a _bootctl_cmds
@ -32,8 +39,11 @@ _bootctl_set-oneshot() {
"install:Install systemd-boot to the ESP and EFI variables" "install:Install systemd-boot to the ESP and EFI variables"
"update:Update systemd-boot in the ESP and EFI variables" "update:Update systemd-boot in the ESP and EFI variables"
"remove:Remove systemd-boot from the ESP and EFI variables" "remove:Remove systemd-boot from the ESP and EFI variables"
"random-seed:Initialize random seed in ESP and EFI variables"
"is-installed:Test whether systemd-boot is installed in the ESP" "is-installed:Test whether systemd-boot is installed in the ESP"
"random-seed:Initialize random seed in ESP and EFI variables"
"systemd-efi-options:Query or set system options string in EFI variable"
"reboot-to-firmware:Query or set reboot-to-firmware EFI flag"
"list:List boot loader entries"
"set-default:Set the default boot loader entry" "set-default:Set the default boot loader entry"
"set-oneshot:Set the default boot loader entry only for the next boot" "set-oneshot:Set the default boot loader entry only for the next boot"
) )
@ -59,4 +69,5 @@ _arguments \
{-x,--print-boot-path}'[Print path to the $BOOT partition]' \ {-x,--print-boot-path}'[Print path to the $BOOT partition]' \
'--no-variables[Do not touch EFI variables]' \ '--no-variables[Do not touch EFI variables]' \
'--no-pager[Do not pipe output into a pager]' \ '--no-pager[Do not pipe output into a pager]' \
'--graceful[Do not fail when locating ESP or writing fails]' \
'*::bootctl command:_bootctl_commands' '*::bootctl command:_bootctl_commands'

View File

@ -49,7 +49,7 @@ int parse_uid(const char *s, uid_t *ret) {
assert(s); assert(s);
assert_cc(sizeof(uid_t) == sizeof(uint32_t)); assert_cc(sizeof(uid_t) == sizeof(uint32_t));
r = safe_atou32(s, &uid); r = safe_atou32_full(s, 10, &uid);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -11,12 +11,14 @@
#include "sd-event.h" #include "sd-event.h"
#include "list.h" #include "list.h"
#include "hashmap.h"
#include "macro.h" #include "macro.h"
#include "sparse-endian.h" #include "sparse-endian.h"
typedef struct sd_dhcp6_option { typedef struct sd_dhcp6_option {
unsigned n_ref; unsigned n_ref;
uint32_t enterprise_identifier;
uint16_t option; uint16_t option;
void *data; void *data;
size_t length; size_t length;
@ -99,6 +101,7 @@ int dhcp6_option_append_pd(uint8_t *buf, size_t len, const DHCP6IA *pd, DHCP6Add
int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn); int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn);
int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class); int dhcp6_option_append_user_class(uint8_t **buf, size_t *buflen, char **user_class);
int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **user_class); int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **user_class);
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options);
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
size_t *optlen, uint8_t **optvalue); size_t *optlen, uint8_t **optvalue);
int dhcp6_option_parse_status(DHCP6Option *option, size_t len); int dhcp6_option_parse_status(DHCP6Option *option, size_t len);

View File

@ -79,6 +79,39 @@ int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
return 0; return 0;
} }
int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHashmap *vendor_options) {
sd_dhcp6_option *options;
Iterator i;
int r;
assert(buf);
assert(*buf);
assert(buflen);
assert(vendor_options);
ORDERED_HASHMAP_FOREACH(options, vendor_options, i) {
_cleanup_free_ uint8_t *p = NULL;
size_t total;
total = 4 + 2 + 2 + options->length;
p = malloc(total);
if (!p)
return -ENOMEM;
unaligned_write_be32(p, options->enterprise_identifier);
unaligned_write_be16(p + 4, options->option);
unaligned_write_be16(p + 6, options->length);
memcpy(p + 8, options->data, options->length);
r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_VENDOR_OPTS, total, p);
if (r < 0)
return r;
}
return 0;
}
int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) { int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
uint16_t len; uint16_t len;
uint8_t *ia_hdr; uint8_t *ia_hdr;
@ -683,7 +716,7 @@ static sd_dhcp6_option* dhcp6_option_free(sd_dhcp6_option *i) {
return mfree(i); return mfree(i);
} }
int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhcp6_option **ret) { int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, uint32_t enterprise_identifier, sd_dhcp6_option **ret) {
assert_return(ret, -EINVAL); assert_return(ret, -EINVAL);
assert_return(length == 0 || data, -EINVAL); assert_return(length == 0 || data, -EINVAL);
@ -698,6 +731,7 @@ int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhc
*p = (sd_dhcp6_option) { *p = (sd_dhcp6_option) {
.n_ref = 1, .n_ref = 1,
.option = option, .option = option,
.enterprise_identifier = enterprise_identifier,
.length = length, .length = length,
.data = TAKE_PTR(q), .data = TAKE_PTR(q),
}; };

View File

@ -81,6 +81,7 @@ struct sd_dhcp6_client {
usec_t information_request_time_usec; usec_t information_request_time_usec;
usec_t information_refresh_time_usec; usec_t information_refresh_time_usec;
OrderedHashmap *extra_options; OrderedHashmap *extra_options;
OrderedHashmap *vendor_options;
}; };
static const uint16_t default_req_opts[] = { static const uint16_t default_req_opts[] = {
@ -225,6 +226,25 @@ int sd_dhcp6_client_set_prefix_delegation_hint(
return 0; return 0;
} }
int sd_dhcp6_client_add_vendor_option(sd_dhcp6_client *client, sd_dhcp6_option *v) {
int r;
assert_return(client, -EINVAL);
assert_return(v, -EINVAL);
r = ordered_hashmap_ensure_allocated(&client->vendor_options, &dhcp6_option_hash_ops);
if (r < 0)
return r;
r = ordered_hashmap_put(client->vendor_options, v, v);
if (r < 0)
return r;
sd_dhcp6_option_ref(v);
return 1;
}
static int client_ensure_duid(sd_dhcp6_client *client) { static int client_ensure_duid(sd_dhcp6_client *client) {
if (client->duid_len != 0) if (client->duid_len != 0)
return 0; return 0;
@ -622,6 +642,13 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r; return r;
} }
if (!ordered_hashmap_isempty(client->vendor_options)) {
r = dhcp6_option_append_vendor_option(&opt, &optlen,
client->vendor_options);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix); r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
if (r < 0) if (r < 0)
@ -680,6 +707,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r; return r;
} }
if (!ordered_hashmap_isempty(client->vendor_options)) {
r = dhcp6_option_append_vendor_option(&opt, &optlen, client->vendor_options);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL); r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0) if (r < 0)
@ -726,6 +759,12 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r; return r;
} }
if (!ordered_hashmap_isempty(client->vendor_options)) {
r = dhcp6_option_append_vendor_option(&opt, &optlen, client->vendor_options);
if (r < 0)
return r;
}
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL); r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0) if (r < 0)

View File

@ -815,7 +815,7 @@ static int show_properties(sd_bus *bus, const char *path, bool *new_line) {
static int show_session(int argc, char *argv[], void *userdata) { static int show_session(int argc, char *argv[], void *userdata) {
bool properties, new_line = false; bool properties, new_line = false;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *path = NULL; _cleanup_free_ char *path = NULL;
@ -834,7 +834,7 @@ static int show_session(int argc, char *argv[], void *userdata) {
return print_session_status_info(bus, "/org/freedesktop/login1/session/auto", &new_line); return print_session_status_info(bus, "/org/freedesktop/login1/session/auto", &new_line);
} }
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
r = get_session_path(bus, argv[i], &error, &path); r = get_session_path(bus, argv[i], &error, &path);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get session path: %s", bus_error_message(&error, r)); return log_error_errno(r, "Failed to get session path: %s", bus_error_message(&error, r));
@ -854,7 +854,7 @@ static int show_session(int argc, char *argv[], void *userdata) {
static int show_user(int argc, char *argv[], void *userdata) { static int show_user(int argc, char *argv[], void *userdata) {
bool properties, new_line = false; bool properties, new_line = false;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
@ -871,7 +871,7 @@ static int show_user(int argc, char *argv[], void *userdata) {
return print_user_status_info(bus, "/org/freedesktop/login1/user/self", &new_line); return print_user_status_info(bus, "/org/freedesktop/login1/user/self", &new_line);
} }
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message * reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message * reply = NULL;
const char *path = NULL; const char *path = NULL;
@ -911,7 +911,7 @@ static int show_user(int argc, char *argv[], void *userdata) {
static int show_seat(int argc, char *argv[], void *userdata) { static int show_seat(int argc, char *argv[], void *userdata) {
bool properties, new_line = false; bool properties, new_line = false;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
@ -928,7 +928,7 @@ static int show_seat(int argc, char *argv[], void *userdata) {
return print_seat_status_info(bus, "/org/freedesktop/login1/seat/auto", &new_line); return print_seat_status_info(bus, "/org/freedesktop/login1/seat/auto", &new_line);
} }
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message * reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message * reply = NULL;
const char *path = NULL; const char *path = NULL;
@ -956,7 +956,7 @@ static int show_seat(int argc, char *argv[], void *userdata) {
static int activate(int argc, char *argv[], void *userdata) { static int activate(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
@ -980,7 +980,7 @@ static int activate(int argc, char *argv[], void *userdata) {
return 0; return 0;
} }
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
r = bus_call_method( r = bus_call_method(
bus, bus,
@ -1001,7 +1001,7 @@ static int activate(int argc, char *argv[], void *userdata) {
static int kill_session(int argc, char *argv[], void *userdata) { static int kill_session(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
@ -1011,7 +1011,7 @@ static int kill_session(int argc, char *argv[], void *userdata) {
if (!arg_kill_who) if (!arg_kill_who)
arg_kill_who = "all"; arg_kill_who = "all";
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
r = bus_call_method( r = bus_call_method(
bus, bus,
@ -1031,7 +1031,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
sd_bus *bus = userdata; sd_bus *bus = userdata;
char* short_argv[3]; char* short_argv[3];
bool b; bool b;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
@ -1051,7 +1051,7 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
argc = 2; argc = 2;
} }
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
uid_t uid; uid_t uid;
if (isempty(argv[i])) if (isempty(argv[i]))
@ -1078,14 +1078,14 @@ static int enable_linger(int argc, char *argv[], void *userdata) {
static int terminate_user(int argc, char *argv[], void *userdata) { static int terminate_user(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
polkit_agent_open_if_enabled(arg_transport, arg_ask_password); polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
uid_t uid; uid_t uid;
r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0); r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
@ -1103,7 +1103,7 @@ static int terminate_user(int argc, char *argv[], void *userdata) {
static int kill_user(int argc, char *argv[], void *userdata) { static int kill_user(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
@ -1113,7 +1113,7 @@ static int kill_user(int argc, char *argv[], void *userdata) {
if (!arg_kill_who) if (!arg_kill_who)
arg_kill_who = "all"; arg_kill_who = "all";
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
uid_t uid; uid_t uid;
r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0); r = get_user_creds((const char**) (argv+i), &uid, NULL, NULL, NULL, 0);
@ -1136,14 +1136,14 @@ static int kill_user(int argc, char *argv[], void *userdata) {
static int attach(int argc, char *argv[], void *userdata) { static int attach(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
polkit_agent_open_if_enabled(arg_transport, arg_ask_password); polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
for (i = 2; i < argc; i++) { for (int i = 2; i < argc; i++) {
r = bus_call_method( r = bus_call_method(
bus, bus,
@ -1200,14 +1200,14 @@ static int lock_sessions(int argc, char *argv[], void *userdata) {
static int terminate_seat(int argc, char *argv[], void *userdata) { static int terminate_seat(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r, i; int r;
assert(bus); assert(bus);
assert(argv); assert(argv);
polkit_agent_open_if_enabled(arg_transport, arg_ask_password); polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
for (i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
r = bus_call_method(bus, bus_login_mgr, "TerminateSeat", &error, NULL, "s", argv[i]); r = bus_call_method(bus, bus_login_mgr, "TerminateSeat", &error, NULL, "s", argv[i]);
if (r < 0) if (r < 0)

View File

@ -102,7 +102,7 @@ static void macsec_receive_channel_free(ReceiveChannel *c) {
if (c->macsec) { if (c->macsec) {
if (c->sci.as_uint64 > 0) if (c->sci.as_uint64 > 0)
ordered_hashmap_remove(c->macsec->receive_channels, &c->sci.as_uint64); ordered_hashmap_remove_value(c->macsec->receive_channels, &c->sci.as_uint64, c);
if (c->section) if (c->section)
ordered_hashmap_remove(c->macsec->receive_channels_by_section, c->section); ordered_hashmap_remove(c->macsec->receive_channels_by_section, c->section);

View File

@ -219,6 +219,7 @@ static int wireguard_set_interface(NetDev *netdev) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
WireguardIPmask *mask_start = NULL; WireguardIPmask *mask_start = NULL;
WireguardPeer *peer, *peer_start; WireguardPeer *peer, *peer_start;
bool sent_once = false;
uint32_t serial; uint32_t serial;
Wireguard *w; Wireguard *w;
int r; int r;
@ -227,7 +228,7 @@ static int wireguard_set_interface(NetDev *netdev) {
w = WIREGUARD(netdev); w = WIREGUARD(netdev);
assert(w); assert(w);
for (peer_start = w->peers; peer_start; ) { for (peer_start = w->peers; peer_start || !sent_once; ) {
uint16_t i = 0; uint16_t i = 0;
message = sd_netlink_message_unref(message); message = sd_netlink_message_unref(message);
@ -278,6 +279,8 @@ static int wireguard_set_interface(NetDev *netdev) {
r = sd_netlink_send(netdev->manager->genl, message, &serial); r = sd_netlink_send(netdev->manager->genl, message, &serial);
if (r < 0) if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not set wireguard device: %m"); return log_netdev_error_errno(netdev, r, "Could not set wireguard device: %m");
sent_once = true;
} }
return 0; return 0;

View File

@ -437,13 +437,13 @@ int config_parse_dhcp_send_option(
_cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL, *old4 = NULL; _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *opt4 = NULL, *old4 = NULL;
_cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL, *old6 = NULL; _cleanup_(sd_dhcp6_option_unrefp) sd_dhcp6_option *opt6 = NULL, *old6 = NULL;
uint32_t uint32_data, enterprise_identifier = 0;
_cleanup_free_ char *word = NULL, *q = NULL; _cleanup_free_ char *word = NULL, *q = NULL;
OrderedHashmap **options = data; OrderedHashmap **options = data;
uint16_t u16, uint16_data;
union in_addr_union addr; union in_addr_union addr;
DHCPOptionDataType type; DHCPOptionDataType type;
uint8_t u8, uint8_data; uint8_t u8, uint8_data;
uint16_t u16, uint16_data;
uint32_t uint32_data;
const void *udata; const void *udata;
const char *p; const char *p;
ssize_t sz; ssize_t sz;
@ -460,10 +460,29 @@ int config_parse_dhcp_send_option(
} }
p = rvalue; p = rvalue;
if (ltype == AF_INET6 && streq(lvalue, "SendVendorOption")) {
r = extract_first_word(&p, &word, ":", 0); r = extract_first_word(&p, &word, ":", 0);
if (r == -ENOMEM) if (r == -ENOMEM)
return log_oom(); return log_oom();
if (r <= 0) { if (r <= 0 || isempty(p)) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid DHCP option, ignoring assignment: %s", rvalue);
return 0;
}
r = safe_atou32(word, &enterprise_identifier);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse DHCPv6 enterprise identifier data, ignoring assignment: %s", p);
return 0;
}
word = mfree(word);
}
r = extract_first_word(&p, &word, ":", 0);
if (r == -ENOMEM)
return log_oom();
if (r <= 0 || isempty(p)) {
log_syntax(unit, LOG_ERR, filename, line, r, log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid DHCP option, ignoring assignment: %s", rvalue); "Invalid DHCP option, ignoring assignment: %s", rvalue);
return 0; return 0;
@ -588,7 +607,7 @@ int config_parse_dhcp_send_option(
} }
if (ltype == AF_INET6) { if (ltype == AF_INET6) {
r = sd_dhcp6_option_new(u16, udata, sz, &opt6); r = sd_dhcp6_option_new(u16, udata, sz, enterprise_identifier, &opt6);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store DHCP option '%s', ignoring assignment: %m", rvalue); "Failed to store DHCP option '%s', ignoring assignment: %m", rvalue);

View File

@ -756,6 +756,7 @@ static int dhcp6_set_hostname(sd_dhcp6_client *client, Link *link) {
int dhcp6_configure(Link *link) { int dhcp6_configure(Link *link) {
_cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL; _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL;
sd_dhcp6_option *vendor_option;
sd_dhcp6_option *send_option; sd_dhcp6_option *send_option;
void *request_options; void *request_options;
const DUID *duid; const DUID *duid;
@ -854,6 +855,14 @@ int dhcp6_configure(Link *link) {
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set vendor class: %m"); return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set vendor class: %m");
} }
ORDERED_HASHMAP_FOREACH(vendor_option, link->network->dhcp6_client_send_vendor_options, i) {
r = sd_dhcp6_client_add_vendor_option(client, vendor_option);
if (r == -EEXIST)
continue;
if (r < 0)
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set vendor option: %m");
}
r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set callback: %m"); return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set callback: %m");

View File

@ -198,6 +198,7 @@ DHCPv6.MUDURL, config_parse_dhcp6_mud_url,
DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0 DHCPv6.RequestOptions, config_parse_dhcp_request_options, AF_INET6, 0
DHCPv6.UserClass, config_parse_dhcp_user_class, AF_INET6, offsetof(Network, dhcp6_user_class) DHCPv6.UserClass, config_parse_dhcp_user_class, AF_INET6, offsetof(Network, dhcp6_user_class)
DHCPv6.VendorClass, config_parse_dhcp_vendor_class, 0, offsetof(Network, dhcp6_vendor_class) DHCPv6.VendorClass, config_parse_dhcp_vendor_class, 0, offsetof(Network, dhcp6_vendor_class)
DHCPv6.SendVendorOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_vendor_options)
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign_prefix) DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign_prefix)
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0

View File

@ -752,6 +752,8 @@ static Network *network_free(Network *network) {
ordered_hashmap_free(network->dhcp_server_send_options); ordered_hashmap_free(network->dhcp_server_send_options);
ordered_hashmap_free(network->dhcp_server_send_vendor_options); ordered_hashmap_free(network->dhcp_server_send_vendor_options);
ordered_hashmap_free(network->ipv6_tokens); ordered_hashmap_free(network->ipv6_tokens);
ordered_hashmap_free(network->dhcp6_client_send_options);
ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
return mfree(network); return mfree(network);
} }

View File

@ -137,6 +137,7 @@ struct Network {
char **dhcp6_vendor_class; char **dhcp6_vendor_class;
struct in6_addr dhcp6_pd_address; struct in6_addr dhcp6_pd_address;
OrderedHashmap *dhcp6_client_send_options; OrderedHashmap *dhcp6_client_send_options;
OrderedHashmap *dhcp6_client_send_vendor_options;
Set *dhcp6_request_options; Set *dhcp6_request_options;
/* DHCP Server Support */ /* DHCP Server Support */

View File

@ -24,6 +24,7 @@ _not_installed_headers = '''
sd-dhcp-client.h sd-dhcp-client.h
sd-dhcp-lease.h sd-dhcp-lease.h
sd-dhcp-option.h sd-dhcp-option.h
sd-dhcp6-option.h
sd-dhcp-server.h sd-dhcp-server.h
sd-ipv4acd.h sd-ipv4acd.h
sd-ipv4ll.h sd-ipv4ll.h

View File

@ -143,7 +143,10 @@ int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client,
int *request); int *request);
int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client,
int request); int request);
int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client, uint32_t transaction_id); int sd_dhcp6_client_set_transaction_id(sd_dhcp6_client *client,
uint32_t transaction_id);
int sd_dhcp6_client_add_vendor_option(sd_dhcp6_client *client,
sd_dhcp6_option *v);
int sd_dhcp6_client_get_lease( int sd_dhcp6_client_get_lease(
sd_dhcp6_client *client, sd_dhcp6_client *client,

View File

@ -26,7 +26,7 @@ _SD_BEGIN_DECLARATIONS;
typedef struct sd_dhcp6_option sd_dhcp6_option; typedef struct sd_dhcp6_option sd_dhcp6_option;
int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, sd_dhcp6_option **ret); int sd_dhcp6_option_new(uint16_t option, const void *data, size_t length, uint32_t enterprise_identifier, sd_dhcp6_option **ret);
sd_dhcp6_option *sd_dhcp6_option_ref(sd_dhcp6_option *ra); sd_dhcp6_option *sd_dhcp6_option_ref(sd_dhcp6_option *ra);
sd_dhcp6_option *sd_dhcp6_option_unref(sd_dhcp6_option *ra); sd_dhcp6_option *sd_dhcp6_option_unref(sd_dhcp6_option *ra);

View File

@ -48,9 +48,19 @@ static void test_parse_uid(void) {
r = parse_uid("65535", &uid); r = parse_uid("65535", &uid);
assert_se(r == -ENXIO); assert_se(r == -ENXIO);
assert_se(uid == 100);
r = parse_uid("0x1234", &uid);
assert_se(r == -EINVAL);
assert_se(uid == 100);
r = parse_uid("01234", &uid);
assert_se(r == 0);
assert_se(uid == 1234);
r = parse_uid("asdsdas", &uid); r = parse_uid("asdsdas", &uid);
assert_se(r == -EINVAL); assert_se(r == -EINVAL);
assert_se(uid == 1234);
} }
static void test_uid_ptr(void) { static void test_uid_ptr(void) {

View File

@ -13,10 +13,9 @@ udevadm_sources = files('''
udevadm-trigger.c udevadm-trigger.c
udevadm-util.c udevadm-util.c
udevadm-util.h udevadm-util.h
udevd.c
'''.split()) '''.split())
systemd_udevd_sources = files('udevd.c')
libudev_core_sources = ''' libudev_core_sources = '''
udev-ctrl.c udev-ctrl.c
udev-ctrl.h udev-ctrl.h

View File

@ -11,6 +11,7 @@
#include "selinux-util.h" #include "selinux-util.h"
#include "string-util.h" #include "string-util.h"
#include "udevadm.h" #include "udevadm.h"
#include "udevd.h"
#include "udev-util.h" #include "udev-util.h"
#include "verbs.h" #include "verbs.h"
#include "util.h" #include "util.h"
@ -110,6 +111,9 @@ static int udevadm_main(int argc, char *argv[]) {
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
int r; int r;
if (strstr(program_invocation_short_name, "udevd"))
return run_udevd(argc, argv);
udev_parse_config(); udev_parse_config();
log_parse_environment(); log_parse_environment();
log_open(); log_open();

View File

@ -59,6 +59,7 @@
#include "strv.h" #include "strv.h"
#include "strxcpyx.h" #include "strxcpyx.h"
#include "syslog-util.h" #include "syslog-util.h"
#include "udevd.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#include "udev-ctrl.h" #include "udev-ctrl.h"
#include "udev-event.h" #include "udev-event.h"
@ -1472,7 +1473,7 @@ static int help(void) {
return log_oom(); return log_oom();
printf("%s [OPTIONS...]\n\n" printf("%s [OPTIONS...]\n\n"
"Manages devices.\n\n" "Rule-based manager for device events and files.\n\n"
" -h --help Print this message\n" " -h --help Print this message\n"
" -V --version Print version of the program\n" " -V --version Print version of the program\n"
" -d --daemon Detach and run in the background\n" " -d --daemon Detach and run in the background\n"
@ -1713,7 +1714,7 @@ static int main_loop(Manager *manager) {
return r; return r;
} }
static int run(int argc, char *argv[]) { int run_udevd(int argc, char *argv[]) {
_cleanup_free_ char *cgroup = NULL; _cleanup_free_ char *cgroup = NULL;
_cleanup_(manager_freep) Manager *manager = NULL; _cleanup_(manager_freep) Manager *manager = NULL;
int fd_ctrl = -1, fd_uevent = -1; int fd_ctrl = -1, fd_uevent = -1;
@ -1828,5 +1829,3 @@ static int run(int argc, char *argv[]) {
return main_loop(manager); return main_loop(manager);
} }
DEFINE_MAIN_FUNCTION(run);

4
src/udev/udevd.h Normal file
View File

@ -0,0 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
int run_udevd(int argc, char *argv[]);

View File

@ -0,0 +1,10 @@
[NetDev]
Name=o
Kind=macsec
[MACsecReceiveChannel]
MACAddress=12.0.4
Port=913
[MACsecReceiveChannel]
MACAddress=12.0.4
Port=913

View File

@ -120,6 +120,7 @@ RequestOptions=
UserClass= UserClass=
VendorClass= VendorClass=
AssignAcquiredDelegatedPrefixAddress= AssignAcquiredDelegatedPrefixAddress=
SendVendorOption=
[Route] [Route]
Destination= Destination=
Protocol= Protocol=

View File

@ -0,0 +1,8 @@
[NetDev]
Name=wg97
Kind=wireguard
[WireGuard]
PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=
ListenPort=51821
FwMark=1235

View File

@ -0,0 +1,2 @@
[Match]
Name=wg97

View File

@ -746,6 +746,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'vtitun99', 'vtitun99',
'vxcan99', 'vxcan99',
'vxlan99', 'vxlan99',
'wg97',
'wg98', 'wg98',
'wg99', 'wg99',
] ]
@ -832,6 +833,8 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'25-vxlan.netdev', '25-vxlan.netdev',
'25-wireguard-23-peers.netdev', '25-wireguard-23-peers.netdev',
'25-wireguard-23-peers.network', '25-wireguard-23-peers.network',
'25-wireguard-no-peer.netdev',
'25-wireguard-no-peer.network',
'25-wireguard-preshared-key.txt', '25-wireguard-preshared-key.txt',
'25-wireguard-private-key.txt', '25-wireguard-private-key.txt',
'25-wireguard.netdev', '25-wireguard.netdev',
@ -1115,9 +1118,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
def test_wireguard(self): def test_wireguard(self):
copy_unit_to_networkd_unit_path('25-wireguard.netdev', '25-wireguard.network', copy_unit_to_networkd_unit_path('25-wireguard.netdev', '25-wireguard.network',
'25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network', '25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
'25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt') '25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt',
'25-wireguard-no-peer.netdev', '25-wireguard-no-peer.network')
start_networkd() start_networkd()
self.wait_online(['wg99:carrier', 'wg98:routable']) self.wait_online(['wg99:carrier', 'wg98:routable', 'wg97:carrier'])
if shutil.which('wg'): if shutil.which('wg'):
call('wg') call('wg')
@ -1142,6 +1146,11 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = check_output('wg show wg98 private-key') output = check_output('wg show wg98 private-key')
self.assertRegex(output, r'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr\+WHtZLZ90FU=') self.assertRegex(output, r'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr\+WHtZLZ90FU=')
output = check_output('wg show wg97 listen-port')
self.assertRegex(output, '51821')
output = check_output('wg show wg97 fwmark')
self.assertRegex(output, '0x4d3')
def test_geneve(self): def test_geneve(self):
copy_unit_to_networkd_unit_path('25-geneve.netdev', 'netdev-link-local-addressing-yes.network') copy_unit_to_networkd_unit_path('25-geneve.netdev', 'netdev-link-local-addressing-yes.network')
start_networkd() start_networkd()

View File

@ -8,7 +8,7 @@
# (at your option) any later version. # (at your option) any later version.
[Unit] [Unit]
Description=udev Kernel Device Manager Description=Rule-based manager for device events and files
Documentation=man:systemd-udevd.service(8) man:udev(7) Documentation=man:systemd-udevd.service(8) man:udev(7)
DefaultDependencies=no DefaultDependencies=no
After=systemd-sysusers.service systemd-hwdb-update.service After=systemd-sysusers.service systemd-hwdb-update.service