Compare commits

..

14 Commits

Author SHA1 Message Date
Yu Watanabe 7f16ef9fba
Merge pull request #16490 from yuwata/network-radv-ndisc-cleanups
network: cleanups for radv and ndisc
2020-07-17 15:12:53 +09:00
Zbigniew Jędrzejewski-Szmek dc9e9a18be
Merge pull request #16491 from keszybz/udev-logging
Improvements to udev logging and related code
2020-07-17 07:12:58 +02:00
Zbigniew Jędrzejewski-Szmek 9e79123884 tree-wide: use SYNTHETIC_ERRNO with log_device_* in more places 2020-07-16 22:08:12 +02:00
Zbigniew Jędrzejewski-Szmek 46d4149d0f sd-device: use LOG_PRI() in log_device_full()
We use LOG_PRI() in all log_*() functions, so let's do that here too for
consistency. Effectively this doesn't change anything since we only use
LOG_{INFO,DEBUG,...} as the argument.
2020-07-16 22:05:21 +02:00
Zbigniew Jędrzejewski-Szmek d6d4961b01 udev: don't complain when udev_watch_end() is called without udev_watch_init()
E.g. udevadm test prints "Invalid inotify descriptor." which is
meaningless without any context. I think it should be OK to call udev_watch_end()
from a cleanup path without any warning (even at debug level).
2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek 6b9f5f01cb basic/string-table: reduce variable scope 2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek 5992f362bf udevadm: use STR_IN_SET(), add comment 2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek fe20121a4c sd-device: use strjoin instead of asprintf
strjoin should be faster for string concatenation.
Also drop "_"-prefix from function prototypes.
2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek 22ba4525d3 udev: tweak debug logs for udev rules
We shouldn't say "ignoring" when running a program because the result is used for
the match/nomatch result of the rule.
2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek 12254ccab0 man: add more details for IMPORT, PROGRAM and RUN keys
967de8face added a note that I found very hard
to understand. Reword it, and also describe how IMPORT and PROGRAM are different
from RUN.

Minor markup adjustements too.
2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek ba60127df7 udev: accept OPTIONS+= without any fuss
There is no reason to consider this wrong. In fact one could argue that +=
is more appropriate, because we always add to options, and not replace previous
assignments. If we output a debug message, we implicitly ask people to "fix" this,
and we shouldn't.

Also, all our rules use += right now.
2020-07-16 18:38:03 +02:00
Zbigniew Jędrzejewski-Szmek b6a80b83bc udev: accept IMPORT{}= without any fuss
Udev logs are full of messages about wrong operator type:
...
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage.rules
/usr/lib/udev/rules.d/60-persistent-storage.rules:30 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:30 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:30 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:30 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:30 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:30 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:54 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:57 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:60 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:63 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:66 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:67 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:93 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:107 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:110 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-storage.rules:113 IMPORT key takes '==' or '!=' operator, assuming '=='.
Reading rules file: /usr/lib/udev/rules.d/60-persistent-v4l.rules
/usr/lib/udev/rules.d/60-persistent-v4l.rules:7 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-v4l.rules:9 IMPORT key takes '==' or '!=' operator, assuming '=='.
/usr/lib/udev/rules.d/60-persistent-v4l.rules:16 IMPORT key takes '==' or '!=' operator, assuming '=='.
...

The warning was downgraded in f0beb6f816, but I
think it should be removed altogether. IMPORT{program}="asdf" seems like an
obvious way to write this, and people don't expect to have to write "==".
So let's just allow any operator.
2020-07-16 18:38:03 +02:00
Yu Watanabe 13e8a49a58 network: ndisc: any failures in processing event make the link in failed state
Also adjust log levels.
2020-07-17 01:18:44 +09:00
Yu Watanabe c97785168b network: radv: clean up conf parsers 2020-07-17 01:16:38 +09:00
15 changed files with 267 additions and 296 deletions

View File

@ -280,13 +280,17 @@
<varlistentry> <varlistentry>
<term><varname>PROGRAM</varname></term> <term><varname>PROGRAM</varname></term>
<listitem> <listitem>
<para>Execute a program to determine whether there <para>Execute a program to determine whether there is a match; the key is true if the program
is a match; the key is true if the program returns returns successfully. The device properties are made available to the executed program in the
successfully. The device properties are made available to the environment. The program's standard output is available in the <varname>RESULT</varname>
executed program in the environment. The program's standard output key.</para>
is available in the <varname>RESULT</varname> key.</para>
<para>This can only be used for very short-running foreground tasks. For details, <para>This can only be used for very short-running foreground tasks. For details, see
see <varname>RUN</varname>.</para> <varname>RUN</varname>.</para>
<para>Note that multiple <varname>PROGRAM</varname> keys may be specified in one rule, and
<literal>=</literal>, <literal>:=</literal>, and <literal>+=</literal> have the same effect as
<literal>==</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -429,9 +433,14 @@
<varlistentry> <varlistentry>
<term><varname>RUN{<replaceable>type</replaceable>}</varname></term> <term><varname>RUN{<replaceable>type</replaceable>}</varname></term>
<listitem> <listitem>
<para>Add a program to the list of programs to be executed after <para>Specify a program to be executed after processing of all the rules for the event. With
processing all the rules for a specific event, depending on <literal>+=</literal>, this invocation is added to the list, and with <literal>=</literal> or
<literal>type</literal>:</para> <literal>:=</literal>, it replaces any previous contents of the list. Please note that both
<literal>program</literal> and <literal>builtin</literal> types described below use a single
list, so clearing the list with <literal>:=</literal> and <literal>=</literal> affects both
types.</para>
<para><replaceable>type</replaceable> may be:</para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>program</literal></term> <term><literal>program</literal></term>
@ -452,21 +461,21 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para>The program name and following arguments are separated by spaces.
Single quotes can be used to specify arguments with spaces.</para> <para>The program name and following arguments are separated by spaces. Single quotes can be
<para>This can only be used for very short-running foreground tasks. Running an used to specify arguments with spaces.</para>
event process for a long period of time may block all further events for
this or a dependent device.</para> <para>This can only be used for very short-running foreground tasks. Running an event process for
<para>Starting daemons or other long-running processes is not appropriate a long period of time may block all further events for this or a dependent device.</para>
for udev; the forked processes, detached or not, will be unconditionally
killed after the event handling has finished.</para> <para>Note that running programs that access the network or mount/unmount filesystems is not
<para>Note that running programs that access the network or mount/unmount allowed inside of udev rules, due to the default sandbox that is enforced on
filesystems is not allowed inside of udev rules, due to the default sandbox <filename>systemd-udevd.service</filename>.</para>
that is enforced on <filename>systemd-udevd.service</filename>.</para>
<para>Please also note that <literal>:=</literal> and <literal>=</literal> are clearing <para>Starting daemons or other long-running processes is not allowed; the forked processes,
both, program and builtin commands.</para> detached or not, will be unconditionally killed after the event handling has finished. In order
<para>In order to activate long-running processes from udev rules, provide a service unit, and to activate long-running processes from udev rules, provide a service unit and pull it in from a
pull it in from a udev device using the <varname>SYSTEMD_WANTS</varname> device property. See udev device using the <varname>SYSTEMD_WANTS</varname> device property. See
<citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para> for details.</para>
</listitem> </listitem>
@ -489,8 +498,9 @@
<varlistentry> <varlistentry>
<term><varname>IMPORT{<replaceable>type</replaceable>}</varname></term> <term><varname>IMPORT{<replaceable>type</replaceable>}</varname></term>
<listitem> <listitem>
<para>Import a set of variables as device properties, <para>Import a set of variables as device properties, depending on
depending on <literal>type</literal>:</para> <replaceable>type</replaceable>:</para>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><literal>program</literal></term> <term><literal>program</literal></term>
@ -542,8 +552,14 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para>This can only be used for very short-running foreground tasks. For details
see <option>RUN</option>.</para> <para>This can only be used for very short-running foreground tasks. For details see
<option>RUN</option>.</para>
<para>Note that multiple <varname>IMPORT{}</varname> keys may be specified in one rule, and
<literal>=</literal>, <literal>:=</literal>, and <literal>+=</literal> have the same effect as
<literal>==</literal>. The key is true if the import is successful, unless <literal>!=</literal>
is used as the operator which causes the key to be true if the import failed.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -633,9 +649,8 @@
<varlistentry> <varlistentry>
<term><option>$number</option>, <option>%n</option></term> <term><option>$number</option>, <option>%n</option></term>
<listitem> <listitem>
<para>The kernel number for this device. For example, <para>The kernel number for this device. For example, <literal>sda3</literal> has kernel number
<literal>sda3</literal> has kernel number <literal>3</literal>. 3.</para>
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -4,12 +4,10 @@
#include "string-util.h" #include "string-util.h"
ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) { ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
size_t i;
if (!key) if (!key)
return -1; return -1;
for (i = 0; i < len; ++i) for (size_t i = 0; i < len; ++i)
if (streq_ptr(table[i], key)) if (streq_ptr(table[i], key))
return (ssize_t) i; return (ssize_t) i;

View File

@ -94,8 +94,8 @@ int device_read_uevent_file(sd_device *device);
int device_set_syspath(sd_device *device, const char *_syspath, bool verify); int device_set_syspath(sd_device *device, const char *_syspath, bool verify);
int device_set_ifindex(sd_device *device, const char *ifindex); int device_set_ifindex(sd_device *device, const char *ifindex);
int device_set_devmode(sd_device *device, const char *devmode); int device_set_devmode(sd_device *device, const char *devmode);
int device_set_devname(sd_device *device, const char *_devname); int device_set_devname(sd_device *device, const char *devname);
int device_set_devtype(sd_device *device, const char *_devtype); int device_set_devtype(sd_device *device, const char *devtype);
int device_set_devnum(sd_device *device, const char *major, const char *minor); int device_set_devnum(sd_device *device, const char *major, const char *minor);
int device_set_subsystem(sd_device *device, const char *_subsystem); int device_set_subsystem(sd_device *device, const char *_subsystem);
int device_set_driver(sd_device *device, const char *_driver); int device_set_driver(sd_device *device, const char *_driver);

View File

@ -558,10 +558,9 @@ int device_monitor_send_device(
r = device_get_properties_nulstr(device, (const uint8_t **) &buf, &blen); r = device_get_properties_nulstr(device, (const uint8_t **) &buf, &blen);
if (r < 0) if (r < 0)
return log_device_debug_errno(device, r, "sd-device-monitor: Failed to get device properties: %m"); return log_device_debug_errno(device, r, "sd-device-monitor: Failed to get device properties: %m");
if (blen < 32) { if (blen < 32)
log_device_debug(device, "sd-device-monitor: Length of device property nulstr is too small to contain valid device information"); log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
return -EINVAL; "sd-device-monitor: Length of device property nulstr is too small to contain valid device information");
}
/* fill in versioned header */ /* fill in versioned header */
r = sd_device_get_subsystem(device, &val); r = sd_device_get_subsystem(device, &val);

View File

@ -363,10 +363,9 @@ static int device_append(sd_device *device, char *key, const char **_major, cons
assert(_minor); assert(_minor);
value = strchr(key, '='); value = strchr(key, '=');
if (!value) { if (!value)
log_device_debug(device, "sd-device: Not a key-value pair: '%s'", key); return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
return -EINVAL; "sd-device: Not a key-value pair: '%s'", key);
}
*value = '\0'; *value = '\0';
@ -400,10 +399,9 @@ void device_seal(sd_device *device) {
static int device_verify(sd_device *device) { static int device_verify(sd_device *device) {
assert(device); assert(device);
if (!device->devpath || !device->subsystem || device->action < 0 || device->seqnum == 0) { if (!device->devpath || !device->subsystem || device->action < 0 || device->seqnum == 0)
log_device_debug(device, "sd-device: Device created from strv or nulstr lacks devpath, subsystem, action or seqnum."); return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
return -EINVAL; "sd-device: Device created from strv or nulstr lacks devpath, subsystem, action or seqnum.");
}
device->sealed = true; device->sealed = true;
@ -464,10 +462,10 @@ int device_new_from_nulstr(sd_device **ret, uint8_t *nulstr, size_t len) {
key = (char*)&nulstr[i]; key = (char*)&nulstr[i];
end = memchr(key, '\0', len - i); end = memchr(key, '\0', len - i);
if (!end) { if (!end)
log_device_debug(device, "sd-device: Failed to parse nulstr"); return log_device_debug_errno(device, SYNTHETIC_ERRNO(EINVAL),
return -EINVAL; "sd-device: Failed to parse nulstr");
}
i += end - key + 1; i += end - key + 1;
r = device_append(device, key, &major, &minor); r = device_append(device, key, &major, &minor);

View File

@ -37,7 +37,7 @@
sd_device *_d = (device); \ sd_device *_d = (device); \
int _level = (level), _error = (error); \ int _level = (level), _error = (error); \
\ \
if (_d && _unlikely_(log_get_max_level() >= _level)) \ if (_d && _unlikely_(log_get_max_level() >= LOG_PRI(_level))) \
(void) sd_device_get_sysname(_d, &_sysname); \ (void) sd_device_get_sysname(_d, &_sysname); \
log_object_internal(_level, _error, PROJECT_FILE, __LINE__, __func__, \ log_object_internal(_level, _error, PROJECT_FILE, __LINE__, __func__, \
_sysname ? "DEVICE=" : NULL, _sysname, \ _sysname ? "DEVICE=" : NULL, _sysname, \

View File

@ -320,24 +320,22 @@ _public_ int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *s
return -ENODEV; return -ENODEV;
} }
int device_set_devtype(sd_device *device, const char *_devtype) { int device_set_devtype(sd_device *device, const char *devtype) {
_cleanup_free_ char *devtype = NULL; _cleanup_free_ char *t = NULL;
int r; int r;
assert(device); assert(device);
assert(_devtype); assert(devtype);
devtype = strdup(_devtype); t = strdup(devtype);
if (!devtype) if (!t)
return -ENOMEM; return -ENOMEM;
r = device_add_property_internal(device, "DEVTYPE", devtype); r = device_add_property_internal(device, "DEVTYPE", t);
if (r < 0) if (r < 0)
return r; return r;
free_and_replace(device->devtype, devtype); return free_and_replace(device->devtype, t);
return 0;
} }
int device_set_ifindex(sd_device *device, const char *name) { int device_set_ifindex(sd_device *device, const char *name) {
@ -359,30 +357,25 @@ int device_set_ifindex(sd_device *device, const char *name) {
return 0; return 0;
} }
int device_set_devname(sd_device *device, const char *_devname) { int device_set_devname(sd_device *device, const char *devname) {
_cleanup_free_ char *devname = NULL; _cleanup_free_ char *t = NULL;
int r; int r;
assert(device); assert(device);
assert(_devname); assert(devname);
if (_devname[0] != '/') { if (devname[0] != '/')
r = asprintf(&devname, "/dev/%s", _devname); t = strjoin("/dev/", devname);
if (r < 0) else
return -ENOMEM; t = strdup(devname);
} else { if (!t)
devname = strdup(_devname); return -ENOMEM;
if (!devname)
return -ENOMEM;
}
r = device_add_property_internal(device, "DEVNAME", devname); r = device_add_property_internal(device, "DEVNAME", t);
if (r < 0) if (r < 0)
return r; return r;
free_and_replace(device->devname, devname); return free_and_replace(device->devname, t);
return 0;
} }
int device_set_devmode(sd_device *device, const char *_devmode) { int device_set_devmode(sd_device *device, const char *_devmode) {
@ -1250,17 +1243,15 @@ int device_get_id_filename(sd_device *device, const char **ret) {
if (!subsystem) if (!subsystem)
return -EINVAL; return -EINVAL;
if (streq(subsystem, "drivers")) {
if (streq(subsystem, "drivers"))
/* the 'drivers' pseudo-subsystem is special, and needs the real subsystem /* the 'drivers' pseudo-subsystem is special, and needs the real subsystem
* encoded as well */ * encoded as well */
r = asprintf(&id, "+drivers:%s:%s", device->driver_subsystem, sysname); id = strjoin("+drivers:", device->driver_subsystem, ":", sysname);
if (r < 0) else
return -ENOMEM; id = strjoin("+", subsystem, ":", sysname);
} else { if (!id)
r = asprintf(&id, "+%s:%s", subsystem, sysname); return -ENOMEM;
if (r < 0)
return -ENOMEM;
}
} }
device->id_filename = TAKE_PTR(id); device->id_filename = TAKE_PTR(id);

View File

@ -936,10 +936,9 @@ static int umount_by_device(sd_bus *bus, const char *what) {
if (r < 0) if (r < 0)
return log_device_error_errno(d, r, "Failed to get device property: %m"); return log_device_error_errno(d, r, "Failed to get device property: %m");
if (!streq(v, "filesystem")) { if (!streq(v, "filesystem"))
log_device_error(d, "%s does not contain a known file system.", what); return log_device_error_errno(d, SYNTHETIC_ERRNO(EINVAL),
return -EINVAL; "%s does not contain a known file system.", what);
}
if (sd_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE", &v) >= 0) if (sd_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE", &v) >= 0)
r2 = stop_mounts(bus, v); r2 = stop_mounts(bus, v);
@ -1275,10 +1274,9 @@ static int discover_loop_backing_file(void) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get device from device number: %m"); return log_error_errno(r, "Failed to get device from device number: %m");
if (sd_device_get_property_value(d, "ID_FS_USAGE", &v) < 0 || !streq(v, "filesystem")) { if (sd_device_get_property_value(d, "ID_FS_USAGE", &v) < 0 || !streq(v, "filesystem"))
log_device_error(d, "%s does not contain a known file system.", arg_mount_what); return log_device_error_errno(d, SYNTHETIC_ERRNO(EINVAL),
return -EINVAL; "%s does not contain a known file system.", arg_mount_what);
}
r = acquire_mount_type(d); r = acquire_mount_type(d);
if (r < 0) if (r < 0)

View File

@ -148,33 +148,35 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
unsigned preference; unsigned preference;
uint32_t mtu; uint32_t mtu;
usec_t time_now; usec_t time_now;
int r;
Address *address; Address *address;
Iterator i; Iterator i;
int r;
assert(link); assert(link);
assert(rt); assert(rt);
r = sd_ndisc_router_get_lifetime(rt, &lifetime); r = sd_ndisc_router_get_lifetime(rt, &lifetime);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); return log_link_error_errno(link, r, "Failed to get gateway lifetime from RA: %m");
if (lifetime == 0) /* not a default router */ if (lifetime == 0) /* not a default router */
return 0; return 0;
r = sd_ndisc_router_get_address(rt, &gateway.in6); r = sd_ndisc_router_get_address(rt, &gateway.in6);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
SET_FOREACH(address, link->addresses, i) { SET_FOREACH(address, link->addresses, i) {
if (address->family != AF_INET6) if (address->family != AF_INET6)
continue; continue;
if (in_addr_equal(AF_INET6, &gateway, &address->in_addr)) { if (in_addr_equal(AF_INET6, &gateway, &address->in_addr)) {
_cleanup_free_ char *buffer = NULL; if (DEBUG_LOGGING) {
_cleanup_free_ char *buffer = NULL;
(void) in_addr_to_string(AF_INET6, &address->in_addr, &buffer); (void) in_addr_to_string(AF_INET6, &address->in_addr, &buffer);
log_link_debug(link, "No NDisc route added, gateway %s matches local address", log_link_debug(link, "No NDisc route added, gateway %s matches local address",
strnull(buffer)); strnull(buffer));
}
return 0; return 0;
} }
} }
@ -183,32 +185,34 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (address->family != AF_INET6) if (address->family != AF_INET6)
continue; continue;
if (in_addr_equal(AF_INET6, &gateway, &address->in_addr)) { if (in_addr_equal(AF_INET6, &gateway, &address->in_addr)) {
_cleanup_free_ char *buffer = NULL; if (DEBUG_LOGGING) {
_cleanup_free_ char *buffer = NULL;
(void) in_addr_to_string(AF_INET6, &address->in_addr, &buffer); (void) in_addr_to_string(AF_INET6, &address->in_addr, &buffer);
log_link_debug(link, "No NDisc route added, gateway %s matches local address", log_link_debug(link, "No NDisc route added, gateway %s matches local address",
strnull(buffer)); strnull(buffer));
}
return 0; return 0;
} }
} }
r = sd_ndisc_router_get_preference(rt, &preference); r = sd_ndisc_router_get_preference(rt, &preference);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); return log_link_error_errno(link, r, "Failed to get default router preference from RA: %m");
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
r = sd_ndisc_router_get_mtu(rt, &mtu); r = sd_ndisc_router_get_mtu(rt, &mtu);
if (r == -ENODATA) if (r == -ENODATA)
mtu = 0; mtu = 0;
else if (r < 0) else if (r < 0)
return log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m"); return log_link_error_errno(link, r, "Failed to get default router MTU from RA: %m");
r = route_new(&route); r = route_new(&route);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m"); return log_oom();
route->family = AF_INET6; route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link); route->table = link_get_ipv6_accept_ra_route_table(link);
@ -220,11 +224,8 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route->mtu = mtu; route->mtu = mtu;
r = route_configure(route, link, ndisc_route_handler); r = route_configure(route, link, ndisc_route_handler);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Could not set default route: %m"); return log_link_error_errno(link, r, "Could not set default route: %m");
link_enter_failed(link);
return r;
}
if (r > 0) if (r > 0)
link->ndisc_routes_messages++; link->ndisc_routes_messages++;
@ -239,11 +240,8 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route_gw->gw = gateway; route_gw->gw = gateway;
r = route_configure(route_gw, link, ndisc_route_handler); r = route_configure(route_gw, link, ndisc_route_handler);
if (r < 0) { if (r < 0)
log_link_error_errno(link, r, "Could not set gateway: %m"); return log_link_error_errno(link, r, "Could not set gateway: %m");
link_enter_failed(link);
return r;
}
if (r > 0) if (r > 0)
link->ndisc_routes_messages++; link->ndisc_routes_messages++;
} }
@ -306,7 +304,7 @@ static int ndisc_router_generate_addresses(Link *link, unsigned prefixlen, uint3
r = set_put(addresses, new_address); r = set_put(addresses, new_address);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to store address: %m"); return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
TAKE_PTR(new_address); TAKE_PTR(new_address);
} }
} }
@ -331,7 +329,7 @@ static int ndisc_router_generate_addresses(Link *link, unsigned prefixlen, uint3
r = set_put(addresses, new_address); r = set_put(addresses, new_address);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to store address: %m"); return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
TAKE_PTR(new_address); TAKE_PTR(new_address);
} }
@ -346,7 +344,7 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
_cleanup_(address_freep) Address *address = NULL; _cleanup_(address_freep) Address *address = NULL;
unsigned prefixlen; unsigned prefixlen;
usec_t time_now; usec_t time_now;
Address *existing_address, *a; Address *a;
Iterator i; Iterator i;
int r; int r;
@ -355,7 +353,7 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen); r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
if (r < 0) if (r < 0)
@ -375,7 +373,7 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
r = address_new(&address); r = address_new(&address);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not allocate address: %m"); return log_oom();
address->family = AF_INET6; address->family = AF_INET6;
r = sd_ndisc_router_prefix_get_address(rt, &address->in_addr.in6); r = sd_ndisc_router_prefix_get_address(rt, &address->in_addr.in6);
@ -384,9 +382,11 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
r = ndisc_router_generate_addresses(link, prefixlen, lifetime_preferred, address, &addresses); r = ndisc_router_generate_addresses(link, prefixlen, lifetime_preferred, address, &addresses);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to generate SLAAC addresses: %m"); return r;
SET_FOREACH(a, addresses, i) { SET_FOREACH(a, addresses, i) {
Address *existing_address;
/* see RFC4862 section 5.5.3.e */ /* see RFC4862 section 5.5.3.e */
r = address_get(link, a->family, &a->in_addr, a->prefixlen, &existing_address); r = address_get(link, a->family, &a->in_addr, a->prefixlen, &existing_address);
if (r > 0) { if (r > 0) {
@ -406,11 +406,8 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
continue; continue;
r = address_configure(a, link, ndisc_address_handler, true); r = address_configure(a, link, ndisc_address_handler, true);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Could not set SLAAC address: %m"); return log_link_error_errno(link, r, "Could not set SLAAC address: %m");
link_enter_failed(link);
return r;
}
if (r > 0) if (r > 0)
link->ndisc_addresses_messages++; link->ndisc_addresses_messages++;
} }
@ -430,7 +427,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen); r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
if (r < 0) if (r < 0)
@ -442,7 +439,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
r = route_new(&route); r = route_new(&route);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m"); return log_oom();
route->family = AF_INET6; route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link); route->table = link_get_ipv6_accept_ra_route_table(link);
@ -457,11 +454,8 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
return log_link_error_errno(link, r, "Failed to get prefix address: %m"); return log_link_error_errno(link, r, "Failed to get prefix address: %m");
r = route_configure(route, link, ndisc_route_handler); r = route_configure(route, link, ndisc_route_handler);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Could not set prefix route: %m"); return log_link_error_errno(link, r, "Could not set prefix route: %m");;
link_enter_failed(link);
return r;
}
if (r > 0) if (r > 0)
link->ndisc_routes_messages++; link->ndisc_routes_messages++;
@ -480,30 +474,30 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
r = sd_ndisc_router_route_get_lifetime(rt, &lifetime); r = sd_ndisc_router_route_get_lifetime(rt, &lifetime);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); return log_link_error_errno(link, r, "Failed to get gateway lifetime from RA: %m");
if (lifetime == 0) if (lifetime == 0)
return 0; return 0;
r = sd_ndisc_router_get_address(rt, &gateway); r = sd_ndisc_router_get_address(rt, &gateway);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m"); return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
r = sd_ndisc_router_route_get_prefixlen(rt, &prefixlen); r = sd_ndisc_router_route_get_prefixlen(rt, &prefixlen);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get route prefix length: %m"); return log_link_error_errno(link, r, "Failed to get route prefix length: %m");
r = sd_ndisc_router_route_get_preference(rt, &preference); r = sd_ndisc_router_route_get_preference(rt, &preference);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); return log_link_error_errno(link, r, "Failed to get default router preference from RA: %m");
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
r = route_new(&route); r = route_new(&route);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m"); return log_oom();
route->family = AF_INET6; route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link); route->table = link_get_ipv6_accept_ra_route_table(link);
@ -519,11 +513,8 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
return log_link_error_errno(link, r, "Failed to get route address: %m"); return log_link_error_errno(link, r, "Failed to get route address: %m");
r = route_configure(route, link, ndisc_route_handler); r = route_configure(route, link, ndisc_route_handler);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Could not set additional route: %m"); return log_link_error_errno(link, r, "Could not set additional route: %m");
link_enter_failed(link);
return r;
}
if (r > 0) if (r > 0)
link->ndisc_routes_messages++; link->ndisc_routes_messages++;
@ -544,24 +535,24 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
uint32_t lifetime; uint32_t lifetime;
const struct in6_addr *a; const struct in6_addr *a;
usec_t time_now; usec_t time_now;
int i, n, r; int n, r;
assert(link); assert(link);
assert(rt); assert(rt);
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime); r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m"); return log_link_error_errno(link, r, "Failed to get RDNSS lifetime: %m");
n = sd_ndisc_router_rdnss_get_addresses(rt, &a); n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
if (n < 0) if (n < 0)
return log_link_warning_errno(link, n, "Failed to get RDNSS addresses: %m"); return log_link_error_errno(link, n, "Failed to get RDNSS addresses: %m");
for (i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
_cleanup_free_ NDiscRDNSS *x = NULL; _cleanup_free_ NDiscRDNSS *x = NULL;
NDiscRDNSS d = { NDiscRDNSS d = {
.address = a[i], .address = a[i],
@ -616,7 +607,7 @@ static int ndisc_dnssl_compare_func(const NDiscDNSSL *a, const NDiscDNSSL *b) {
DEFINE_PRIVATE_HASH_OPS(ndisc_dnssl_hash_ops, NDiscDNSSL, ndisc_dnssl_hash_func, ndisc_dnssl_compare_func); DEFINE_PRIVATE_HASH_OPS(ndisc_dnssl_hash_ops, NDiscDNSSL, ndisc_dnssl_hash_func, ndisc_dnssl_compare_func);
static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) { static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
uint32_t lifetime; uint32_t lifetime;
usec_t time_now; usec_t time_now;
@ -627,32 +618,24 @@ static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
assert(rt); assert(rt);
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now); r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Failed to get RA timestamp: %m"); return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");
return;
}
r = sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime); r = sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m"); return log_link_error_errno(link, r, "Failed to get DNSSL lifetime: %m");
return;
}
r = sd_ndisc_router_dnssl_get_domains(rt, &l); r = sd_ndisc_router_dnssl_get_domains(rt, &l);
if (r < 0) { if (r < 0)
log_link_warning_errno(link, r, "Failed to get RDNSS addresses: %m"); return log_link_error_errno(link, r, "Failed to get DNSSL addresses: %m");
return;
}
STRV_FOREACH(i, l) { STRV_FOREACH(i, l) {
_cleanup_free_ NDiscDNSSL *s; _cleanup_free_ NDiscDNSSL *s = NULL;
NDiscDNSSL *x; NDiscDNSSL *x;
s = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*i) + 1); s = malloc0(ALIGN(sizeof(NDiscDNSSL)) + strlen(*i) + 1);
if (!s) { if (!s)
log_oom(); return log_oom();
return;
}
strcpy(NDISC_DNSSL_DOMAIN(s), *i); strcpy(NDISC_DNSSL_DOMAIN(s), *i);
@ -678,35 +661,32 @@ static void ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
s->valid_until = time_now + lifetime * USEC_PER_SEC; s->valid_until = time_now + lifetime * USEC_PER_SEC;
r = set_ensure_consume(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops, TAKE_PTR(s)); r = set_ensure_consume(&link->ndisc_dnssl, &ndisc_dnssl_hash_ops, TAKE_PTR(s));
if (r < 0) { if (r < 0)
log_oom(); return log_oom();
return;
}
assert(r > 0); assert(r > 0);
link_dirty(link); link_dirty(link);
} }
return 0;
} }
static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) { static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
int r;
assert(link); assert(link);
assert(link->network); assert(link->network);
assert(rt); assert(rt);
r = sd_ndisc_router_option_rewind(rt); for (int r = sd_ndisc_router_option_rewind(rt); ; r = sd_ndisc_router_option_next(rt)) {
for (;;) {
uint8_t type; uint8_t type;
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to iterate through options: %m"); return log_link_error_errno(link, r, "Failed to iterate through options: %m");
if (r == 0) /* EOF */ if (r == 0) /* EOF */
break; return 0;
r = sd_ndisc_router_option_get_type(rt, &type); r = sd_ndisc_router_option_get_type(rt, &type);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA option type: %m"); return log_link_error_errno(link, r, "Failed to get RA option type: %m");
switch (type) { switch (type) {
@ -725,44 +705,52 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
(void) in_addr_to_string(AF_INET6, &a, &b); (void) in_addr_to_string(AF_INET6, &a, &b);
log_link_debug(link, "Prefix '%s' is deny-listed, ignoring", strna(b)); log_link_debug(link, "Prefix '%s' is deny-listed, ignoring", strna(b));
} }
break; break;
} }
r = sd_ndisc_router_prefix_get_flags(rt, &flags); r = sd_ndisc_router_prefix_get_flags(rt, &flags);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA prefix flags: %m"); return log_link_error_errno(link, r, "Failed to get RA prefix flags: %m");
if (link->network->ipv6_accept_ra_use_onlink_prefix && if (link->network->ipv6_accept_ra_use_onlink_prefix &&
FLAGS_SET(flags, ND_OPT_PI_FLAG_ONLINK)) FLAGS_SET(flags, ND_OPT_PI_FLAG_ONLINK)) {
(void) ndisc_router_process_onlink_prefix(link, rt); r = ndisc_router_process_onlink_prefix(link, rt);
if (r < 0)
return r;
}
if (link->network->ipv6_accept_ra_use_autonomous_prefix && if (link->network->ipv6_accept_ra_use_autonomous_prefix &&
FLAGS_SET(flags, ND_OPT_PI_FLAG_AUTO)) FLAGS_SET(flags, ND_OPT_PI_FLAG_AUTO)) {
(void) ndisc_router_process_autonomous_prefix(link, rt); r = ndisc_router_process_autonomous_prefix(link, rt);
if (r < 0)
return r;
}
break; break;
} }
case SD_NDISC_OPTION_ROUTE_INFORMATION: case SD_NDISC_OPTION_ROUTE_INFORMATION:
(void) ndisc_router_process_route(link, rt); r = ndisc_router_process_route(link, rt);
if (r < 0)
return r;
break; break;
case SD_NDISC_OPTION_RDNSS: case SD_NDISC_OPTION_RDNSS:
if (link->network->ipv6_accept_ra_use_dns) if (link->network->ipv6_accept_ra_use_dns) {
(void) ndisc_router_process_rdnss(link, rt); r = ndisc_router_process_rdnss(link, rt);
if (r < 0)
return r;
}
break; break;
case SD_NDISC_OPTION_DNSSL: case SD_NDISC_OPTION_DNSSL:
if (link->network->ipv6_accept_ra_use_dns) if (link->network->ipv6_accept_ra_use_dns) {
(void) ndisc_router_process_dnssl(link, rt); r = ndisc_router_process_dnssl(link, rt);
if (r < 0)
return r;
}
break; break;
} }
r = sd_ndisc_router_option_next(rt);
} }
return 0;
} }
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
@ -776,7 +764,7 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
r = sd_ndisc_router_get_flags(rt, &flags); r = sd_ndisc_router_get_flags(rt, &flags);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA flags: %m"); return log_link_error_errno(link, r, "Failed to get RA flags: %m");
if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) && link->network->ipv6_accept_ra_start_dhcp6_client)) { if ((flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER) && link->network->ipv6_accept_ra_start_dhcp6_client)) {
@ -785,23 +773,27 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
else else
/* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */ /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED)); r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED));
if (r < 0 && r != -EBUSY) if (r < 0 && r != -EBUSY)
log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m"); return log_link_error_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
else { else {
log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request"); log_link_debug(link, "Acquiring DHCPv6 lease on NDisc request");
r = 0; r = 0;
} }
} }
(void) ndisc_router_process_default(link, rt); r = ndisc_router_process_default(link, rt);
(void) ndisc_router_process_options(link, rt); if (r < 0)
return r;
r = ndisc_router_process_options(link, rt);
if (r < 0)
return r;
return r; return r;
} }
static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata) { static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *rt, void *userdata) {
Link *link = userdata; Link *link = userdata;
int r;
assert(link); assert(link);
@ -814,7 +806,11 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *r
link->ndisc_addresses_configured = false; link->ndisc_addresses_configured = false;
link->ndisc_routes_configured = false; link->ndisc_routes_configured = false;
(void) ndisc_router_handler(link, rt); r = ndisc_router_handler(link, rt);
if (r < 0) {
link_enter_failed(link);
return;
}
if (link->ndisc_addresses_messages == 0) if (link->ndisc_addresses_messages == 0)
link->ndisc_addresses_configured = true; link->ndisc_addresses_configured = true;
@ -847,7 +843,7 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event event, sd_ndisc_router *r
break; break;
default: default:
log_link_warning(link, "IPv6 Neighbor Discovery unknown event: %d", event); assert_not_reached("IPv6 Neighbor Discovery unknown event");
} }
} }

View File

@ -270,7 +270,7 @@ BridgeFDB.AssociatedWith, config_parse_fdb_ntf_flags,
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0 BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0 BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0 BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, 0 Network.IPv6PrefixDelegation, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
Network.IPv6PDSubnetId, config_parse_router_prefix_subnet_id, 0, 0 Network.IPv6PDSubnetId, config_parse_router_prefix_subnet_id, 0, 0
IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec) IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed)

View File

@ -219,10 +219,11 @@ int config_parse_prefix(const char *unit,
return 0; return 0;
} }
if (sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen) < 0) r = sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen);
return -EADDRNOTAVAIL; if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set radv prefix, ignoring assignment: %s", rvalue);
log_syntax(unit, LOG_INFO, filename, line, r, "Found prefix %s", rvalue); return 0;
}
p = NULL; p = NULL;
@ -241,7 +242,7 @@ int config_parse_prefix_flags(const char *unit,
void *userdata) { void *userdata) {
Network *network = userdata; Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL; _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
int r, val; int r;
assert(filename); assert(filename);
assert(section); assert(section);
@ -255,18 +256,18 @@ int config_parse_prefix_flags(const char *unit,
r = parse_boolean(rvalue); r = parse_boolean(rvalue);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue); log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0; return 0;
} }
val = r;
if (streq(lvalue, "OnLink")) if (streq(lvalue, "OnLink"))
r = sd_radv_prefix_set_onlink(p->radv_prefix, val); r = sd_radv_prefix_set_onlink(p->radv_prefix, r);
else if (streq(lvalue, "AddressAutoconfiguration")) else if (streq(lvalue, "AddressAutoconfiguration"))
r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, val); r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, r);
if (r < 0) if (r < 0) {
return r; log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
return 0;
}
p = NULL; p = NULL;
@ -311,8 +312,10 @@ int config_parse_prefix_lifetime(const char *unit,
else if (streq(lvalue, "ValidLifetimeSec")) else if (streq(lvalue, "ValidLifetimeSec"))
r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix, r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix,
DIV_ROUND_UP(usec, USEC_PER_SEC)); DIV_ROUND_UP(usec, USEC_PER_SEC));
if (r < 0) if (r < 0) {
return r; log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
return 0;
}
p = NULL; p = NULL;
@ -392,10 +395,11 @@ int config_parse_route_prefix(const char *unit,
return 0; return 0;
} }
if (sd_radv_prefix_set_route_prefix(p->radv_route_prefix, &in6addr.in6, prefixlen) < 0) r = sd_radv_prefix_set_route_prefix(p->radv_route_prefix, &in6addr.in6, prefixlen);
return -EADDRNOTAVAIL; if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set route prefix, ignoring assignment: %m");
log_syntax(unit, LOG_INFO, filename, line, r, "Found route prefix %s", rvalue); return 0;
}
p = NULL; p = NULL;
@ -436,8 +440,11 @@ int config_parse_route_prefix_lifetime(const char *unit,
/* a value of 0xffffffff represents infinity */ /* a value of 0xffffffff represents infinity */
r = sd_radv_route_prefix_set_lifetime(p->radv_route_prefix, DIV_ROUND_UP(usec, USEC_PER_SEC)); r = sd_radv_route_prefix_set_lifetime(p->radv_route_prefix, DIV_ROUND_UP(usec, USEC_PER_SEC));
if (r < 0) if (r < 0) {
return r; log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to set route lifetime, ignoring assignment: %m");
return 0;
}
p = NULL; p = NULL;
@ -828,38 +835,10 @@ DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(
RADVPrefixDelegation, RADVPrefixDelegation,
RADV_PREFIX_DELEGATION_BOTH); RADV_PREFIX_DELEGATION_BOTH);
int config_parse_router_prefix_delegation( DEFINE_CONFIG_PARSE_ENUM(config_parse_router_prefix_delegation,
const char *unit, radv_prefix_delegation,
const char *filename, RADVPrefixDelegation,
unsigned line, "Invalid router prefix delegation");
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = userdata;
RADVPrefixDelegation d;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
d = radv_prefix_delegation_from_string(rvalue);
if (d < 0) {
log_syntax(unit, LOG_WARNING, filename, line, SYNTHETIC_ERRNO(EINVAL),
"Invalid router prefix delegation '%s', ignoring assignment.", rvalue);
return 0;
}
network->router_prefix_delegation = d;
return 0;
}
int config_parse_router_preference(const char *unit, int config_parse_router_preference(const char *unit,
const char *filename, const char *filename,
@ -917,10 +896,16 @@ int config_parse_router_prefix_subnet_id(const char *unit,
} }
r = safe_atoux64(rvalue, &t); r = safe_atoux64(rvalue, &t);
if (r < 0 || t > INT64_MAX) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, log_syntax(unit, LOG_WARNING, filename, line, r,
"Subnet id '%s' is invalid, ignoring assignment.", "Failed to parse %s=, ignoring assignment: %s",
rvalue); lvalue, rvalue);
return 0;
}
if (t > INT64_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid subnet id '%s', ignoring assignment.",
rvalue);
return 0; return 0;
} }

View File

@ -47,10 +47,10 @@ static int node_symlink(sd_device *dev, const char *node, const char *slink) {
/* preserve link with correct target, do not replace node of other device */ /* preserve link with correct target, do not replace node of other device */
if (lstat(slink, &stats) == 0) { if (lstat(slink, &stats) == 0) {
if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) { if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode))
log_device_error(dev, "Conflicting device node '%s' found, link to '%s' will not be created.", slink, node); return log_device_error_errno(dev, SYNTHETIC_ERRNO(EOPNOTSUPP),
return -EOPNOTSUPP; "Conflicting device node '%s' found, link to '%s' will not be created.", slink, node);
} else if (S_ISLNK(stats.st_mode)) { else if (S_ISLNK(stats.st_mode)) {
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
if (readlink_malloc(slink, &buf) >= 0 && if (readlink_malloc(slink, &buf) >= 0 &&

View File

@ -595,7 +595,7 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
if (!is_match) { if (!is_match) {
if (streq(value, "%k")) if (streq(value, "%k"))
return log_token_error_errno(rules, SYNTHETIC_ERRNO(EINVAL), return log_token_error_errno(rules, SYNTHETIC_ERRNO(EINVAL),
"Ignoring NAME=\"%%k\" is ignored, as it breaks kernel supplied names."); "NAME=\"%%k\" is ignored, as it breaks kernel supplied names.");
if (isempty(value)) if (isempty(value))
return log_token_error_errno(rules, SYNTHETIC_ERRNO(EINVAL), return log_token_error_errno(rules, SYNTHETIC_ERRNO(EINVAL),
"Ignoring NAME=\"\", as udev will not delete any device nodes."); "Ignoring NAME=\"\", as udev will not delete any device nodes.");
@ -755,10 +755,8 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
check_value_format_and_warn(rules, key, value, true); check_value_format_and_warn(rules, key, value, true);
if (op == OP_REMOVE) if (op == OP_REMOVE)
return log_token_invalid_op(rules, key); return log_token_invalid_op(rules, key);
if (!is_match) { if (!is_match)
log_token_debug(rules, "%s key takes '==' or '!=' operator, assuming '=='.", key);
op = OP_MATCH; op = OP_MATCH;
}
r = rule_line_add_token(rule_line, TK_M_PROGRAM, op, value, NULL); r = rule_line_add_token(rule_line, TK_M_PROGRAM, op, value, NULL);
} else if (streq(key, "IMPORT")) { } else if (streq(key, "IMPORT")) {
@ -767,10 +765,8 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
check_value_format_and_warn(rules, key, value, true); check_value_format_and_warn(rules, key, value, true);
if (op == OP_REMOVE) if (op == OP_REMOVE)
return log_token_invalid_op(rules, key); return log_token_invalid_op(rules, key);
if (!is_match) { if (!is_match)
log_token_debug(rules, "%s key takes '==' or '!=' operator, assuming '=='.", key);
op = OP_MATCH; op = OP_MATCH;
}
if (streq(attr, "file")) if (streq(attr, "file"))
r = rule_line_add_token(rule_line, TK_M_IMPORT_FILE, op, value, NULL); r = rule_line_add_token(rule_line, TK_M_IMPORT_FILE, op, value, NULL);
@ -813,10 +809,8 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
return log_token_invalid_attr(rules, key); return log_token_invalid_attr(rules, key);
if (is_match || op == OP_REMOVE) if (is_match || op == OP_REMOVE)
return log_token_invalid_op(rules, key); return log_token_invalid_op(rules, key);
if (op == OP_ADD) { if (op == OP_ADD)
log_token_debug(rules, "Operator '+=' is specified to %s key, assuming '='.", key);
op = OP_ASSIGN; op = OP_ASSIGN;
}
if (streq(value, "string_escape=none")) if (streq(value, "string_escape=none"))
r = rule_line_add_token(rule_line, TK_A_OPTIONS_STRING_ESCAPE_NONE, op, NULL, NULL); r = rule_line_add_token(rule_line, TK_A_OPTIONS_STRING_ESCAPE_NONE, op, NULL, NULL);
@ -866,7 +860,7 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
check_value_format_and_warn(rules, key, value, true); check_value_format_and_warn(rules, key, value, true);
r = rule_line_add_token(rule_line, TK_A_OWNER, op, value, NULL); r = rule_line_add_token(rule_line, TK_A_OWNER, op, value, NULL);
} else { } else {
log_token_debug(rules, "Resolving user name is disabled, ignoring %s=%s", key, value); log_token_debug(rules, "User name resolution is disabled, ignoring %s=%s", key, value);
return 0; return 0;
} }
} else if (streq(key, "GROUP")) { } else if (streq(key, "GROUP")) {
@ -949,7 +943,7 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
if (op != OP_ASSIGN) if (op != OP_ASSIGN)
return log_token_invalid_op(rules, key); return log_token_invalid_op(rules, key);
if (FLAGS_SET(rule_line->type, LINE_HAS_GOTO)) { if (FLAGS_SET(rule_line->type, LINE_HAS_GOTO)) {
log_token_warning(rules, "Contains multiple GOTO key, ignoring GOTO=\"%s\".", value); log_token_warning(rules, "Contains multiple GOTO keys, ignoring GOTO=\"%s\".", value);
return 0; return 0;
} }
@ -1661,7 +1655,7 @@ static int udev_rule_apply_token_to_event(
if (r == -ENOENT) if (r == -ENOENT)
return token->op == OP_NOMATCH; return token->op == OP_NOMATCH;
if (r < 0) if (r < 0)
return log_rule_error_errno(dev, rules, r, "Failed to test the existence of '%s': %m", buf); return log_rule_error_errno(dev, rules, r, "Failed to test for the existence of '%s': %m", buf);
if (stat(buf, &statbuf) < 0) if (stat(buf, &statbuf) < 0)
return token->op == OP_NOMATCH; return token->op == OP_NOMATCH;
@ -1682,16 +1676,16 @@ static int udev_rule_apply_token_to_event(
r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof(result)); r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof(result));
if (r != 0) { if (r != 0) {
if (r < 0) if (r < 0)
log_rule_warning_errno(dev, rules, r, "Failed to execute '%s', ignoring: %m", buf); log_rule_warning_errno(dev, rules, r, "Failed to execute \"%s\": %m", buf);
else /* returned value is positive when program fails */ else /* returned value is positive when program fails */
log_rule_debug(dev, rules, "Command \"%s\" returned %d (error), ignoring", buf, r); log_rule_debug(dev, rules, "Command \"%s\" returned %d (error)", buf, r);
return token->op == OP_NOMATCH; return token->op == OP_NOMATCH;
} }
delete_trailing_chars(result, "\n"); delete_trailing_chars(result, "\n");
count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT); count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT);
if (count > 0) if (count > 0)
log_rule_debug(dev, rules, "Replaced %zu character(s) from result of '%s'", log_rule_debug(dev, rules, "Replaced %zu character(s) in result of \"%s\"",
count, buf); count, buf);
event->program_result = strdup(result); event->program_result = strdup(result);

View File

@ -125,8 +125,7 @@ int udev_watch_end(sd_device *dev) {
int wd, r; int wd, r;
if (inotify_fd < 0) if (inotify_fd < 0)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), return 0; /* Nothing to do. */
"Invalid inotify descriptor.");
r = device_get_watch_handle(dev, &wd); r = device_get_watch_handle(dev, &wd);
if (r == -ENOENT) if (r == -ENOENT)

View File

@ -44,17 +44,15 @@ static const char *arg_export_prefix = NULL;
static usec_t arg_wait_for_initialization_timeout = 0; static usec_t arg_wait_for_initialization_timeout = 0;
static bool skip_attribute(const char *name) { static bool skip_attribute(const char *name) {
static const char* const skip[] = { /* Those are either displayed separately or should not be shown at all. */
"uevent", return STR_IN_SET(name,
"dev", "uevent",
"modalias", "dev",
"resource", "modalias",
"driver", "resource",
"subsystem", "driver",
"module", "subsystem",
}; "module");
return string_table_lookup(skip, ELEMENTSOF(skip), name) >= 0;
} }
typedef struct SysAttr { typedef struct SysAttr {