<row><entry><varname>fou</varname></entry>
<entry>Foo-over-UDP tunneling.</entry></row>
+ <row><entry><varname>xfrm</varname></entry>
+ <entry>A virtual tunnel interface like vti/vti6 but with several advantages.</entry></row>
+
</tbody>
</tgroup>
</table>
Linux Ethernet Bonding Driver HOWTO</ulink></para>
</refsect1>
+ <refsect1>
+ <title>[Xfrm] Section Options</title>
+
+ <para>The <literal>[Xfrm]</literal> section accepts the following
+ keys:</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>InterfaceId=</varname></term>
+ <listitem>
+ <para>Sets the ID/key of the xfrm interface which needs to be associated with a SA/policy.
+ Can be decimal or hexadecimal, valid range is 0-0xffffffff, defaults to 0.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Independent=</varname></term>
+ <listitem>
+ <para>Takes a boolean. If set to <literal>no</literal>, the xfrm interface should have an
+ underlying device which can be used for hardware offloading. Defaults to <literal>no</literal>.
+ See <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for how to configure the underlying device.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>For more detail information see
+ <ulink url="https://lwn.net/Articles/757391">
+ Virtual xfrm interfaces</ulink></para>
+ </refsect1>
+
<refsect1>
<title>[VRF] Section Options</title>
<para>The <literal>[VRF]</literal> section only applies for
AllowedIPs=fd31:bf08:57cb::/48,192.168.26.0/24
Endpoint=wireguard.example.com:51820</programlisting>
</example>
+
+ <example>
+ <title>/etc/systemd/network/27-xfrm.netdev</title>
+ <programlisting>[Xfrm]
+Name=xfrm0
+Kind=xfrm
+
+[Xfrm]
+Independent=yes</programlisting>
+ </example>
</refsect1>
<refsect1>
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>Xfrm=</varname></term>
+ <listitem>
+ <para>The name of the xfrm to create on the link. See
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This option may be specified more than once.</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>KeepConfiguration=</varname></term>
<listitem>
MACVTAP=macvtap-test
</programlisting>
</example>
+
+ <example>
+ <title>A Xfrm interface with physical underlying device.</title>
+
+ <programlisting># /etc/systemd/network/27-xfrm.netdev
+[NetDev]
+Name=xfrm0
+
+[Xfrm]
+InterfaceId=7</programlisting>
+
+ <programlisting># /etc/systemd/network/27-eth0.network
+[Match]
+Name=eth0
+
+[Network]
+Xfrm=xfrm0</programlisting>
+
+ <para>This creates a <literal>xfrm0</literal> interface and binds it to the <literal>eth0</literal> device.
+ This allows hardware based ipsec offloading to the <literal>eth0</literal> nic.
+ If offloading is not needed, xfrm interfaces can be assigned to the <literal>lo</literal> device.
+ </para>
+ </example>
</refsect1>
<refsect1>
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include <stdlib.h>
+#include <string.h>
+
#include "macro.h"
static inline void _reset_errno_(int *saved_errno) {
return -errno;
}
+static inline char *strerror_safe(int error) {
+ /* 'safe' here does NOT mean thread safety. */
+ return strerror(abs(error));
+}
+
/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
*
* Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. See the
cmd = exec_command_line(c->argv);
fprintf(f,
"%sCommand Line: %s\n",
- prefix, cmd ? cmd : strerror(ENOMEM));
+ prefix, cmd ? cmd : strerror_safe(ENOMEM));
exec_status_dump(&c->exec_status, f, prefix2);
}
break;
}
- r = log_warning_errno(errno, "Failed to add watch on %s: %s", s->path, errno == ENOSPC ? "too many watches" : strerror(-r));
+ r = log_warning_errno(errno, "Failed to add watch on %s: %s", s->path, errno == ENOSPC ? "too many watches" : strerror_safe(r));
if (cut)
*cut = tmp;
goto fail;
#include "alloc-util.h"
#include "audit-fd.h"
#include "bus-util.h"
+#include "errno-util.h"
#include "format-util.h"
#include "log.h"
#include "path-util.h"
/* Return an access denied error, if we couldn't load
* the AVC but enforcing mode was on, or we couldn't
* determine whether it is one. */
- return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to open the SELinux AVC: %s", strerror(saved_errno));
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to open the SELinux AVC: %s", strerror_safe(saved_errno));
}
selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback);
r = socket_address_print(&p->address, &k);
if (r < 0)
- t = strerror(-r);
+ t = strerror_safe(r);
else
t = k;
"%s\tMerged into: %s\n",
prefix, u->merged_into->id);
else if (u->load_state == UNIT_ERROR)
- fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
+ fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror_safe(u->load_error));
for (n = sd_bus_track_first(u->bus_track); n; n = sd_bus_track_next(u->bus_track))
fprintf(f, "%s\tBus Ref: %s\n", prefix, n);
#include "alloc-util.h"
#include "bus-util.h"
+#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "hostname-util.h"
errno = 0;
k = fread(buf, 1, n, m->tmp);
if (k != n) {
- log_error("Failed to read from file: %s", errno ? strerror(errno) : "Premature EOF");
+ log_error("Failed to read from file: %s", errno != 0 ? strerror_safe(errno) : "Premature EOF");
return MHD_CONTENT_READER_END_WITH_ERROR;
}
errno = 0;
k = fread(buf, 1, n, m->tmp);
if (k != n) {
- log_error("Failed to read from file: %s", errno ? strerror(errno) : "Premature EOF");
+ log_error("Failed to read from file: %s", errno != 0 ? strerror_safe(errno) : "Premature EOF");
return MHD_CONTENT_READER_END_WITH_ERROR;
}
r = get_boots(j, NULL, &boot_id, arg_boot_offset);
assert(r <= 1);
if (r <= 0) {
- const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
+ const char *reason = (r == 0) ? "No such boot ID in journal" : strerror_safe(r);
if (sd_id128_is_null(arg_boot_id))
log_error("Data from the specified boot (%+i) is not available: %s",
/* We failed to format the message. Emit a warning instead. */
char buf[LINE_MAX];
- xsprintf(buf, "MESSAGE=Entry printing failed: %s", strerror(-r));
+ xsprintf(buf, "MESSAGE=Entry printing failed: %s", strerror_safe(r));
n = 3;
iovec[n++] = IOVEC_MAKE_STRING("PRIORITY=4");
assert(client);
if (error < 0)
- log_dhcp_client(client, "STOPPED: %s", strerror(-error));
+ log_dhcp_client_errno(client, error, "STOPPED: %m");
else if (error == SD_DHCP_CLIENT_EVENT_STOP)
log_dhcp_client(client, "STOPPED");
else
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->dns,
lease->dns_count,
&lease->dns_allocated);
- if (r < 0) {
- log_dhcp6_client(client, "Invalid DNS server option: %s",
- strerror(-r));
-
- return r;
- }
+ if (r < 0)
+ return log_dhcp6_client_errno(client, r, "Invalid DNS server option: %m");
lease->dns_count = r;
r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp,
lease->ntp_count,
&lease->ntp_allocated);
- if (r < 0) {
- log_dhcp6_client(client, "Invalid SNTP server option: %s",
- strerror(-r));
-
- return r;
- }
+ if (r < 0)
+ return log_dhcp6_client_errno(client, r, "Invalid SNTP server option: %m");
lease->ntp_count = r;
if (error < 0)
error = -error;
- return strerror(error);
+ return strerror_safe(error);
}
static bool map_ok(const sd_bus_error_map *map) {
#include "bus-internal.h"
#include "bus-match.h"
#include "bus-util.h"
+#include "errno-util.h"
#include "fd-util.h"
#include "format-util.h"
#include "log.h"
errno = 0;
if (read(pp[0], &x, 1) <= 0) {
- log_error("Failed to read from pipe: %s", errno ? strerror(errno) : "early read");
+ log_error("Failed to read from pipe: %s", errno != 0 ? strerror_safe(errno) : "early read");
goto finish;
}
#include "bus-error.h"
#include "bus-util.h"
#include "errno-list.h"
+#include "errno-util.h"
static void test_error(void) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL, second = SD_BUS_ERROR_NULL;
assert_se(!sd_bus_error_is_set(&error));
assert_se(sd_bus_error_set_errno(&error, EBUSY) == -EBUSY);
assert_se(streq(error.name, "System.Error.EBUSY"));
- assert_se(streq(error.message, strerror(EBUSY)));
+ assert_se(streq(error.message, strerror_safe(EBUSY)));
assert_se(sd_bus_error_has_name(&error, "System.Error.EBUSY"));
assert_se(sd_bus_error_get_errno(&error) == EBUSY);
assert_se(sd_bus_error_is_set(&error));
#include "signal-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strxcpyx.h"
#include "time-util.h"
#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
}
static void event_log_delays(sd_event *e) {
- char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1];
- unsigned i;
- int o;
+ char b[ELEMENTSOF(e->delays) * DECIMAL_STR_MAX(unsigned) + 1], *p;
+ size_t l, i;
- for (i = o = 0; i < ELEMENTSOF(e->delays); i++) {
- o += snprintf(&b[o], sizeof(b) - o, "%u ", e->delays[i]);
+ p = b;
+ l = sizeof(b);
+ for (i = 0; i < ELEMENTSOF(e->delays); i++) {
+ l = strpcpyf(&p, l, "%u ", e->delays[i]);
e->delays[i] = 0;
}
- log_debug("Event loop iterations: %.*s", o, b);
+ log_debug("Event loop iterations: %s", b);
}
_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
[IFLA_MACSEC_VALIDATION] = { .type = NETLINK_TYPE_U8 },
};
+static const NLType rtnl_link_info_data_xfrm_types[] = {
+ [IFLA_XFRM_LINK] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_XFRM_IF_ID] = { .type = NETLINK_TYPE_U32 }
+};
+
/* these strings must match the .kind entries in the kernel */
static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_BOND] = "bond",
[NL_UNION_LINK_INFO_DATA_CAN] = "can",
[NL_UNION_LINK_INFO_DATA_MACSEC] = "macsec",
[NL_UNION_LINK_INFO_DATA_NLMON] = "nlmon",
+ [NL_UNION_LINK_INFO_DATA_XFRM] = "xfrm",
};
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
.types = rtnl_link_info_data_can_types },
[NL_UNION_LINK_INFO_DATA_MACSEC] = { .count = ELEMENTSOF(rtnl_link_info_data_macsec_types),
.types = rtnl_link_info_data_macsec_types },
+ [NL_UNION_LINK_INFO_DATA_XFRM] = { .count = ELEMENTSOF(rtnl_link_info_data_xfrm_types),
+ .types = rtnl_link_info_data_xfrm_types },
};
static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
NL_UNION_LINK_INFO_DATA_CAN,
NL_UNION_LINK_INFO_DATA_MACSEC,
NL_UNION_LINK_INFO_DATA_NLMON,
+ NL_UNION_LINK_INFO_DATA_XFRM,
_NL_UNION_LINK_INFO_DATA_MAX,
_NL_UNION_LINK_INFO_DATA_INVALID = -1
} NLUnionLinkInfoData;
#include "sd-messages.h"
#include "alloc-util.h"
+#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
k = read(s->manager->console_active_fd, t, sizeof(t)-1);
if (k <= 0) {
- log_error("Failed to read current console: %s", k < 0 ? strerror(errno) : "EOF");
+ log_error("Failed to read current console: %s", k < 0 ? strerror_safe(errno) : "EOF");
return k < 0 ? -errno : -EIO;
}
#include "bus-internal.h"
#include "bus-util.h"
#include "cgroup-util.h"
+#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
if (streq(limit, "infinity")) {
r = sd_bus_message_append(m, "(sv)", "MemoryMax", "t", (uint64_t)-1);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror_safe(r));
return r;
}
} else {
if (r >= 0) {
r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U));
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror_safe(r));
return r;
}
} else {
if (r >= 0) {
r = sd_bus_message_append(m, "(sv)", "MemoryMax", "t", val);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror_safe(r));
return r;
}
} else
if (r >= 0) {
r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", val);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror_safe(r));
return r;
}
} else
if (r >= 0) {
r = sd_bus_message_append(m, "(sv)", field, "t", val);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror_safe(r));
return r;
}
} else if (streq(field, "CPUWeight"))
* up properly for us. */
if (lstat(path, &st) < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror(errno));
+ pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror_safe(errno));
goto fail;
}
r = sd_bus_open_system(&bus);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", strerror_safe(r));
return PAM_SESSION_ERR;
}
"org.freedesktop.login1.Manager",
"CreateSession");
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to create CreateSession method call: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to create CreateSession method call: %s", strerror_safe(r));
return PAM_SESSION_ERR;
}
remote_user,
remote_host);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror_safe(r));
return PAM_SESSION_ERR;
}
r = sd_bus_message_open_container(m, 'a', "(sv)");
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to open message container: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to open message container: %s", strerror_safe(r));
return PAM_SYSTEM_ERR;
}
r = sd_bus_message_close_container(m);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to close message container: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to close message container: %s", strerror_safe(r));
return PAM_SYSTEM_ERR;
}
&vtnr,
&existing);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", strerror_safe(r));
return PAM_SESSION_ERR;
}
r = sd_bus_open_system(&bus);
if (r < 0) {
- pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", strerror(-r));
+ pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", strerror_safe(r));
return PAM_SESSION_ERR;
}
netdev/l2tp-tunnel.h
netdev/macsec.c
netdev/macsec.h
+ netdev/xfrm.c
+ netdev/xfrm.h
networkd-address-label.c
networkd-address-label.h
networkd-address-pool.c
#include "netdev/wireguard.h"
#include "netdev/fou-tunnel.h"
#include "netdev/l2tp-tunnel.h"
+#include "netdev/xfrm.h"
#include "vlan-util.h"
%}
struct ConfigPerfItem;
WireGuardPeer.PresharedKey, config_parse_wireguard_preshared_key, 0, 0
WireGuardPeer.PresharedKeyFile, config_parse_wireguard_preshared_key_file, 0, 0
WireGuardPeer.PersistentKeepalive, config_parse_wireguard_keepalive, 0, 0
+Xfrm.InterfaceId, config_parse_uint32, 0, offsetof(Xfrm, if_id)
+Xfrm.Independent, config_parse_bool, 0, offsetof(Xfrm, independent)
#include "netdev/vxcan.h"
#include "netdev/vxlan.h"
#include "netdev/wireguard.h"
+#include "netdev/xfrm.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "networkd-link.h"
[NETDEV_KIND_L2TP] = &l2tptnl_vtable,
[NETDEV_KIND_MACSEC] = &macsec_vtable,
[NETDEV_KIND_NLMON] = &nlmon_vtable,
+ [NETDEV_KIND_XFRM] = &xfrm_vtable,
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_L2TP] = "l2tp",
[NETDEV_KIND_MACSEC] = "macsec",
[NETDEV_KIND_NLMON] = "nlmon",
+ [NETDEV_KIND_XFRM] = "xfrm",
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
case NETDEV_KIND_ERSPAN:
independent = ERSPAN(netdev)->independent;
break;
+ case NETDEV_KIND_XFRM:
+ independent = XFRM(netdev)->independent;
+ break;
default:
break;
}
NETDEV_KIND_L2TP,
NETDEV_KIND_MACSEC,
NETDEV_KIND_NLMON,
+ NETDEV_KIND_XFRM,
_NETDEV_KIND_MAX,
_NETDEV_KIND_TUNNEL, /* Used by config_parse_stacked_netdev() */
_NETDEV_KIND_INVALID = -1
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "missing_network.h"
+#include "netdev/xfrm.h"
+
+static int xfrm_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *message) {
+ int if_idx, r;
+ Xfrm *x;
+
+ assert(netdev);
+ assert(message);
+
+ x = XFRM(netdev);
+
+ if (x->independent)
+ if_idx = LOOPBACK_IFINDEX;
+ else {
+ assert(link);
+ if (link->ifindex == 0)
+ return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(ENODEV), "Could not get interface index: %m");
+ if_idx = link->ifindex;
+ }
+
+ r = sd_netlink_message_append_u32(message, IFLA_XFRM_LINK, if_idx);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_XFRM_LINK: %m");
+
+ r = sd_netlink_message_append_u32(message, IFLA_XFRM_IF_ID, x->if_id);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_XFRM_IF_ID: %m");
+
+ return 0;
+}
+
+const NetDevVTable xfrm_vtable = {
+ .object_size = sizeof(Xfrm),
+ .sections = "Match\0NetDev\0Xfrm\0",
+ .fill_message_create = xfrm_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED
+};
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "netdev/netdev.h"
+
+typedef struct Xfrm {
+ NetDev meta;
+
+ uint32_t if_id;
+ bool independent;
+} Xfrm;
+
+DEFINE_NETDEV_CAST(XFRM, Xfrm);
+extern const NetDevVTable xfrm_vtable;
if (!link->network)
return false;
- if (STRPTR_IN_SET(link->kind, "vrf", "wireguard", "ipip", "gre", "ip6gre", "ip6tnl", "sit", "vti", "vti6", "can", "vcan", "vxcan", "nlmon"))
+ if (STRPTR_IN_SET(link->kind,
+ "vrf", "wireguard", "ipip", "gre", "ip6gre","ip6tnl", "sit", "vti",
+ "vti6", "can", "vcan", "vxcan", "nlmon", "xfrm"))
return false;
/* L3 or L3S mode do not support ARP. */
if (link->network->bond)
return false;
- if (link->network->bond)
- return false;
-
return link->network->link_local & mask;
}
continue;
}
+ if (set_contains(network->ndisc_black_listed_prefix, &ip.in6))
+ continue;
+
r = set_ensure_allocated(&network->ndisc_black_listed_prefix, &in6_addr_hash_ops);
if (r < 0)
return log_oom();
r = set_put(network->ndisc_black_listed_prefix, a);
if (r < 0) {
- if (r == -EEXIST)
- log_syntax(unit, LOG_WARNING, filename, line, r,
- "NDISC black listed prefixs is duplicated, ignoring assignment: %s", n);
- else
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to store NDISC black listed prefix '%s', ignoring assignment: %m", n);
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to store NDISC black listed prefix '%s', ignoring assignment: %m", n);
continue;
}
Network.L2TP, config_parse_stacked_netdev, NETDEV_KIND_L2TP, offsetof(Network, stacked_netdev_names)
Network.MACsec, config_parse_stacked_netdev, NETDEV_KIND_MACSEC, offsetof(Network, stacked_netdev_names)
Network.Tunnel, config_parse_stacked_netdev, _NETDEV_KIND_TUNNEL, offsetof(Network, stacked_netdev_names)
+Network.Xfrm, config_parse_stacked_netdev, NETDEV_KIND_XFRM, offsetof(Network, stacked_netdev_names)
Network.VRF, config_parse_ifname, 0, offsetof(Network, vrf_name)
Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp)
Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server)
assert(IN_SET(kind,
NETDEV_KIND_VLAN, NETDEV_KIND_MACVLAN, NETDEV_KIND_MACVTAP,
NETDEV_KIND_IPVLAN, NETDEV_KIND_IPVTAP, NETDEV_KIND_VXLAN,
- NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL));
+ NETDEV_KIND_L2TP, NETDEV_KIND_MACSEC, _NETDEV_KIND_TUNNEL,
+ NETDEV_KIND_XFRM));
if (!ifname_valid(rvalue)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
NetDev *bridge;
NetDev *bond;
NetDev *vrf;
+ NetDev *xfrm;
Hashmap *stacked_netdevs;
char *bridge_name;
char *bond_name;
const union in_addr_union *destination,
unsigned destination_prefixlen) {
+ static const xt_chainlabel chain = "POSTROUTING";
_cleanup_(iptc_freep) struct xtc_handle *h = NULL;
struct ipt_entry *entry, *mask;
struct ipt_entry_target *t;
memset(mask, 0xFF, sz);
if (add) {
- if (iptc_check_entry("POSTROUTING", entry, (unsigned char*) mask, h))
+ if (iptc_check_entry(chain, entry, (unsigned char*) mask, h))
return 0;
if (errno != ENOENT) /* if other error than not existing yet, fail */
return -errno;
- if (!iptc_insert_entry("POSTROUTING", entry, 0, h))
+ if (!iptc_insert_entry(chain, entry, 0, h))
return -errno;
} else {
- if (!iptc_delete_entry("POSTROUTING", entry, (unsigned char*) mask, h)) {
+ if (!iptc_delete_entry(chain, entry, (unsigned char*) mask, h)) {
if (errno == ENOENT) /* if it's already gone, all is good! */
return 0;
uint16_t remote_port,
const union in_addr_union *previous_remote) {
+ static const xt_chainlabel chain_pre = "PREROUTING", chain_output = "OUTPUT";
_cleanup_(iptc_freep) struct xtc_handle *h = NULL;
struct ipt_entry *entry, *mask;
struct ipt_entry_target *t;
if (add) {
/* Add the PREROUTING rule, if it is missing so far */
- if (!iptc_check_entry("PREROUTING", entry, (unsigned char*) mask, h)) {
+ if (!iptc_check_entry(chain_pre, entry, (unsigned char*) mask, h)) {
if (errno != ENOENT)
return -EINVAL;
- if (!iptc_insert_entry("PREROUTING", entry, 0, h))
+ if (!iptc_insert_entry(chain_pre, entry, 0, h))
return -errno;
}
if (previous_remote && previous_remote->in.s_addr != remote->in.s_addr) {
mr->range[0].min_ip = mr->range[0].max_ip = previous_remote->in.s_addr;
- if (!iptc_delete_entry("PREROUTING", entry, (unsigned char*) mask, h)) {
+ if (!iptc_delete_entry(chain_pre, entry, (unsigned char*) mask, h)) {
if (errno != ENOENT)
return -errno;
}
entry->ip.invflags = IPT_INV_DSTIP;
}
- if (!iptc_check_entry("OUTPUT", entry, (unsigned char*) mask, h)) {
+ if (!iptc_check_entry(chain_output, entry, (unsigned char*) mask, h)) {
if (errno != ENOENT)
return -errno;
- if (!iptc_insert_entry("OUTPUT", entry, 0, h))
+ if (!iptc_insert_entry(chain_output, entry, 0, h))
return -errno;
}
if (previous_remote && previous_remote->in.s_addr != remote->in.s_addr) {
mr->range[0].min_ip = mr->range[0].max_ip = previous_remote->in.s_addr;
- if (!iptc_delete_entry("OUTPUT", entry, (unsigned char*) mask, h)) {
+ if (!iptc_delete_entry(chain_output, entry, (unsigned char*) mask, h)) {
if (errno != ENOENT)
return -errno;
}
}
}
} else {
- if (!iptc_delete_entry("PREROUTING", entry, (unsigned char*) mask, h)) {
+ if (!iptc_delete_entry(chain_pre, entry, (unsigned char*) mask, h)) {
if (errno != ENOENT)
return -errno;
}
entry->ip.invflags = IPT_INV_DSTIP;
}
- if (!iptc_delete_entry("OUTPUT", entry, (unsigned char*) mask, h)) {
+ if (!iptc_delete_entry(chain_output, entry, (unsigned char*) mask, h)) {
if (errno != ENOENT)
return -errno;
}
#include <unistd.h>
#include "alloc-util.h"
+#include "errno-util.h"
#include "escape.h"
#include "fd-util.h"
#include "io-util.h"
"Failed to store received data of size %zu "
"(in addition to existing %zu bytes with %zu filled): %s",
size, imp->size, imp->filled,
- strerror(ENOMEM));
+ strerror_safe(ENOMEM));
memcpy(imp->buf + imp->filled, data, size);
imp->filled += size;
int r;
/**
- * Finds where the unit is defined on disk. Returns 0 if the unit is not found. Returns 1 if it is found, and
- * sets:
+ * Finds where the unit is defined on disk. Returns 0 if the unit is not found. Returns 1 if it is
+ * found, and sets:
* - the path to the unit in *ret_frament_path, if it exists on disk,
- * - and a strv of existing drop-ins in *ret_dropin_paths, if the arg is not NULL and any dropins were found.
+ * - and a strv of existing drop-ins in *ret_dropin_paths, if the arg is not NULL and any dropins
+ * were found.
*
- * Returns -ERFKILL if the unit is masked, and -EKEYREJECTED if the unit file could not be loaded for some
- * reason (the latter only applies if we are going through the service manager)
+ * Returns -ERFKILL if the unit is masked, and -EKEYREJECTED if the unit file could not be loaded for
+ * some reason (the latter only applies if we are going through the service manager).
*/
assert(unit_name);
r = 0;
goto not_found;
}
- if (!streq(load_state, "loaded"))
+ if (!STR_IN_SET(load_state, "loaded", "bad-setting"))
return -EKEYREJECTED;
r = sd_bus_get_property_string(
if (i->status_text)
printf(" Status: \"%s\"\n", i->status_text);
if (i->status_errno > 0)
- printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
+ printf(" Error: %i (%s)\n", i->status_errno, strerror_safe(i->status_errno));
if (i->ip_ingress_bytes != (uint64_t) -1 && i->ip_egress_bytes != (uint64_t) -1) {
char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
sd_notifyf(0, "STATUS=Failed to start up: %s\n"
"ERRNO=%i",
- strerror(errno),
+ strerror_safe(errno),
errno);
See sd_notifyf(3) for more information.
#include "alloc-util.h"
#include "calendarspec.h"
+#include "errno-util.h"
#include "string-util.h"
#include "util.h"
u = now(CLOCK_REALTIME);
r = calendar_spec_next_usec(c, u, &u);
- printf("Next: %s\n", r < 0 ? strerror(-r) : format_timestamp(buf, sizeof(buf), u));
+ printf("Next: %s\n", r < 0 ? strerror_safe(r) : format_timestamp(buf, sizeof(buf), u));
calendar_spec_free(c);
assert_se(calendar_spec_from_string(p, &c) >= 0);
u = after;
r = calendar_spec_next_usec(c, after, &u);
- printf("At: %s\n", r < 0 ? strerror(-r) : format_timestamp_us(buf, sizeof buf, u));
+ printf("At: %s\n", r < 0 ? strerror_safe(r) : format_timestamp_us(buf, sizeof buf, u));
if (expect != (usec_t)-1)
assert_se(r >= 0 && u == expect);
else
assert_se((r = calendar_spec_next_usec(c, n, &u)) >= 0);
printf("Now: %s (%"PRIu64")\n", format_timestamp_us(buf, sizeof buf, n), n);
- printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror(-r) : format_timestamp_us(buf, sizeof buf, u), u);
+ printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror_safe(r) : format_timestamp_us(buf, sizeof buf, u), u);
assert_se((r = calendar_spec_next_usec(c, u, &w)) >= 0);
- printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror(-r) : format_timestamp_us(zaf, sizeof zaf, w), w);
+ printf("Next hourly: %s (%"PRIu64")\n", r < 0 ? strerror_safe(r) : format_timestamp_us(zaf, sizeof zaf, w), w);
assert_se(n < u);
assert_se(u <= n + USEC_PER_HOUR);
int r;
r = path_extract_filename(input, &k);
- log_info("%s → %s/%s [expected: %s/%s]", strnull(input), strnull(k), strerror(-r), strnull(output), strerror(-ret));
+ log_info("%s → %s/%s [expected: %s/%s]", strnull(input), strnull(k), strerror_safe(r), strnull(output), strerror_safe(ret));
assert_se(streq_ptr(k, output));
assert_se(r == ret);
}
#include <sys/types.h>
#include <unistd.h>
+#include "errno-util.h"
#include "fd-util.h"
#include "log.h"
#include "memory-util.h"
log_info("/= running system =/");
r = can_sleep("suspend");
- log_info("Suspend configured and possible: %s", r >= 0 ? yes_no(r) : strerror(-r));
+ log_info("Suspend configured and possible: %s", r >= 0 ? yes_no(r) : strerror_safe(r));
r = can_sleep("hibernate");
- log_info("Hibernation configured and possible: %s", r >= 0 ? yes_no(r) : strerror(-r));
+ log_info("Hibernation configured and possible: %s", r >= 0 ? yes_no(r) : strerror_safe(r));
r = can_sleep("hybrid-sleep");
- log_info("Hybrid-sleep configured and possible: %s", r >= 0 ? yes_no(r) : strerror(-r));
+ log_info("Hybrid-sleep configured and possible: %s", r >= 0 ? yes_no(r) : strerror_safe(r));
r = can_sleep("suspend-then-hibernate");
- log_info("Suspend-then-Hibernate configured and possible: %s", r >= 0 ? yes_no(r) : strerror(-r));
+ log_info("Suspend-then-Hibernate configured and possible: %s", r >= 0 ? yes_no(r) : strerror_safe(r));
}
int main(int argc, char* argv[]) {
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include <stdio.h>
#include <string.h>
#include "string-util.h"
assert_se(space_left == 10);
}
+static void test_sd_event_code_migration(void) {
+ char b[100 * DECIMAL_STR_MAX(unsigned) + 1];
+ char c[100 * DECIMAL_STR_MAX(unsigned) + 1], *p;
+ unsigned i;
+ size_t l;
+ int o;
+
+ for (i = o = 0; i < 100; i++)
+ o += snprintf(&b[o], sizeof(b) - o, "%u ", i);
+
+ p = c;
+ l = sizeof(c);
+ for (i = 0; i < 100; i++)
+ l = strpcpyf(&p, l, "%u ", i);
+
+ assert_se(streq(b, c));
+}
+
int main(int argc, char *argv[]) {
test_strpcpy();
test_strpcpyf();
test_strscpy();
test_strscpyl();
+ test_sd_event_code_migration();
+
return 0;
}
/* Also log about this briefly. We do so at LOG_NOTICE level, as we fixed up the situation automatically, hence
* there's no immediate need for action by the user. However, in the interest of making things less confusing
* to the user, let's still inform the user that these snippets should really be updated. */
-
- log_notice("[%s:%u] Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", fname, line, *path, n);
+ log_syntax(NULL, LOG_NOTICE, fname, line, 0, "Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", *path, n);
free_and_replace(*path, n);
--- /dev/null
+[NetDev]
+Name=xfrm99
+Kind=xfrm
+
+[Xfrm]
+InterfaceId=7
+Independent=false
Key=
KeyFile=
Activate=
+[Xfrm]
+Independent=
+InterfaceId=
--- /dev/null
+[Match]
+Name=eth0
+
+[Network]
+Xfrm=xfrm99
IPv6HopLimit=
IPForward=
IPv6Token=
+Xfrm=
Description=
VXLAN=
L2TP=
--- /dev/null
+[IPv6AcceptRA]
+BlackList=70:: 70::
\ No newline at end of file