Compare commits
No commits in common. "7d94934b9dd9ceacc18da914ce781272aee6f573" and "349176ae6c095725ddc11599dd03c7f16a5bb099" have entirely different histories.
7d94934b9d
...
349176ae6c
|
@ -1152,29 +1152,6 @@
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
|
||||||
<title>[NextHop] Section Options</title>
|
|
||||||
<para>The <literal>[NextHop]</literal> section accepts the
|
|
||||||
following keys. Specify several <literal>[NextHop]</literal>
|
|
||||||
sections to configure several nexthop. Nexthop is used to manipulate entries in the kernel's nexthop
|
|
||||||
tables.</para>
|
|
||||||
|
|
||||||
<variablelist class='network-directives'>
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>Gateway=</varname></term>
|
|
||||||
<listitem>
|
|
||||||
<para>As in the <literal>[Network]</literal> section. This is mandatory.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>Id=</varname></term>
|
|
||||||
<listitem>
|
|
||||||
<para>The id of the nexthop (an unsigned integer). If unspecified or '0' then automatically chosen by kernel.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
</refsect1>
|
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>[Route] Section Options</title>
|
<title>[Route] Section Options</title>
|
||||||
<para>The <literal>[Route]</literal> section accepts the
|
<para>The <literal>[Route]</literal> section accepts the
|
||||||
|
|
26
man/udev.xml
26
man/udev.xml
|
@ -236,32 +236,6 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>CONST{<replaceable>key</replaceable>}</varname></term>
|
|
||||||
<listitem>
|
|
||||||
<para>Match against a system-wide constant. Supported keys are:</para>
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>arch</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>System's architecture. See <option>ConditionArchitecture=</option> in
|
|
||||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
|
||||||
for possible values.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>virt</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>System's virtualization environment. See
|
|
||||||
<citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
|
||||||
for possible values.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
<para>Unknown keys will never match.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>TAG</varname></term>
|
<term><varname>TAG</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
|
||||||
#ifndef _LINUX_NEXTHOP_H
|
|
||||||
#define _LINUX_NEXTHOP_H
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
struct nhmsg {
|
|
||||||
unsigned char nh_family;
|
|
||||||
unsigned char nh_scope; /* return only */
|
|
||||||
unsigned char nh_protocol; /* Routing protocol that installed nh */
|
|
||||||
unsigned char resvd;
|
|
||||||
unsigned int nh_flags; /* RTNH_F flags */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* entry in a nexthop group */
|
|
||||||
struct nexthop_grp {
|
|
||||||
__u32 id; /* nexthop id - must exist */
|
|
||||||
__u8 weight; /* weight of this nexthop */
|
|
||||||
__u8 resvd1;
|
|
||||||
__u16 resvd2;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
|
|
||||||
__NEXTHOP_GRP_TYPE_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
NHA_UNSPEC,
|
|
||||||
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
|
|
||||||
|
|
||||||
NHA_GROUP, /* array of nexthop_grp */
|
|
||||||
NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */
|
|
||||||
/* if NHA_GROUP attribute is added, no other attributes can be set */
|
|
||||||
|
|
||||||
NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */
|
|
||||||
/* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */
|
|
||||||
|
|
||||||
NHA_OIF, /* u32; nexthop device */
|
|
||||||
NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */
|
|
||||||
NHA_ENCAP_TYPE, /* u16; lwt encap type */
|
|
||||||
NHA_ENCAP, /* lwt encap data */
|
|
||||||
|
|
||||||
/* NHA_OIF can be appended to dump request to return only
|
|
||||||
* nexthops using given device
|
|
||||||
*/
|
|
||||||
NHA_GROUPS, /* flag; only return nexthop groups in dump */
|
|
||||||
NHA_MASTER, /* u32; only return nexthops with given master dev */
|
|
||||||
|
|
||||||
__NHA_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NHA_MAX (__NHA_MAX - 1)
|
|
||||||
#endif
|
|
|
@ -157,13 +157,6 @@ enum {
|
||||||
RTM_GETCHAIN,
|
RTM_GETCHAIN,
|
||||||
#define RTM_GETCHAIN RTM_GETCHAIN
|
#define RTM_GETCHAIN RTM_GETCHAIN
|
||||||
|
|
||||||
RTM_NEWNEXTHOP = 104,
|
|
||||||
#define RTM_NEWNEXTHOP RTM_NEWNEXTHOP
|
|
||||||
RTM_DELNEXTHOP,
|
|
||||||
#define RTM_DELNEXTHOP RTM_DELNEXTHOP
|
|
||||||
RTM_GETNEXTHOP,
|
|
||||||
#define RTM_GETNEXTHOP RTM_GETNEXTHOP
|
|
||||||
|
|
||||||
__RTM_MAX,
|
__RTM_MAX,
|
||||||
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
|
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
|
||||||
};
|
};
|
||||||
|
@ -349,7 +342,6 @@ enum rtattr_type_t {
|
||||||
RTA_IP_PROTO,
|
RTA_IP_PROTO,
|
||||||
RTA_SPORT,
|
RTA_SPORT,
|
||||||
RTA_DPORT,
|
RTA_DPORT,
|
||||||
RTA_NH_ID,
|
|
||||||
__RTA_MAX
|
__RTA_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -712,8 +704,6 @@ enum rtnetlink_groups {
|
||||||
#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
|
#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
|
||||||
RTNLGRP_IPV6_MROUTE_R,
|
RTNLGRP_IPV6_MROUTE_R,
|
||||||
#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
|
#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
|
||||||
RTNLGRP_NEXTHOP,
|
|
||||||
#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
|
|
||||||
__RTNLGRP_MAX
|
__RTNLGRP_MAX
|
||||||
};
|
};
|
||||||
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
|
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
|
||||||
|
|
|
@ -164,7 +164,9 @@ static int automount_verify(Automount *a) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(a);
|
assert(a);
|
||||||
assert(UNIT(a)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(a)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (path_equal(a->where, "/")) {
|
if (path_equal(a->where, "/")) {
|
||||||
log_unit_error(UNIT(a), "Cannot have an automount unit for the root directory. Refusing.");
|
log_unit_error(UNIT(a), "Cannot have an automount unit for the root directory. Refusing.");
|
||||||
|
@ -199,9 +201,19 @@ static int automount_set_where(Automount *a) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int automount_add_extras(Automount *a) {
|
static int automount_load(Unit *u) {
|
||||||
|
Automount *a = AUTOMOUNT(u);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
assert(u->load_state == UNIT_STUB);
|
||||||
|
|
||||||
|
/* Load a .automount file */
|
||||||
|
r = unit_load_fragment_and_dropin(u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->load_state == UNIT_LOADED) {
|
||||||
r = automount_set_where(a);
|
r = automount_set_where(a);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -214,28 +226,11 @@ static int automount_add_extras(Automount *a) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return automount_add_default_dependencies(a);
|
r = automount_add_default_dependencies(a);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int automount_load(Unit *u) {
|
|
||||||
Automount *a = AUTOMOUNT(u);
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(u);
|
|
||||||
assert(u->load_state == UNIT_STUB);
|
|
||||||
|
|
||||||
/* Load a .automount file */
|
|
||||||
r = unit_load_fragment_and_dropin(u, true);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = automount_add_extras(a);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return automount_verify(a);
|
return automount_verify(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -970,10 +970,10 @@ static uint64_t cgroup_cpu_weight_to_shares(uint64_t weight) {
|
||||||
CGROUP_CPU_SHARES_MIN, CGROUP_CPU_SHARES_MAX);
|
CGROUP_CPU_SHARES_MIN, CGROUP_CPU_SHARES_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cgroup_apply_unified_cpuset(Unit *u, const CPUSet *cpus, const char *name) {
|
static void cgroup_apply_unified_cpuset(Unit *u, CPUSet cpus, const char *name) {
|
||||||
_cleanup_free_ char *buf = NULL;
|
_cleanup_free_ char *buf = NULL;
|
||||||
|
|
||||||
buf = cpu_set_to_range_string(cpus);
|
buf = cpu_set_to_range_string(&cpus);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1221,8 +1221,8 @@ static void cgroup_context_apply(
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((apply_mask & CGROUP_MASK_CPUSET) && !is_local_root) {
|
if ((apply_mask & CGROUP_MASK_CPUSET) && !is_local_root) {
|
||||||
cgroup_apply_unified_cpuset(u, &c->cpuset_cpus, "cpuset.cpus");
|
cgroup_apply_unified_cpuset(u, c->cpuset_cpus, "cpuset.cpus");
|
||||||
cgroup_apply_unified_cpuset(u, &c->cpuset_mems, "cpuset.mems");
|
cgroup_apply_unified_cpuset(u, c->cpuset_mems, "cpuset.mems");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The 'io' controller attributes are not exported on the host's root cgroup (being a pure cgroup v2
|
/* The 'io' controller attributes are not exported on the host's root cgroup (being a pure cgroup v2
|
||||||
|
|
|
@ -116,7 +116,7 @@ static void device_done(Unit *u) {
|
||||||
static int device_load(Unit *u) {
|
static int device_load(Unit *u) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, false);
|
r = unit_load_fragment_and_dropin_optional(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -513,7 +513,9 @@ static int mount_verify(Mount *m) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(UNIT(m)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(m)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!m->from_fragment && !m->from_proc_self_mountinfo && !UNIT(m)->perpetual)
|
if (!m->from_fragment && !m->from_proc_self_mountinfo && !UNIT(m)->perpetual)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
@ -604,11 +606,11 @@ static int mount_add_extras(Mount *m) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mount_load_root_mount(Unit *u) {
|
static int mount_load_root_mount(Unit *u) {
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|
||||||
if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
|
if (!unit_has_name(u, SPECIAL_ROOT_MOUNT))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
u->perpetual = true;
|
u->perpetual = true;
|
||||||
u->default_dependencies = false;
|
u->default_dependencies = false;
|
||||||
|
@ -619,33 +621,39 @@ static void mount_load_root_mount(Unit *u) {
|
||||||
|
|
||||||
if (!u->description)
|
if (!u->description)
|
||||||
u->description = strdup("Root Mount");
|
u->description = strdup("Root Mount");
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mount_load(Unit *u) {
|
static int mount_load(Unit *u) {
|
||||||
Mount *m = MOUNT(u);
|
Mount *m = MOUNT(u);
|
||||||
int r, q = 0;
|
int r, q, w;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(u->load_state == UNIT_STUB);
|
assert(u->load_state == UNIT_STUB);
|
||||||
|
|
||||||
mount_load_root_mount(u);
|
r = mount_load_root_mount(u);
|
||||||
|
|
||||||
bool fragment_optional = m->from_proc_self_mountinfo || u->perpetual;
|
if (m->from_proc_self_mountinfo || u->perpetual)
|
||||||
r = unit_load_fragment_and_dropin(u, !fragment_optional);
|
q = unit_load_fragment_and_dropin_optional(u);
|
||||||
|
else
|
||||||
|
q = unit_load_fragment_and_dropin(u);
|
||||||
|
|
||||||
/* Add in some extras. Note we do this in all cases (even if we failed to load the unit) when announced by the
|
/* Add in some extras. Note we do this in all cases (even if we failed to load the unit) when announced by the
|
||||||
* kernel, because we need some things to be set up no matter what when the kernel establishes a mount and thus
|
* kernel, because we need some things to be set up no matter what when the kernel establishes a mount and thus
|
||||||
* we need to update the state in our unit to track it. After all, consider that we don't allow changing the
|
* we need to update the state in our unit to track it. After all, consider that we don't allow changing the
|
||||||
* 'slice' field for a unit once it is active. */
|
* 'slice' field for a unit once it is active. */
|
||||||
if (u->load_state == UNIT_LOADED || m->from_proc_self_mountinfo || u->perpetual)
|
if (u->load_state == UNIT_LOADED || m->from_proc_self_mountinfo || u->perpetual)
|
||||||
q = mount_add_extras(m);
|
w = mount_add_extras(m);
|
||||||
|
else
|
||||||
|
w = 0;
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (q < 0)
|
if (q < 0)
|
||||||
return q;
|
return q;
|
||||||
if (u->load_state != UNIT_LOADED)
|
if (w < 0)
|
||||||
return 0;
|
return w;
|
||||||
|
|
||||||
return mount_verify(m);
|
return mount_verify(m);
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,7 +284,9 @@ static int path_add_mount_dependencies(Path *p) {
|
||||||
|
|
||||||
static int path_verify(Path *p) {
|
static int path_verify(Path *p) {
|
||||||
assert(p);
|
assert(p);
|
||||||
assert(UNIT(p)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(p)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!p->specs) {
|
if (!p->specs) {
|
||||||
log_unit_error(UNIT(p), "Path unit lacks path setting. Refusing.");
|
log_unit_error(UNIT(p), "Path unit lacks path setting. Refusing.");
|
||||||
|
@ -331,9 +333,19 @@ static int path_add_trigger_dependencies(Path *p) {
|
||||||
return unit_add_two_dependencies(UNIT(p), UNIT_BEFORE, UNIT_TRIGGERS, x, true, UNIT_DEPENDENCY_IMPLICIT);
|
return unit_add_two_dependencies(UNIT(p), UNIT_BEFORE, UNIT_TRIGGERS, x, true, UNIT_DEPENDENCY_IMPLICIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int path_add_extras(Path *p) {
|
static int path_load(Unit *u) {
|
||||||
|
Path *p = PATH(u);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
assert(u->load_state == UNIT_STUB);
|
||||||
|
|
||||||
|
r = unit_load_fragment_and_dropin(u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->load_state == UNIT_LOADED) {
|
||||||
|
|
||||||
r = path_add_trigger_dependencies(p);
|
r = path_add_trigger_dependencies(p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -342,27 +354,11 @@ static int path_add_extras(Path *p) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
return path_add_default_dependencies(p);
|
r = path_add_default_dependencies(p);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int path_load(Unit *u) {
|
|
||||||
Path *p = PATH(u);
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(u);
|
|
||||||
assert(u->load_state == UNIT_STUB);
|
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, true);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = path_add_extras(p);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return path_verify(p);
|
return path_verify(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,9 @@ static int scope_add_default_dependencies(Scope *s) {
|
||||||
|
|
||||||
static int scope_verify(Scope *s) {
|
static int scope_verify(Scope *s) {
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(UNIT(s)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (set_isempty(UNIT(s)->pids) &&
|
if (set_isempty(UNIT(s)->pids) &&
|
||||||
!MANAGER_IS_RELOADING(UNIT(s)->manager) &&
|
!MANAGER_IS_RELOADING(UNIT(s)->manager) &&
|
||||||
|
@ -160,20 +162,6 @@ static int scope_load_init_scope(Unit *u) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scope_add_extras(Scope *s) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = unit_patch_contexts(UNIT(s));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = unit_set_default_slice(UNIT(s));
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return scope_add_default_dependencies(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int scope_load(Unit *u) {
|
static int scope_load(Unit *u) {
|
||||||
Scope *s = SCOPE(u);
|
Scope *s = SCOPE(u);
|
||||||
int r;
|
int r;
|
||||||
|
@ -188,18 +176,24 @@ static int scope_load(Unit *u) {
|
||||||
r = scope_load_init_scope(u);
|
r = scope_load_init_scope(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
r = unit_load_fragment_and_dropin_optional(u);
|
||||||
r = unit_load_fragment_and_dropin(u, false);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
if (u->load_state == UNIT_LOADED) {
|
||||||
return 0;
|
r = unit_patch_contexts(u);
|
||||||
|
|
||||||
r = scope_add_extras(s);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = unit_set_default_slice(u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = scope_add_default_dependencies(s);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return scope_verify(s);
|
return scope_verify(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,7 +548,9 @@ static int service_arm_timer(Service *s, usec_t usec) {
|
||||||
|
|
||||||
static int service_verify(Service *s) {
|
static int service_verify(Service *s) {
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(UNIT(s)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]
|
if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]
|
||||||
&& UNIT(s)->success_action == EMERGENCY_ACTION_NONE) {
|
&& UNIT(s)->success_action == EMERGENCY_ACTION_NONE) {
|
||||||
|
@ -758,17 +760,32 @@ static int service_load(Unit *u) {
|
||||||
Service *s = SERVICE(u);
|
Service *s = SERVICE(u);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, true);
|
assert(s);
|
||||||
|
|
||||||
|
/* Load a .service file */
|
||||||
|
r = unit_load_fragment(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
/* Still nothing found? Then let's give up */
|
||||||
return 0;
|
if (u->load_state == UNIT_STUB)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
/* This is a new unit? Then let's add in some extras */
|
/* This is a new unit? Then let's add in some extras */
|
||||||
|
if (u->load_state == UNIT_LOADED) {
|
||||||
|
|
||||||
|
/* We were able to load something, then let's add in
|
||||||
|
* the dropin directories. */
|
||||||
|
r = unit_load_dropin(u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
/* This is a new unit? Then let's add in some
|
||||||
|
* extras */
|
||||||
r = service_add_extras(s);
|
r = service_add_extras(s);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return service_verify(s);
|
return service_verify(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,9 @@ static int slice_verify(Slice *s) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(UNIT(s)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!slice_name_is_valid(UNIT(s)->id)) {
|
if (!slice_name_is_valid(UNIT(s)->id)) {
|
||||||
log_unit_error(UNIT(s), "Slice name %s is not valid. Refusing.", UNIT(s)->id);
|
log_unit_error(UNIT(s), "Slice name %s is not valid. Refusing.", UNIT(s)->id);
|
||||||
|
@ -168,14 +170,13 @@ static int slice_load(Unit *u) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, false);
|
r = unit_load_fragment_and_dropin_optional(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* This is a new unit? Then let's add in some extras */
|
/* This is a new unit? Then let's add in some extras */
|
||||||
|
if (u->load_state == UNIT_LOADED) {
|
||||||
|
|
||||||
r = unit_patch_contexts(u);
|
r = unit_patch_contexts(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -187,6 +188,7 @@ static int slice_load(Unit *u) {
|
||||||
r = slice_add_default_dependencies(s);
|
r = slice_add_default_dependencies(s);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return slice_verify(s);
|
return slice_verify(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,7 +433,9 @@ static const char *socket_find_symlink_target(Socket *s) {
|
||||||
|
|
||||||
static int socket_verify(Socket *s) {
|
static int socket_verify(Socket *s) {
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(UNIT(s)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!s->ports) {
|
if (!s->ports) {
|
||||||
log_unit_error(UNIT(s), "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing.");
|
log_unit_error(UNIT(s), "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing.");
|
||||||
|
@ -512,17 +514,16 @@ static int socket_load(Unit *u) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, true);
|
r = unit_load_fragment_and_dropin(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
if (u->load_state == UNIT_LOADED) {
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* This is a new unit? Then let's add in some extras */
|
/* This is a new unit? Then let's add in some extras */
|
||||||
r = socket_add_extras(s);
|
r = socket_add_extras(s);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return socket_verify(s);
|
return socket_verify(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -232,7 +232,8 @@ static int swap_verify(Swap *s) {
|
||||||
_cleanup_free_ char *e = NULL;
|
_cleanup_free_ char *e = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(UNIT(s)->load_state == UNIT_LOADED);
|
if (UNIT(s)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
r = unit_name_from_path(s->what, ".swap", &e);
|
r = unit_name_from_path(s->what, ".swap", &e);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -339,26 +340,28 @@ static int swap_add_extras(Swap *s) {
|
||||||
|
|
||||||
static int swap_load(Unit *u) {
|
static int swap_load(Unit *u) {
|
||||||
Swap *s = SWAP(u);
|
Swap *s = SWAP(u);
|
||||||
int r, q = 0;
|
int r, q;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(u->load_state == UNIT_STUB);
|
assert(u->load_state == UNIT_STUB);
|
||||||
|
|
||||||
/* Load a .swap file */
|
/* Load a .swap file */
|
||||||
bool fragment_optional = s->from_proc_swaps;
|
if (SWAP(u)->from_proc_swaps)
|
||||||
r = unit_load_fragment_and_dropin(u, !fragment_optional);
|
r = unit_load_fragment_and_dropin_optional(u);
|
||||||
|
else
|
||||||
|
r = unit_load_fragment_and_dropin(u);
|
||||||
|
|
||||||
/* Add in some extras, and do so either when we successfully loaded something or when /proc/swaps is
|
/* Add in some extras, and do so either when we successfully loaded something or when /proc/swaps is already
|
||||||
* already active. */
|
* active. */
|
||||||
if (u->load_state == UNIT_LOADED || s->from_proc_swaps)
|
if (u->load_state == UNIT_LOADED || s->from_proc_swaps)
|
||||||
q = swap_add_extras(s);
|
q = swap_add_extras(s);
|
||||||
|
else
|
||||||
|
q = 0;
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (q < 0)
|
if (q < 0)
|
||||||
return q;
|
return q;
|
||||||
if (u->load_state != UNIT_LOADED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return swap_verify(s);
|
return swap_verify(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,15 +80,18 @@ static int target_load(Unit *u) {
|
||||||
|
|
||||||
assert(t);
|
assert(t);
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, true);
|
r = unit_load_fragment_and_dropin(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* This is a new unit? Then let's add in some extras */
|
/* This is a new unit? Then let's add in some extras */
|
||||||
return target_add_default_dependencies(t);
|
if (u->load_state == UNIT_LOADED) {
|
||||||
|
r = target_add_default_dependencies(t);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int target_coldplug(Unit *u) {
|
static int target_coldplug(Unit *u) {
|
||||||
|
|
|
@ -73,7 +73,9 @@ static void timer_done(Unit *u) {
|
||||||
|
|
||||||
static int timer_verify(Timer *t) {
|
static int timer_verify(Timer *t) {
|
||||||
assert(t);
|
assert(t);
|
||||||
assert(UNIT(t)->load_state == UNIT_LOADED);
|
|
||||||
|
if (UNIT(t)->load_state != UNIT_LOADED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!t->values && !t->on_clock_change && !t->on_timezone_change) {
|
if (!t->values && !t->on_clock_change && !t->on_timezone_change) {
|
||||||
log_unit_error(UNIT(t), "Timer unit lacks value setting. Refusing.");
|
log_unit_error(UNIT(t), "Timer unit lacks value setting. Refusing.");
|
||||||
|
@ -176,14 +178,12 @@ static int timer_load(Unit *u) {
|
||||||
assert(u);
|
assert(u);
|
||||||
assert(u->load_state == UNIT_STUB);
|
assert(u->load_state == UNIT_STUB);
|
||||||
|
|
||||||
r = unit_load_fragment_and_dropin(u, true);
|
r = unit_load_fragment_and_dropin(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state != UNIT_LOADED)
|
if (u->load_state == UNIT_LOADED) {
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* This is a new unit? Then let's add in some extras */
|
|
||||||
r = timer_add_trigger_dependencies(t);
|
r = timer_add_trigger_dependencies(t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -195,6 +195,7 @@ static int timer_load(Unit *u) {
|
||||||
r = timer_add_default_dependencies(t);
|
r = timer_add_default_dependencies(t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return timer_verify(t);
|
return timer_verify(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1361,7 +1361,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Common implementation for multiple backends */
|
/* Common implementation for multiple backends */
|
||||||
int unit_load_fragment_and_dropin(Unit *u, bool fragment_required) {
|
int unit_load_fragment_and_dropin(Unit *u) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
|
@ -1371,13 +1371,9 @@ int unit_load_fragment_and_dropin(Unit *u, bool fragment_required) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (u->load_state == UNIT_STUB) {
|
if (u->load_state == UNIT_STUB)
|
||||||
if (fragment_required)
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
u->load_state = UNIT_LOADED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load drop-in directory data. If u is an alias, we might be reloading the
|
/* Load drop-in directory data. If u is an alias, we might be reloading the
|
||||||
* target unit needlessly. But we cannot be sure which drops-ins have already
|
* target unit needlessly. But we cannot be sure which drops-ins have already
|
||||||
* been loaded and which not, at least without doing complicated book-keeping,
|
* been loaded and which not, at least without doing complicated book-keeping,
|
||||||
|
@ -1385,6 +1381,27 @@ int unit_load_fragment_and_dropin(Unit *u, bool fragment_required) {
|
||||||
return unit_load_dropin(unit_follow_merge(u));
|
return unit_load_dropin(unit_follow_merge(u));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Common implementation for multiple backends */
|
||||||
|
int unit_load_fragment_and_dropin_optional(Unit *u) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
|
||||||
|
/* Same as unit_load_fragment_and_dropin(), but whether
|
||||||
|
* something can be loaded or not doesn't matter. */
|
||||||
|
|
||||||
|
/* Load a .service/.socket/.slice/… file */
|
||||||
|
r = unit_load_fragment(u);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u->load_state == UNIT_STUB)
|
||||||
|
u->load_state = UNIT_LOADED;
|
||||||
|
|
||||||
|
/* Load drop-in directory data */
|
||||||
|
return unit_load_dropin(unit_follow_merge(u));
|
||||||
|
}
|
||||||
|
|
||||||
void unit_add_to_target_deps_queue(Unit *u) {
|
void unit_add_to_target_deps_queue(Unit *u) {
|
||||||
Manager *m = u->manager;
|
Manager *m = u->manager;
|
||||||
|
|
||||||
|
@ -1542,11 +1559,16 @@ int unit_load(Unit *u) {
|
||||||
u->fragment_mtime = now(CLOCK_REALTIME);
|
u->fragment_mtime = now(CLOCK_REALTIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNIT_VTABLE(u)->load) {
|
||||||
r = UNIT_VTABLE(u)->load(u);
|
r = UNIT_VTABLE(u)->load(u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
assert(u->load_state != UNIT_STUB);
|
if (u->load_state == UNIT_STUB) {
|
||||||
|
r = -ENOENT;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (u->load_state == UNIT_LOADED) {
|
if (u->load_state == UNIT_LOADED) {
|
||||||
unit_add_to_target_deps_queue(u);
|
unit_add_to_target_deps_queue(u);
|
||||||
|
|
|
@ -670,7 +670,8 @@ int unit_merge_by_name(Unit *u, const char *other);
|
||||||
|
|
||||||
Unit *unit_follow_merge(Unit *u) _pure_;
|
Unit *unit_follow_merge(Unit *u) _pure_;
|
||||||
|
|
||||||
int unit_load_fragment_and_dropin(Unit *u, bool fragment_required);
|
int unit_load_fragment_and_dropin(Unit *u);
|
||||||
|
int unit_load_fragment_and_dropin_optional(Unit *u);
|
||||||
int unit_load(Unit *unit);
|
int unit_load(Unit *unit);
|
||||||
|
|
||||||
int unit_set_slice(Unit *u, Unit *slice);
|
int unit_set_slice(Unit *u, Unit *slice);
|
||||||
|
|
|
@ -88,8 +88,7 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
|
||||||
assert_return(m, -EINVAL);
|
assert_return(m, -EINVAL);
|
||||||
assert_return(m->hdr, -EINVAL);
|
assert_return(m->hdr, -EINVAL);
|
||||||
|
|
||||||
assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH,
|
assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH, RTM_GETRULE, RTM_GETADDRLABEL), -EINVAL);
|
||||||
RTM_GETRULE, RTM_GETADDRLABEL, RTM_GETNEXTHOP), -EINVAL);
|
|
||||||
|
|
||||||
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
|
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include <linux/if_link.h>
|
#include <linux/if_link.h>
|
||||||
#include <linux/if_macsec.h>
|
#include <linux/if_macsec.h>
|
||||||
#include <linux/if_tunnel.h>
|
#include <linux/if_tunnel.h>
|
||||||
#include <linux/nexthop.h>
|
|
||||||
#include <linux/l2tp.h>
|
#include <linux/l2tp.h>
|
||||||
#include <linux/veth.h>
|
#include <linux/veth.h>
|
||||||
#include <linux/wireguard.h>
|
#include <linux/wireguard.h>
|
||||||
|
@ -717,17 +716,6 @@ static const NLTypeSystem rtnl_routing_policy_rule_type_system = {
|
||||||
.types = rtnl_routing_policy_rule_types,
|
.types = rtnl_routing_policy_rule_types,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NLType rtnl_nexthop_types[] = {
|
|
||||||
[NHA_ID] = { .type = NETLINK_TYPE_U32 },
|
|
||||||
[NHA_OIF] = { .type = NETLINK_TYPE_U32 },
|
|
||||||
[NHA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const NLTypeSystem rtnl_nexthop_type_system = {
|
|
||||||
.count = ELEMENTSOF(rtnl_nexthop_types),
|
|
||||||
.types = rtnl_nexthop_types,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const NLType rtnl_types[] = {
|
static const NLType rtnl_types[] = {
|
||||||
[NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
|
[NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
|
||||||
[NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
|
[NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
|
||||||
|
@ -750,9 +738,6 @@ static const NLType rtnl_types[] = {
|
||||||
[RTM_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
|
[RTM_NEWRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
|
||||||
[RTM_DELRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
|
[RTM_DELRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
|
||||||
[RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
|
[RTM_GETRULE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_routing_policy_rule_type_system, .size = sizeof(struct rtmsg) },
|
||||||
[RTM_NEWNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) },
|
|
||||||
[RTM_DELNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) },
|
|
||||||
[RTM_GETNEXTHOP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_nexthop_type_system, .size = sizeof(struct nhmsg) },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const NLTypeSystem rtnl_type_system_root = {
|
const NLTypeSystem rtnl_type_system_root = {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/rtnetlink.h>
|
|
||||||
|
|
||||||
#include "sd-netlink.h"
|
#include "sd-netlink.h"
|
||||||
|
|
||||||
#include "in-addr-util.h"
|
#include "in-addr-util.h"
|
||||||
|
@ -21,10 +19,6 @@ static inline bool rtnl_message_type_is_route(uint16_t type) {
|
||||||
return IN_SET(type, RTM_NEWROUTE, RTM_GETROUTE, RTM_DELROUTE);
|
return IN_SET(type, RTM_NEWROUTE, RTM_GETROUTE, RTM_DELROUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool rtnl_message_type_is_nexthop(uint16_t type) {
|
|
||||||
return IN_SET(type, RTM_NEWNEXTHOP, RTM_GETNEXTHOP, RTM_DELNEXTHOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool rtnl_message_type_is_link(uint16_t type) {
|
static inline bool rtnl_message_type_is_link(uint16_t type) {
|
||||||
return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
|
return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <linux/if_addrlabel.h>
|
#include <linux/if_addrlabel.h>
|
||||||
#include <linux/nexthop.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -286,70 +285,6 @@ int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret,
|
|
||||||
uint16_t nhmsg_type, int nh_family,
|
|
||||||
unsigned char nh_protocol) {
|
|
||||||
struct nhmsg *nhm;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert_return(rtnl_message_type_is_nexthop(nhmsg_type), -EINVAL);
|
|
||||||
assert_return((nhmsg_type == RTM_GETNEXTHOP && nh_family == AF_UNSPEC) ||
|
|
||||||
IN_SET(nh_family, AF_INET, AF_INET6), -EINVAL);
|
|
||||||
assert_return(ret, -EINVAL);
|
|
||||||
|
|
||||||
r = message_new(rtnl, ret, nhmsg_type);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (nhmsg_type == RTM_NEWNEXTHOP)
|
|
||||||
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
|
|
||||||
|
|
||||||
nhm = NLMSG_DATA((*ret)->hdr);
|
|
||||||
|
|
||||||
nhm->nh_family = nh_family;
|
|
||||||
nhm->nh_scope = RT_SCOPE_UNIVERSE;
|
|
||||||
nhm->nh_protocol = nh_protocol;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags) {
|
|
||||||
struct nhmsg *nhm;
|
|
||||||
|
|
||||||
assert_return(m, -EINVAL);
|
|
||||||
assert_return(m->hdr, -EINVAL);
|
|
||||||
assert_return(rtnl_message_type_is_nexthop(m->hdr->nlmsg_type), -EINVAL);
|
|
||||||
|
|
||||||
nhm = NLMSG_DATA(m->hdr);
|
|
||||||
nhm->nh_flags |= flags;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_rtnl_message_nexthop_set_family(sd_netlink_message *m, uint8_t family) {
|
|
||||||
struct nhmsg *nhm;
|
|
||||||
|
|
||||||
assert_return(m, -EINVAL);
|
|
||||||
assert_return(m->hdr, -EINVAL);
|
|
||||||
|
|
||||||
nhm = NLMSG_DATA(m->hdr);
|
|
||||||
nhm->nh_family = family;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family) {
|
|
||||||
struct nhmsg *nhm;
|
|
||||||
|
|
||||||
assert_return(m, -EINVAL);
|
|
||||||
assert_return(m->hdr, -EINVAL);
|
|
||||||
|
|
||||||
nhm = NLMSG_DATA(m->hdr);
|
|
||||||
*family = nhm->nh_family ;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) {
|
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) {
|
||||||
struct ndmsg *ndm;
|
struct ndmsg *ndm;
|
||||||
|
|
||||||
|
@ -778,14 +713,6 @@ int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) {
|
||||||
|
|
||||||
*family = rtm->rtm_family;
|
*family = rtm->rtm_family;
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else if (rtnl_message_type_is_nexthop(m->hdr->nlmsg_type)) {
|
|
||||||
struct nhmsg *nhm;
|
|
||||||
|
|
||||||
nhm = NLMSG_DATA(m->hdr);
|
|
||||||
|
|
||||||
*family = nhm->nh_family;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -896,13 +896,6 @@ int sd_netlink_add_match(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
case RTM_NEWNEXTHOP:
|
|
||||||
case RTM_DELNEXTHOP:
|
|
||||||
r = socket_broadcast_group_ref(rtnl, RTNLGRP_NEXTHOP);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,8 +93,6 @@ sources = files('''
|
||||||
networkd-network-bus.h
|
networkd-network-bus.h
|
||||||
networkd-network.c
|
networkd-network.c
|
||||||
networkd-network.h
|
networkd-network.h
|
||||||
networkd-nexthop.c
|
|
||||||
networkd-nexthop.h
|
|
||||||
networkd-route.c
|
networkd-route.c
|
||||||
networkd-route.h
|
networkd-route.h
|
||||||
networkd-routing-policy-rule.c
|
networkd-routing-policy-rule.c
|
||||||
|
|
|
@ -672,9 +672,6 @@ static Link *link_free(Link *link) {
|
||||||
link->routes = set_free_with_destructor(link->routes, route_free);
|
link->routes = set_free_with_destructor(link->routes, route_free);
|
||||||
link->routes_foreign = set_free_with_destructor(link->routes_foreign, route_free);
|
link->routes_foreign = set_free_with_destructor(link->routes_foreign, route_free);
|
||||||
|
|
||||||
link->nexthops = set_free_with_destructor(link->nexthops, nexthop_free);
|
|
||||||
link->nexthops_foreign = set_free_with_destructor(link->nexthops_foreign, nexthop_free);
|
|
||||||
|
|
||||||
link->neighbors = set_free_with_destructor(link->neighbors, neighbor_free);
|
link->neighbors = set_free_with_destructor(link->neighbors, neighbor_free);
|
||||||
link->neighbors_foreign = set_free_with_destructor(link->neighbors_foreign, neighbor_free);
|
link->neighbors_foreign = set_free_with_destructor(link->neighbors_foreign, neighbor_free);
|
||||||
|
|
||||||
|
@ -906,58 +903,6 @@ static int link_request_set_routing_policy_rule(Link *link) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(link->nexthop_messages > 0);
|
|
||||||
assert(IN_SET(link->state, LINK_STATE_CONFIGURING,
|
|
||||||
LINK_STATE_FAILED, LINK_STATE_LINGER));
|
|
||||||
|
|
||||||
link->nexthop_messages--;
|
|
||||||
|
|
||||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
|
||||||
if (r < 0 && r != -EEXIST) {
|
|
||||||
log_link_warning_errno(link, r, "Could not set nexthop: %m");
|
|
||||||
link_enter_failed(link);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link->nexthop_messages == 0) {
|
|
||||||
log_link_debug(link, "Nexthop set");
|
|
||||||
link->static_nexthops_configured = true;
|
|
||||||
link_check_ready(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int link_request_set_nexthop(Link *link) {
|
|
||||||
NextHop *nh;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
LIST_FOREACH(nexthops, nh, link->network->static_nexthops) {
|
|
||||||
r = nexthop_configure(nh, link, nexthop_handler);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_warning_errno(link, r, "Could not set nexthop: %m");
|
|
||||||
if (r > 0)
|
|
||||||
link->nexthop_messages++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link->nexthop_messages == 0) {
|
|
||||||
link->static_nexthops_configured = true;
|
|
||||||
link_check_ready(link);
|
|
||||||
} else {
|
|
||||||
log_link_debug(link, "Setting nexthop");
|
|
||||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -1003,7 +948,6 @@ int link_request_set_routes(Link *link) {
|
||||||
assert(link->state != _LINK_STATE_INVALID);
|
assert(link->state != _LINK_STATE_INVALID);
|
||||||
|
|
||||||
link->static_routes_configured = false;
|
link->static_routes_configured = false;
|
||||||
link->static_routes_ready = false;
|
|
||||||
|
|
||||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||||
/* During configuring addresses, the link lost its carrier. As networkd is dropping
|
/* During configuring addresses, the link lost its carrier. As networkd is dropping
|
||||||
|
@ -1073,17 +1017,6 @@ void link_check_ready(Link *link) {
|
||||||
if (!link->static_routes_configured)
|
if (!link->static_routes_configured)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!link->static_routes_ready) {
|
|
||||||
link->static_routes_ready = true;
|
|
||||||
r = link_request_set_nexthop(link);
|
|
||||||
if (r < 0)
|
|
||||||
link_enter_failed(link);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!link->static_nexthops_configured)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!link->routing_policy_rules_configured)
|
if (!link->routing_policy_rules_configured)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1201,8 +1134,6 @@ static int link_request_set_addresses(Link *link) {
|
||||||
link->addresses_ready = false;
|
link->addresses_ready = false;
|
||||||
link->neighbors_configured = false;
|
link->neighbors_configured = false;
|
||||||
link->static_routes_configured = false;
|
link->static_routes_configured = false;
|
||||||
link->static_routes_ready = false;
|
|
||||||
link->static_nexthops_configured = false;
|
|
||||||
link->routing_policy_rules_configured = false;
|
link->routing_policy_rules_configured = false;
|
||||||
|
|
||||||
r = link_set_bridge_fdb(link);
|
r = link_set_bridge_fdb(link);
|
||||||
|
|
|
@ -69,7 +69,6 @@ typedef struct Link {
|
||||||
unsigned address_label_messages;
|
unsigned address_label_messages;
|
||||||
unsigned neighbor_messages;
|
unsigned neighbor_messages;
|
||||||
unsigned route_messages;
|
unsigned route_messages;
|
||||||
unsigned nexthop_messages;
|
|
||||||
unsigned routing_policy_rule_messages;
|
unsigned routing_policy_rule_messages;
|
||||||
unsigned routing_policy_rule_remove_messages;
|
unsigned routing_policy_rule_remove_messages;
|
||||||
unsigned enslaving;
|
unsigned enslaving;
|
||||||
|
@ -80,8 +79,9 @@ typedef struct Link {
|
||||||
Set *neighbors_foreign;
|
Set *neighbors_foreign;
|
||||||
Set *routes;
|
Set *routes;
|
||||||
Set *routes_foreign;
|
Set *routes_foreign;
|
||||||
Set *nexthops;
|
|
||||||
Set *nexthops_foreign;
|
bool addresses_configured;
|
||||||
|
bool addresses_ready;
|
||||||
|
|
||||||
sd_dhcp_client *dhcp_client;
|
sd_dhcp_client *dhcp_client;
|
||||||
sd_dhcp_lease *dhcp_lease, *dhcp_lease_old;
|
sd_dhcp_lease *dhcp_lease, *dhcp_lease_old;
|
||||||
|
@ -100,12 +100,8 @@ typedef struct Link {
|
||||||
sd_ipv4ll *ipv4ll;
|
sd_ipv4ll *ipv4ll;
|
||||||
bool ipv4ll_address:1;
|
bool ipv4ll_address:1;
|
||||||
|
|
||||||
bool addresses_configured:1;
|
|
||||||
bool addresses_ready:1;
|
|
||||||
bool neighbors_configured:1;
|
bool neighbors_configured:1;
|
||||||
bool static_routes_configured:1;
|
bool static_routes_configured:1;
|
||||||
bool static_routes_ready:1;
|
|
||||||
bool static_nexthops_configured:1;
|
|
||||||
bool routing_policy_rules_configured:1;
|
bool routing_policy_rules_configured:1;
|
||||||
bool setting_mtu:1;
|
bool setting_mtu:1;
|
||||||
|
|
||||||
|
@ -202,7 +198,6 @@ uint32_t link_get_vrf_table(Link *link);
|
||||||
uint32_t link_get_dhcp_route_table(Link *link);
|
uint32_t link_get_dhcp_route_table(Link *link);
|
||||||
uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
|
uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
|
||||||
int link_request_set_routes(Link *link);
|
int link_request_set_routes(Link *link);
|
||||||
int link_request_set_nexthop(Link *link);
|
|
||||||
|
|
||||||
#define ADDRESS_FMT_VAL(address) \
|
#define ADDRESS_FMT_VAL(address) \
|
||||||
be32toh((address).s_addr) >> 24, \
|
be32toh((address).s_addr) >> 24, \
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <linux/fib_rules.h>
|
#include <linux/fib_rules.h>
|
||||||
#include <linux/nexthop.h>
|
|
||||||
|
|
||||||
#include "sd-daemon.h"
|
#include "sd-daemon.h"
|
||||||
#include "sd-netlink.h"
|
#include "sd-netlink.h"
|
||||||
|
@ -1154,118 +1153,6 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
|
|
||||||
_cleanup_(nexthop_freep) NextHop *tmp = NULL;
|
|
||||||
_cleanup_free_ char *gateway = NULL;
|
|
||||||
NextHop *nexthop = NULL;
|
|
||||||
Manager *m = userdata;
|
|
||||||
Link *link = NULL;
|
|
||||||
uint16_t type;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(rtnl);
|
|
||||||
assert(message);
|
|
||||||
assert(m);
|
|
||||||
|
|
||||||
if (sd_netlink_message_is_error(message)) {
|
|
||||||
r = sd_netlink_message_get_errno(message);
|
|
||||||
if (r < 0)
|
|
||||||
log_warning_errno(r, "rtnl: failed to receive rule message, ignoring: %m");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_netlink_message_get_type(message, &type);
|
|
||||||
if (r < 0) {
|
|
||||||
log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
} else if (!IN_SET(type, RTM_NEWNEXTHOP, RTM_DELNEXTHOP)) {
|
|
||||||
log_warning("rtnl: received unexpected message type %u when processing nexthop, ignoring.", type);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = nexthop_new(&tmp);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = sd_rtnl_message_get_family(message, &tmp->family);
|
|
||||||
if (r < 0) {
|
|
||||||
log_warning_errno(r, "rtnl: could not get nexthop family, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
} else if (!IN_SET(tmp->family, AF_INET, AF_INET6)) {
|
|
||||||
log_debug("rtnl: received nexthop message with invalid family %d, ignoring.", tmp->family);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tmp->family) {
|
|
||||||
case AF_INET:
|
|
||||||
r = sd_netlink_message_read_in_addr(message, NHA_GATEWAY, &tmp->gw.in);
|
|
||||||
if (r < 0 && r != -ENODATA) {
|
|
||||||
log_warning_errno(r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AF_INET6:
|
|
||||||
r = sd_netlink_message_read_in6_addr(message, NHA_GATEWAY, &tmp->gw.in6);
|
|
||||||
if (r < 0 && r != -ENODATA) {
|
|
||||||
log_warning_errno(r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert_not_reached("Received rule message with unsupported address family");
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_netlink_message_read_u32(message, NHA_ID, &tmp->id);
|
|
||||||
if (r < 0 && r != -ENODATA) {
|
|
||||||
log_warning_errno(r, "rtnl: could not get NHA_ID attribute, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_netlink_message_read_u32(message, NHA_OIF, &tmp->oif);
|
|
||||||
if (r < 0 && r != -ENODATA) {
|
|
||||||
log_warning_errno(r, "rtnl: could not get NHA_OIF attribute, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = link_get(m, tmp->oif, &link);
|
|
||||||
if (r < 0 || !link) {
|
|
||||||
if (!m->enumerating)
|
|
||||||
log_warning("rtnl: received nexthop message for link (%d) we do not know about, ignoring", tmp->oif);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) nexthop_get(link, tmp, &nexthop);
|
|
||||||
|
|
||||||
if (DEBUG_LOGGING)
|
|
||||||
(void) in_addr_to_string(tmp->family, &tmp->gw, &gateway);
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case RTM_NEWNEXTHOP:
|
|
||||||
if (!nexthop) {
|
|
||||||
log_debug("Remembering foreign nexthop: %s, oif: %d, id: %d", gateway, tmp->oif, tmp->id);
|
|
||||||
r = nexthop_add_foreign(link, tmp, &nexthop);
|
|
||||||
if (r < 0) {
|
|
||||||
log_warning_errno(r, "Could not remember foreign nexthop, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RTM_DELNEXTHOP:
|
|
||||||
log_debug("Forgetting foreign nexthop: %s, oif: %d, id: %d", gateway, tmp->oif, tmp->id);
|
|
||||||
nexthop_free(nexthop);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert_not_reached("Received invalid RTNL message type");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int systemd_netlink_fd(void) {
|
static int systemd_netlink_fd(void) {
|
||||||
int n, fd, rtnl_fd = -EINVAL;
|
int n, fd, rtnl_fd = -EINVAL;
|
||||||
|
|
||||||
|
@ -1366,14 +1253,6 @@ static int manager_connect_rtnl(Manager *m) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, NULL, RTM_NEWNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_netlink_add_match(m->rtnl, NULL, RTM_DELNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2052,47 +1931,6 @@ int manager_rtnl_enumerate_rules(Manager *m) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_rtnl_enumerate_nexthop(Manager *m) {
|
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
|
||||||
sd_netlink_message *nexthop;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(m);
|
|
||||||
assert(m->rtnl);
|
|
||||||
|
|
||||||
r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_netlink_message_request_dump(req, true);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_netlink_call(m->rtnl, req, 0, &reply);
|
|
||||||
if (r < 0) {
|
|
||||||
if (r == -EOPNOTSUPP) {
|
|
||||||
log_debug("Nexthop are not supported by the kernel. Ignoring.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (nexthop = reply; nexthop; nexthop = sd_netlink_message_next(nexthop)) {
|
|
||||||
int k;
|
|
||||||
|
|
||||||
m->enumerating = true;
|
|
||||||
|
|
||||||
k = manager_rtnl_process_nexthop(m->rtnl, nexthop, m);
|
|
||||||
if (k < 0)
|
|
||||||
r = k;
|
|
||||||
|
|
||||||
m->enumerating = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
|
int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
|
||||||
AddressPool *p;
|
AddressPool *p;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -83,13 +83,11 @@ int manager_rtnl_enumerate_addresses(Manager *m);
|
||||||
int manager_rtnl_enumerate_neighbors(Manager *m);
|
int manager_rtnl_enumerate_neighbors(Manager *m);
|
||||||
int manager_rtnl_enumerate_routes(Manager *m);
|
int manager_rtnl_enumerate_routes(Manager *m);
|
||||||
int manager_rtnl_enumerate_rules(Manager *m);
|
int manager_rtnl_enumerate_rules(Manager *m);
|
||||||
int manager_rtnl_enumerate_nexthop(Manager *m);
|
|
||||||
|
|
||||||
int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
||||||
int manager_rtnl_process_neighbor(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
int manager_rtnl_process_neighbor(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
||||||
int manager_rtnl_process_route(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
int manager_rtnl_process_route(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
||||||
int manager_rtnl_process_rule(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
int manager_rtnl_process_rule(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
||||||
int manager_rtnl_process_nexthop(sd_netlink *nl, sd_netlink_message *message, void *userdata);
|
|
||||||
|
|
||||||
void manager_dirty(Manager *m);
|
void manager_dirty(Manager *m);
|
||||||
|
|
||||||
|
|
|
@ -546,7 +546,6 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link);
|
assert(link);
|
||||||
assert(link->network);
|
|
||||||
assert(rt);
|
assert(rt);
|
||||||
|
|
||||||
r = sd_ndisc_router_option_rewind(rt);
|
r = sd_ndisc_router_option_rewind(rt);
|
||||||
|
@ -565,24 +564,8 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
case SD_NDISC_OPTION_PREFIX_INFORMATION: {
|
case SD_NDISC_OPTION_PREFIX_INFORMATION: {
|
||||||
union in_addr_union a;
|
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
|
||||||
r = sd_ndisc_router_prefix_get_address(rt, &a.in6);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
|
||||||
|
|
||||||
if (set_contains(link->network->ndisc_black_listed_prefix, &a.in6)) {
|
|
||||||
if (DEBUG_LOGGING) {
|
|
||||||
_cleanup_free_ char *b = NULL;
|
|
||||||
|
|
||||||
(void) in_addr_to_string(AF_INET6, &a, &b);
|
|
||||||
log_link_debug(link, "Prefix '%s' is black listed, ignoring", strna(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
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_warning_errno(link, r, "Failed to get RA prefix flags: %m");
|
||||||
|
@ -619,6 +602,46 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ndisc_prefix_is_black_listed(Link *link, sd_ndisc_router *rt) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(link->network);
|
||||||
|
assert(rt);
|
||||||
|
|
||||||
|
for (r = sd_ndisc_router_option_rewind(rt); ; r = sd_ndisc_router_option_next(rt)) {
|
||||||
|
union in_addr_union a;
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Failed to iterate through options: %m");
|
||||||
|
if (r == 0) /* EOF */
|
||||||
|
return false;
|
||||||
|
|
||||||
|
r = sd_ndisc_router_option_get_type(rt, &type);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Failed to get RA option type: %m");
|
||||||
|
|
||||||
|
if (type != SD_NDISC_OPTION_PREFIX_INFORMATION)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r = sd_ndisc_router_prefix_get_address(rt, &a.in6);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
||||||
|
|
||||||
|
if (set_contains(link->network->ndisc_black_listed_prefix, &a.in6)) {
|
||||||
|
if (DEBUG_LOGGING) {
|
||||||
|
_cleanup_free_ char *b = NULL;
|
||||||
|
|
||||||
|
(void) in_addr_to_string(AF_INET6, &a, &b);
|
||||||
|
log_link_debug(link, "Prefix '%s' is black listed, ignoring", strna(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
int r;
|
int r;
|
||||||
|
@ -643,8 +666,10 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ndisc_prefix_is_black_listed(link, rt) == 0) {
|
||||||
(void) ndisc_router_process_default(link, rt);
|
(void) ndisc_router_process_default(link, rt);
|
||||||
(void) ndisc_router_process_options(link, rt);
|
(void) ndisc_router_process_options(link, rt);
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,8 +141,6 @@ Route.InitialAdvertisedReceiveWindow, config_parse_tcp_window,
|
||||||
Route.QuickAck, config_parse_quickack, 0, 0
|
Route.QuickAck, config_parse_quickack, 0, 0
|
||||||
Route.FastOpenNoCookie, config_parse_fast_open_no_cookie, 0, 0
|
Route.FastOpenNoCookie, config_parse_fast_open_no_cookie, 0, 0
|
||||||
Route.TTLPropagate, config_parse_route_ttl_propagate, 0, 0
|
Route.TTLPropagate, config_parse_route_ttl_propagate, 0, 0
|
||||||
NextHop.Id, config_parse_nexthop_id, 0, 0
|
|
||||||
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
|
||||||
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
|
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
|
||||||
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
|
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
|
||||||
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
|
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
|
||||||
|
|
|
@ -151,7 +151,6 @@ int network_verify(Network *network) {
|
||||||
AddressLabel *label, *label_next;
|
AddressLabel *label, *label_next;
|
||||||
Prefix *prefix, *prefix_next;
|
Prefix *prefix, *prefix_next;
|
||||||
RoutingPolicyRule *rule, *rule_next;
|
RoutingPolicyRule *rule, *rule_next;
|
||||||
NextHop *nexthop, *nextnop_next;
|
|
||||||
|
|
||||||
assert(network);
|
assert(network);
|
||||||
assert(network->filename);
|
assert(network->filename);
|
||||||
|
@ -283,10 +282,6 @@ int network_verify(Network *network) {
|
||||||
if (route_section_verify(route, network) < 0)
|
if (route_section_verify(route, network) < 0)
|
||||||
route_free(route);
|
route_free(route);
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(nexthops, nexthop, nextnop_next, network->static_nexthops)
|
|
||||||
if (nexthop_section_verify(nexthop) < 0)
|
|
||||||
nexthop_free(nexthop);
|
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(static_fdb_entries, fdb, fdb_next, network->static_fdb_entries)
|
LIST_FOREACH_SAFE(static_fdb_entries, fdb, fdb_next, network->static_fdb_entries)
|
||||||
if (section_is_invalid(fdb->section))
|
if (section_is_invalid(fdb->section))
|
||||||
fdb_entry_free(fdb);
|
fdb_entry_free(fdb);
|
||||||
|
@ -458,9 +453,8 @@ int network_load_one(Manager *manager, const char *filename) {
|
||||||
"IPv6AddressLabel\0"
|
"IPv6AddressLabel\0"
|
||||||
"RoutingPolicyRule\0"
|
"RoutingPolicyRule\0"
|
||||||
"Route\0"
|
"Route\0"
|
||||||
"NextHop\0"
|
"DHCP\0"
|
||||||
"DHCP\0" /* compat */
|
"DHCPv4\0" /* compat */
|
||||||
"DHCPv4\0"
|
|
||||||
"DHCPv6\0"
|
"DHCPv6\0"
|
||||||
"DHCPServer\0"
|
"DHCPServer\0"
|
||||||
"IPv6AcceptRA\0"
|
"IPv6AcceptRA\0"
|
||||||
|
@ -531,9 +525,8 @@ static Network *network_free(Network *network) {
|
||||||
FdbEntry *fdb_entry;
|
FdbEntry *fdb_entry;
|
||||||
Neighbor *neighbor;
|
Neighbor *neighbor;
|
||||||
AddressLabel *label;
|
AddressLabel *label;
|
||||||
Address *address;
|
|
||||||
NextHop *nexthop;
|
|
||||||
Prefix *prefix;
|
Prefix *prefix;
|
||||||
|
Address *address;
|
||||||
Route *route;
|
Route *route;
|
||||||
|
|
||||||
if (!network)
|
if (!network)
|
||||||
|
@ -580,9 +573,6 @@ static Network *network_free(Network *network) {
|
||||||
while ((route = network->static_routes))
|
while ((route = network->static_routes))
|
||||||
route_free(route);
|
route_free(route);
|
||||||
|
|
||||||
while ((nexthop = network->static_nexthops))
|
|
||||||
nexthop_free(nexthop);
|
|
||||||
|
|
||||||
while ((address = network->static_addresses))
|
while ((address = network->static_addresses))
|
||||||
address_free(address);
|
address_free(address);
|
||||||
|
|
||||||
|
@ -606,7 +596,6 @@ static Network *network_free(Network *network) {
|
||||||
|
|
||||||
hashmap_free(network->addresses_by_section);
|
hashmap_free(network->addresses_by_section);
|
||||||
hashmap_free(network->routes_by_section);
|
hashmap_free(network->routes_by_section);
|
||||||
hashmap_free(network->nexthops_by_section);
|
|
||||||
hashmap_free(network->fdb_entries_by_section);
|
hashmap_free(network->fdb_entries_by_section);
|
||||||
hashmap_free(network->neighbors_by_section);
|
hashmap_free(network->neighbors_by_section);
|
||||||
hashmap_free(network->address_labels_by_section);
|
hashmap_free(network->address_labels_by_section);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "networkd-lldp-rx.h"
|
#include "networkd-lldp-rx.h"
|
||||||
#include "networkd-lldp-tx.h"
|
#include "networkd-lldp-tx.h"
|
||||||
#include "networkd-neighbor.h"
|
#include "networkd-neighbor.h"
|
||||||
#include "networkd-nexthop.h"
|
|
||||||
#include "networkd-radv.h"
|
#include "networkd-radv.h"
|
||||||
#include "networkd-route.h"
|
#include "networkd-route.h"
|
||||||
#include "networkd-routing-policy-rule.h"
|
#include "networkd-routing-policy-rule.h"
|
||||||
|
@ -229,7 +228,6 @@ struct Network {
|
||||||
|
|
||||||
LIST_HEAD(Address, static_addresses);
|
LIST_HEAD(Address, static_addresses);
|
||||||
LIST_HEAD(Route, static_routes);
|
LIST_HEAD(Route, static_routes);
|
||||||
LIST_HEAD(NextHop, static_nexthops);
|
|
||||||
LIST_HEAD(FdbEntry, static_fdb_entries);
|
LIST_HEAD(FdbEntry, static_fdb_entries);
|
||||||
LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
|
LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
|
||||||
LIST_HEAD(Neighbor, neighbors);
|
LIST_HEAD(Neighbor, neighbors);
|
||||||
|
@ -240,7 +238,6 @@ struct Network {
|
||||||
|
|
||||||
unsigned n_static_addresses;
|
unsigned n_static_addresses;
|
||||||
unsigned n_static_routes;
|
unsigned n_static_routes;
|
||||||
unsigned n_static_nexthops;
|
|
||||||
unsigned n_static_fdb_entries;
|
unsigned n_static_fdb_entries;
|
||||||
unsigned n_ipv6_proxy_ndp_addresses;
|
unsigned n_ipv6_proxy_ndp_addresses;
|
||||||
unsigned n_neighbors;
|
unsigned n_neighbors;
|
||||||
|
@ -251,7 +248,6 @@ struct Network {
|
||||||
|
|
||||||
Hashmap *addresses_by_section;
|
Hashmap *addresses_by_section;
|
||||||
Hashmap *routes_by_section;
|
Hashmap *routes_by_section;
|
||||||
Hashmap *nexthops_by_section;
|
|
||||||
Hashmap *fdb_entries_by_section;
|
Hashmap *fdb_entries_by_section;
|
||||||
Hashmap *neighbors_by_section;
|
Hashmap *neighbors_by_section;
|
||||||
Hashmap *address_labels_by_section;
|
Hashmap *address_labels_by_section;
|
||||||
|
|
|
@ -1,473 +0,0 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+
|
|
||||||
* Copyright © 2019 VMware, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/nexthop.h>
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
|
||||||
#include "conf-parser.h"
|
|
||||||
#include "in-addr-util.h"
|
|
||||||
#include "netlink-util.h"
|
|
||||||
#include "networkd-manager.h"
|
|
||||||
#include "networkd-nexthop.h"
|
|
||||||
#include "parse-util.h"
|
|
||||||
#include "set.h"
|
|
||||||
#include "string-util.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
int nexthop_new(NextHop **ret) {
|
|
||||||
_cleanup_(nexthop_freep) NextHop *nexthop = NULL;
|
|
||||||
|
|
||||||
nexthop = new(NextHop, 1);
|
|
||||||
if (!nexthop)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*nexthop = (NextHop) {
|
|
||||||
.family = AF_UNSPEC,
|
|
||||||
};
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(nexthop);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nexthop_new_static(Network *network, const char *filename, unsigned section_line, NextHop **ret) {
|
|
||||||
_cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
|
|
||||||
_cleanup_(nexthop_freep) NextHop *nexthop = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(network);
|
|
||||||
assert(ret);
|
|
||||||
assert(!!filename == (section_line > 0));
|
|
||||||
|
|
||||||
if (filename) {
|
|
||||||
r = network_config_section_new(filename, section_line, &n);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
nexthop = hashmap_get(network->nexthops_by_section, n);
|
|
||||||
if (nexthop) {
|
|
||||||
*ret = TAKE_PTR(nexthop);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = nexthop_new(&nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
nexthop->protocol = RTPROT_STATIC;
|
|
||||||
nexthop->network = network;
|
|
||||||
LIST_PREPEND(nexthops, network->static_nexthops, nexthop);
|
|
||||||
network->n_static_nexthops++;
|
|
||||||
|
|
||||||
if (filename) {
|
|
||||||
nexthop->section = TAKE_PTR(n);
|
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&network->nexthops_by_section, &network_config_hash_ops);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = hashmap_put(network->nexthops_by_section, nexthop->section, nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(nexthop);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nexthop_free(NextHop *nexthop) {
|
|
||||||
if (!nexthop)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (nexthop->network) {
|
|
||||||
LIST_REMOVE(nexthops, nexthop->network->static_nexthops, nexthop);
|
|
||||||
|
|
||||||
assert(nexthop->network->n_static_nexthops > 0);
|
|
||||||
nexthop->network->n_static_nexthops--;
|
|
||||||
|
|
||||||
if (nexthop->section)
|
|
||||||
hashmap_remove(nexthop->network->nexthops_by_section, nexthop->section);
|
|
||||||
}
|
|
||||||
|
|
||||||
network_config_section_free(nexthop->section);
|
|
||||||
|
|
||||||
if (nexthop->link) {
|
|
||||||
set_remove(nexthop->link->nexthops, nexthop);
|
|
||||||
set_remove(nexthop->link->nexthops_foreign, nexthop);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(nexthop);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
|
|
||||||
assert(nexthop);
|
|
||||||
|
|
||||||
siphash24_compress(&nexthop->id, sizeof(nexthop->id), state);
|
|
||||||
siphash24_compress(&nexthop->oif, sizeof(nexthop->oif), state);
|
|
||||||
siphash24_compress(&nexthop->family, sizeof(nexthop->family), state);
|
|
||||||
|
|
||||||
switch (nexthop->family) {
|
|
||||||
case AF_INET:
|
|
||||||
case AF_INET6:
|
|
||||||
siphash24_compress(&nexthop->gw, FAMILY_ADDRESS_SIZE(nexthop->family), state);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* treat any other address family as AF_UNSPEC */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nexthop_compare_func(const NextHop *a, const NextHop *b) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = CMP(a->id, b->id);
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = CMP(a->oif, b->oif);
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = CMP(a->family, b->family);
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
switch (a->family) {
|
|
||||||
case AF_INET:
|
|
||||||
case AF_INET6:
|
|
||||||
|
|
||||||
r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family));
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
/* treat any other address family as AF_UNSPEC */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|
||||||
nexthop_hash_ops,
|
|
||||||
NextHop,
|
|
||||||
nexthop_hash_func,
|
|
||||||
nexthop_compare_func,
|
|
||||||
nexthop_free);
|
|
||||||
|
|
||||||
bool nexthop_equal(NextHop *r1, NextHop *r2) {
|
|
||||||
if (r1 == r2)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!r1 || !r2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return nexthop_compare_func(r1, r2) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nexthop_get(Link *link, NextHop *in, NextHop **ret) {
|
|
||||||
NextHop *existing;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(in);
|
|
||||||
|
|
||||||
existing = set_get(link->nexthops, in);
|
|
||||||
if (existing) {
|
|
||||||
if (ret)
|
|
||||||
*ret = existing;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
existing = set_get(link->nexthops_foreign, in);
|
|
||||||
if (existing) {
|
|
||||||
if (ret)
|
|
||||||
*ret = existing;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nexthop_add_internal(Link *link, Set **nexthops, NextHop *in, NextHop **ret) {
|
|
||||||
_cleanup_(nexthop_freep) NextHop *nexthop = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(nexthops);
|
|
||||||
assert(in);
|
|
||||||
|
|
||||||
r = nexthop_new(&nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
nexthop->id = in->id;
|
|
||||||
nexthop->oif = in->oif;
|
|
||||||
nexthop->family = in->family;
|
|
||||||
nexthop->gw = in->gw;
|
|
||||||
|
|
||||||
r = set_ensure_allocated(nexthops, &nexthop_hash_ops);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = set_put(*nexthops, nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
if (r == 0)
|
|
||||||
return -EEXIST;
|
|
||||||
|
|
||||||
nexthop->link = link;
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = nexthop;
|
|
||||||
|
|
||||||
nexthop = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nexthop_add_foreign(Link *link, NextHop *in, NextHop **ret) {
|
|
||||||
return nexthop_add_internal(link, &link->nexthops_foreign, in, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int nexthop_add(Link *link, NextHop *in, NextHop **ret) {
|
|
||||||
NextHop *nexthop;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = nexthop_get(link, in, &nexthop);
|
|
||||||
if (r == -ENOENT) {
|
|
||||||
/* NextHop does not exist, create a new one */
|
|
||||||
r = nexthop_add_internal(link, &link->nexthops, in, &nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
} else if (r == 0) {
|
|
||||||
/* Take over a foreign nexthop */
|
|
||||||
r = set_ensure_allocated(&link->nexthops, &nexthop_hash_ops);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = set_put(link->nexthops, nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
set_remove(link->nexthops_foreign, nexthop);
|
|
||||||
} else if (r == 1) {
|
|
||||||
/* NextHop exists, do nothing */
|
|
||||||
;
|
|
||||||
} else
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = nexthop;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(m);
|
|
||||||
assert(link);
|
|
||||||
assert(link->ifname);
|
|
||||||
|
|
||||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
|
||||||
if (r < 0 && r != -ESRCH)
|
|
||||||
log_link_warning_errno(link, r, "Could not drop nexthop: %m");
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nexthop_remove(NextHop *nexthop, Link *link,
|
|
||||||
link_netlink_message_handler_t callback) {
|
|
||||||
|
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(link->manager);
|
|
||||||
assert(link->manager->rtnl);
|
|
||||||
assert(link->ifindex > 0);
|
|
||||||
assert(IN_SET(nexthop->family, AF_INET, AF_INET6));
|
|
||||||
|
|
||||||
r = sd_rtnl_message_new_nexthop(link->manager->rtnl, &req,
|
|
||||||
RTM_DELNEXTHOP, nexthop->family,
|
|
||||||
nexthop->protocol);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not create RTM_DELNEXTHOP message: %m");
|
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
|
||||||
_cleanup_free_ char *gw = NULL;
|
|
||||||
|
|
||||||
if (!in_addr_is_null(nexthop->family, &nexthop->gw))
|
|
||||||
(void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
|
|
||||||
|
|
||||||
log_link_debug(link, "Removing nexthop: gw: %s", strna(gw));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_addr_is_null(nexthop->family, &nexthop->gw) == 0) {
|
|
||||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, nexthop->family, &nexthop->gw);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not append RTA_GATEWAY attribute: %m");
|
|
||||||
}
|
|
||||||
|
|
||||||
r = netlink_call_async(link->manager->rtnl, NULL, req,
|
|
||||||
callback ?: nexthop_remove_handler,
|
|
||||||
link_netlink_destroy_callback, link);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
|
||||||
|
|
||||||
link_ref(link);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nexthop_configure(
|
|
||||||
NextHop *nexthop,
|
|
||||||
Link *link,
|
|
||||||
link_netlink_message_handler_t callback) {
|
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(link);
|
|
||||||
assert(link->manager);
|
|
||||||
assert(link->manager->rtnl);
|
|
||||||
assert(link->ifindex > 0);
|
|
||||||
assert(IN_SET(nexthop->family, AF_INET, AF_INET6));
|
|
||||||
assert(callback);
|
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
|
||||||
_cleanup_free_ char *gw = NULL;
|
|
||||||
|
|
||||||
if (!in_addr_is_null(nexthop->family, &nexthop->gw))
|
|
||||||
(void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
|
|
||||||
|
|
||||||
log_link_debug(link, "Configuring nexthop: gw: %s", strna(gw));
|
|
||||||
}
|
|
||||||
|
|
||||||
r = sd_rtnl_message_new_nexthop(link->manager->rtnl, &req,
|
|
||||||
RTM_NEWNEXTHOP, nexthop->family,
|
|
||||||
nexthop->protocol);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not create RTM_NEWNEXTHOP message: %m");
|
|
||||||
|
|
||||||
r = sd_netlink_message_append_u32(req, NHA_ID, nexthop->id);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not append NHA_ID attribute: %m");
|
|
||||||
|
|
||||||
r = sd_netlink_message_append_u32(req, NHA_OIF, link->ifindex);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m");
|
|
||||||
|
|
||||||
if (in_addr_is_null(nexthop->family, &nexthop->gw) == 0) {
|
|
||||||
r = netlink_message_append_in_addr_union(req, NHA_GATEWAY, nexthop->family, &nexthop->gw);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m");
|
|
||||||
|
|
||||||
r = sd_rtnl_message_nexthop_set_family(req, nexthop->family);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not set nexthop family: %m");
|
|
||||||
}
|
|
||||||
|
|
||||||
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
|
||||||
link_netlink_destroy_callback, link);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
|
||||||
|
|
||||||
link_ref(link);
|
|
||||||
|
|
||||||
r = nexthop_add(link, nexthop, &nexthop);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not add nexthop: %m");
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nexthop_section_verify(NextHop *nh) {
|
|
||||||
if (section_is_invalid(nh->section))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (in_addr_is_null(nh->family, &nh->gw) < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int config_parse_nexthop_id(
|
|
||||||
const char *unit,
|
|
||||||
const char *filename,
|
|
||||||
unsigned line,
|
|
||||||
const char *section,
|
|
||||||
unsigned section_line,
|
|
||||||
const char *lvalue,
|
|
||||||
int ltype,
|
|
||||||
const char *rvalue,
|
|
||||||
void *data,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
_cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
|
|
||||||
Network *network = userdata;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(filename);
|
|
||||||
assert(section);
|
|
||||||
assert(lvalue);
|
|
||||||
assert(rvalue);
|
|
||||||
assert(data);
|
|
||||||
|
|
||||||
r = nexthop_new_static(network, filename, section_line, &n);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = safe_atou32(rvalue, &n->id);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Could not parse nexthop id \"%s\", ignoring assignment: %m", rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAKE_PTR(n);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int config_parse_nexthop_gateway(
|
|
||||||
const char *unit,
|
|
||||||
const char *filename,
|
|
||||||
unsigned line,
|
|
||||||
const char *section,
|
|
||||||
unsigned section_line,
|
|
||||||
const char *lvalue,
|
|
||||||
int ltype,
|
|
||||||
const char *rvalue,
|
|
||||||
void *data,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
_cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
|
|
||||||
Network *network = userdata;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(filename);
|
|
||||||
assert(section);
|
|
||||||
assert(lvalue);
|
|
||||||
assert(rvalue);
|
|
||||||
assert(data);
|
|
||||||
|
|
||||||
r = nexthop_new_static(network, filename, section_line, &n);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = in_addr_from_string_auto(rvalue, &n->family, &n->gw);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
|
||||||
"Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAKE_PTR(n);
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+
|
|
||||||
* Copyright © 2019 VMware, Inc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "conf-parser.h"
|
|
||||||
#include "macro.h"
|
|
||||||
|
|
||||||
typedef struct NextHop NextHop;
|
|
||||||
typedef struct NetworkConfigSection NetworkConfigSection;
|
|
||||||
|
|
||||||
#include "networkd-network.h"
|
|
||||||
#include "networkd-util.h"
|
|
||||||
|
|
||||||
struct NextHop {
|
|
||||||
Network *network;
|
|
||||||
NetworkConfigSection *section;
|
|
||||||
|
|
||||||
Link *link;
|
|
||||||
|
|
||||||
unsigned char protocol;
|
|
||||||
|
|
||||||
int family;
|
|
||||||
uint32_t oif;
|
|
||||||
uint32_t id;
|
|
||||||
|
|
||||||
union in_addr_union gw;
|
|
||||||
|
|
||||||
LIST_FIELDS(NextHop, nexthops);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct hash_ops nexthop_hash_ops;
|
|
||||||
|
|
||||||
int nexthop_new(NextHop **ret);
|
|
||||||
void nexthop_free(NextHop *nexthop);
|
|
||||||
int nexthop_configure(NextHop *nexthop, Link *link, link_netlink_message_handler_t callback);
|
|
||||||
int nexthop_remove(NextHop *nexthop, Link *link, link_netlink_message_handler_t callback);
|
|
||||||
|
|
||||||
int nexthop_get(Link *link, NextHop *in, NextHop **ret);
|
|
||||||
int nexthop_add(Link *link, NextHop *in, NextHop **ret);
|
|
||||||
int nexthop_add_foreign(Link *link, NextHop *in, NextHop **ret);
|
|
||||||
bool nexthop_equal(NextHop *r1, NextHop *r2);
|
|
||||||
|
|
||||||
int nexthop_section_verify(NextHop *nexthop);
|
|
||||||
|
|
||||||
DEFINE_NETWORK_SECTION_FUNCTIONS(NextHop, nexthop_free);
|
|
||||||
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_id);
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_gateway);
|
|
|
@ -107,10 +107,6 @@ static int run(int argc, char *argv[]) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not enumerate rules: %m");
|
return log_error_errno(r, "Could not enumerate rules: %m");
|
||||||
|
|
||||||
r = manager_rtnl_enumerate_nexthop(m);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Could not enumerate nexthop: %m");
|
|
||||||
|
|
||||||
r = manager_start(m);
|
r = manager_start(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Could not start manager: %m");
|
return log_error_errno(r, "Could not start manager: %m");
|
||||||
|
|
|
@ -419,17 +419,21 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (STR_IN_SET(field, "DevicePolicy", "Slice"))
|
if (STR_IN_SET(field, "DevicePolicy", "Slice"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting",
|
"CPUAccounting", "MemoryAccounting", "IOAccounting", "BlockIOAccounting",
|
||||||
"TasksAccounting", "IPAccounting"))
|
"TasksAccounting", "IPAccounting"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight"))
|
if (STR_IN_SET(field, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight"))
|
||||||
|
|
||||||
return bus_append_cg_weight_parse(m, field, eq);
|
return bus_append_cg_weight_parse(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "CPUShares", "StartupCPUShares"))
|
if (STR_IN_SET(field, "CPUShares", "StartupCPUShares"))
|
||||||
|
|
||||||
return bus_append_cg_cpu_shares_parse(m, field, eq);
|
return bus_append_cg_cpu_shares_parse(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "AllowedCPUs", "AllowedMemoryNodes")) {
|
if (STR_IN_SET(field, "AllowedCPUs", "AllowedMemoryNodes")) {
|
||||||
|
@ -449,12 +453,15 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight"))
|
if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight"))
|
||||||
|
|
||||||
return bus_append_cg_blkio_weight_parse(m, field, eq);
|
return bus_append_cg_blkio_weight_parse(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "DisableControllers"))
|
if (streq(field, "DisableControllers"))
|
||||||
|
|
||||||
return bus_append_strv(m, "DisableControllers", eq, EXTRACT_UNQUOTE);
|
return bus_append_strv(m, "DisableControllers", eq, EXTRACT_UNQUOTE);
|
||||||
|
|
||||||
if (streq(field, "Delegate")) {
|
if (streq(field, "Delegate")) {
|
||||||
|
|
||||||
r = parse_boolean(eq);
|
r = parse_boolean(eq);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_append_strv(m, "DelegateControllers", eq, EXTRACT_UNQUOTE);
|
return bus_append_strv(m, "DelegateControllers", eq, EXTRACT_UNQUOTE);
|
||||||
|
@ -466,15 +473,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STR_IN_SET(field, "MemoryMin",
|
if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) {
|
||||||
"DefaultMemoryLow",
|
|
||||||
"DefaultMemoryMin",
|
|
||||||
"MemoryLow",
|
|
||||||
"MemoryHigh",
|
|
||||||
"MemoryMax",
|
|
||||||
"MemorySwapMax",
|
|
||||||
"MemoryLimit",
|
|
||||||
"TasksMax")) {
|
|
||||||
|
|
||||||
if (isempty(eq) || streq(eq, "infinity")) {
|
if (isempty(eq) || streq(eq, "infinity")) {
|
||||||
r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX);
|
r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX);
|
||||||
|
@ -506,6 +505,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(field, "CPUQuota")) {
|
if (streq(field, "CPUQuota")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
|
r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
|
||||||
else {
|
else {
|
||||||
|
@ -540,6 +540,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(field, "DeviceAllow")) {
|
if (streq(field, "DeviceAllow")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 0);
|
r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 0);
|
||||||
else {
|
else {
|
||||||
|
@ -561,6 +562,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
|
if (cgroup_io_limit_type_from_string(field) >= 0 || STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0);
|
r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0);
|
||||||
else {
|
else {
|
||||||
|
@ -594,6 +596,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) {
|
if (STR_IN_SET(field, "IODeviceWeight", "BlockIODeviceWeight")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0);
|
r = sd_bus_message_append(m, "(sv)", field, "a(st)", 0);
|
||||||
else {
|
else {
|
||||||
|
@ -789,13 +792,17 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bus_append_automount_property(sd_bus_message *m, const char *field, const char *eq) {
|
static int bus_append_automount_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||||
|
|
||||||
if (streq(field, "Where"))
|
if (streq(field, "Where"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "DirectoryMode"))
|
if (streq(field, "DirectoryMode"))
|
||||||
|
|
||||||
return bus_append_parse_mode(m, field, eq);
|
return bus_append_parse_mode(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "TimeoutIdleSec"))
|
if (streq(field, "TimeoutIdleSec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -811,6 +818,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
"WorkingDirectory", "RootDirectory", "SyslogIdentifier",
|
"WorkingDirectory", "RootDirectory", "SyslogIdentifier",
|
||||||
"ProtectSystem", "ProtectHome", "SELinuxContext", "RootImage",
|
"ProtectSystem", "ProtectHome", "SELinuxContext", "RootImage",
|
||||||
"RuntimeDirectoryPreserve", "Personality", "KeyringMode", "NetworkNamespacePath"))
|
"RuntimeDirectoryPreserve", "Personality", "KeyringMode", "NetworkNamespacePath"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
|
@ -820,6 +828,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
"DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules",
|
"DynamicUser", "RemoveIPC", "ProtectKernelTunables", "ProtectKernelModules",
|
||||||
"ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality",
|
"ProtectControlGroups", "MountAPIVFS", "CPUSchedulingResetOnFork", "LockPersonality",
|
||||||
"ProtectHostname", "RestrictSUIDSGID"))
|
"ProtectHostname", "RestrictSUIDSGID"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
|
@ -827,56 +836,73 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
"ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths",
|
"ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths",
|
||||||
"RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory",
|
"RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory",
|
||||||
"SupplementaryGroups", "SystemCallArchitectures"))
|
"SupplementaryGroups", "SystemCallArchitectures"))
|
||||||
|
|
||||||
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "SyslogLevel", "LogLevelMax"))
|
if (STR_IN_SET(field, "SyslogLevel", "LogLevelMax"))
|
||||||
|
|
||||||
return bus_append_log_level_from_string(m, field, eq);
|
return bus_append_log_level_from_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "SyslogFacility"))
|
if (streq(field, "SyslogFacility"))
|
||||||
|
|
||||||
return bus_append_log_facility_unshifted_from_string(m, field, eq);
|
return bus_append_log_facility_unshifted_from_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "SecureBits"))
|
if (streq(field, "SecureBits"))
|
||||||
|
|
||||||
return bus_append_secure_bits_from_string(m, field, eq);
|
return bus_append_secure_bits_from_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "CPUSchedulingPolicy"))
|
if (streq(field, "CPUSchedulingPolicy"))
|
||||||
|
|
||||||
return bus_append_sched_policy_from_string(m, field, eq);
|
return bus_append_sched_policy_from_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "CPUSchedulingPriority", "OOMScoreAdjust"))
|
if (STR_IN_SET(field, "CPUSchedulingPriority", "OOMScoreAdjust"))
|
||||||
|
|
||||||
return bus_append_safe_atoi(m, field, eq);
|
return bus_append_safe_atoi(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "Nice"))
|
if (streq(field, "Nice"))
|
||||||
|
|
||||||
return bus_append_parse_nice(m, field, eq);
|
return bus_append_parse_nice(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "SystemCallErrorNumber"))
|
if (streq(field, "SystemCallErrorNumber"))
|
||||||
|
|
||||||
return bus_append_parse_errno(m, field, eq);
|
return bus_append_parse_errno(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "IOSchedulingClass"))
|
if (streq(field, "IOSchedulingClass"))
|
||||||
|
|
||||||
return bus_append_ioprio_class_from_string(m, field, eq);
|
return bus_append_ioprio_class_from_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "IOSchedulingPriority"))
|
if (streq(field, "IOSchedulingPriority"))
|
||||||
|
|
||||||
return bus_append_ioprio_parse_priority(m, field, eq);
|
return bus_append_ioprio_parse_priority(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode",
|
"RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode",
|
||||||
"LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask"))
|
"LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask"))
|
||||||
|
|
||||||
return bus_append_parse_mode(m, field, eq);
|
return bus_append_parse_mode(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "TimerSlackNSec"))
|
if (streq(field, "TimerSlackNSec"))
|
||||||
|
|
||||||
return bus_append_parse_nsec(m, field, eq);
|
return bus_append_parse_nsec(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "LogRateLimitIntervalSec"))
|
if (streq(field, "LogRateLimitIntervalSec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "LogRateLimitBurst"))
|
if (streq(field, "LogRateLimitBurst"))
|
||||||
|
|
||||||
return bus_append_safe_atou(m, field, eq);
|
return bus_append_safe_atou(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "MountFlags"))
|
if (streq(field, "MountFlags"))
|
||||||
|
|
||||||
return bus_append_mount_propagation_flags_from_string(m, field, eq);
|
return bus_append_mount_propagation_flags_from_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "Environment", "UnsetEnvironment", "PassEnvironment"))
|
if (STR_IN_SET(field, "Environment", "UnsetEnvironment", "PassEnvironment"))
|
||||||
|
|
||||||
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE);
|
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE);
|
||||||
|
|
||||||
if (streq(field, "EnvironmentFile")) {
|
if (streq(field, "EnvironmentFile")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", "EnvironmentFiles", "a(sb)", 0);
|
r = sd_bus_message_append(m, "(sv)", "EnvironmentFiles", "a(sb)", 0);
|
||||||
else
|
else
|
||||||
|
@ -890,6 +916,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(field, "LogExtraFields")) {
|
if (streq(field, "LogExtraFields")) {
|
||||||
|
|
||||||
r = sd_bus_message_open_container(m, 'r', "sv");
|
r = sd_bus_message_open_container(m, 'r', "sv");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
@ -1327,6 +1354,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bus_append_kill_property(sd_bus_message *m, const char *field, const char *eq) {
|
static int bus_append_kill_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||||
|
|
||||||
if (streq(field, "KillMode"))
|
if (streq(field, "KillMode"))
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
|
@ -1342,15 +1370,19 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
|
||||||
static int bus_append_mount_property(sd_bus_message *m, const char *field, const char *eq) {
|
static int bus_append_mount_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||||
|
|
||||||
if (STR_IN_SET(field, "What", "Where", "Options", "Type"))
|
if (STR_IN_SET(field, "What", "Where", "Options", "Type"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "TimeoutSec"))
|
if (streq(field, "TimeoutSec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "DirectoryMode"))
|
if (streq(field, "DirectoryMode"))
|
||||||
|
|
||||||
return bus_append_parse_mode(m, field, eq);
|
return bus_append_parse_mode(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "SloppyOptions", "LazyUnmount", "ForceUnmount"))
|
if (STR_IN_SET(field, "SloppyOptions", "LazyUnmount", "ForceUnmount"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1360,14 +1392,17 @@ static int bus_append_path_property(sd_bus_message *m, const char *field, const
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (streq(field, "MakeDirectory"))
|
if (streq(field, "MakeDirectory"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "DirectoryMode"))
|
if (streq(field, "DirectoryMode"))
|
||||||
|
|
||||||
return bus_append_parse_mode(m, field, eq);
|
return bus_append_parse_mode(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"PathExists", "PathExistsGlob", "PathChanged",
|
"PathExists", "PathExistsGlob", "PathChanged",
|
||||||
"PathModified", "DirectoryNotEmpty")) {
|
"PathModified", "DirectoryNotEmpty")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 0);
|
r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 0);
|
||||||
else
|
else
|
||||||
|
@ -1387,15 +1422,19 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"PIDFile", "Type", "Restart", "BusName", "NotifyAccess",
|
"PIDFile", "Type", "Restart", "BusName", "NotifyAccess",
|
||||||
"USBFunctionDescriptors", "USBFunctionStrings", "OOMPolicy"))
|
"USBFunctionDescriptors", "USBFunctionStrings", "OOMPolicy"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "PermissionsStartOnly", "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID"))
|
if (STR_IN_SET(field, "PermissionsStartOnly", "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "RestartSec", "TimeoutStartSec", "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec"))
|
if (STR_IN_SET(field, "RestartSec", "TimeoutStartSec", "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "TimeoutSec")) {
|
if (streq(field, "TimeoutSec")) {
|
||||||
|
|
||||||
r = bus_append_parse_sec_rename(m, "TimeoutStartSec", eq);
|
r = bus_append_parse_sec_rename(m, "TimeoutStartSec", eq);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1404,6 +1443,7 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(field, "FileDescriptorStoreMax"))
|
if (streq(field, "FileDescriptorStoreMax"))
|
||||||
|
|
||||||
return bus_append_safe_atou(m, field, eq);
|
return bus_append_safe_atou(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
|
@ -1503,47 +1543,60 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast",
|
"Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast",
|
||||||
"PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet"))
|
"PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "Priority", "IPTTL", "Mark"))
|
if (STR_IN_SET(field, "Priority", "IPTTL", "Mark"))
|
||||||
|
|
||||||
return bus_append_safe_atoi(m, field, eq);
|
return bus_append_safe_atoi(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "IPTOS"))
|
if (streq(field, "IPTOS"))
|
||||||
|
|
||||||
return bus_append_ip_tos_from_string(m, field, eq);
|
return bus_append_ip_tos_from_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "Backlog", "MaxConnections", "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst"))
|
if (STR_IN_SET(field, "Backlog", "MaxConnections", "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst"))
|
||||||
|
|
||||||
return bus_append_safe_atou(m, field, eq);
|
return bus_append_safe_atou(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "SocketMode", "DirectoryMode"))
|
if (STR_IN_SET(field, "SocketMode", "DirectoryMode"))
|
||||||
|
|
||||||
return bus_append_parse_mode(m, field, eq);
|
return bus_append_parse_mode(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "MessageQueueMaxMessages", "MessageQueueMessageSize"))
|
if (STR_IN_SET(field, "MessageQueueMaxMessages", "MessageQueueMessageSize"))
|
||||||
|
|
||||||
return bus_append_safe_atoi64(m, field, eq);
|
return bus_append_safe_atoi64(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "TimeoutSec", "KeepAliveTimeSec", "KeepAliveIntervalSec", "DeferAcceptSec", "TriggerLimitIntervalSec"))
|
if (STR_IN_SET(field, "TimeoutSec", "KeepAliveTimeSec", "KeepAliveIntervalSec", "DeferAcceptSec", "TriggerLimitIntervalSec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "ReceiveBuffer", "SendBuffer", "PipeSize"))
|
if (STR_IN_SET(field, "ReceiveBuffer", "SendBuffer", "PipeSize"))
|
||||||
|
|
||||||
return bus_append_parse_size(m, field, eq, 1024);
|
return bus_append_parse_size(m, field, eq, 1024);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "ExecStartPre", "ExecStartPost", "ExecReload", "ExecStopPost"))
|
if (STR_IN_SET(field, "ExecStartPre", "ExecStartPost", "ExecReload", "ExecStopPost"))
|
||||||
|
|
||||||
return bus_append_exec_command(m, field, eq);
|
return bus_append_exec_command(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"SmackLabel", "SmackLabelIPIn", "SmackLabelIPOut", "TCPCongestion",
|
"SmackLabel", "SmackLabelIPIn", "SmackLabelIPOut", "TCPCongestion",
|
||||||
"BindToDevice", "BindIPv6Only", "FileDescriptorName",
|
"BindToDevice", "BindIPv6Only", "FileDescriptorName",
|
||||||
"SocketUser", "SocketGroup"))
|
"SocketUser", "SocketGroup"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "Symlinks"))
|
if (streq(field, "Symlinks"))
|
||||||
|
|
||||||
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
||||||
|
|
||||||
if (streq(field, "SocketProtocol"))
|
if (streq(field, "SocketProtocol"))
|
||||||
|
|
||||||
return bus_append_parse_ip_protocol(m, field, eq);
|
return bus_append_parse_ip_protocol(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",
|
"ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",
|
||||||
"ListenSpecial", "ListenMessageQueue", "ListenFIFO", "ListenUSBFunction")) {
|
"ListenSpecial", "ListenMessageQueue", "ListenFIFO", "ListenUSBFunction")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 0);
|
r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 0);
|
||||||
else
|
else
|
||||||
|
@ -1561,14 +1614,17 @@ static int bus_append_timer_property(sd_bus_message *m, const char *field, const
|
||||||
|
|
||||||
if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent",
|
if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent",
|
||||||
"OnTimezoneChange", "OnClockChange"))
|
"OnTimezoneChange", "OnClockChange"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec"))
|
if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"OnActiveSec", "OnBootSec", "OnStartupSec",
|
"OnActiveSec", "OnBootSec", "OnStartupSec",
|
||||||
"OnUnitActiveSec","OnUnitInactiveSec")) {
|
"OnUnitActiveSec","OnUnitInactiveSec")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 0);
|
r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 0);
|
||||||
else {
|
else {
|
||||||
|
@ -1586,6 +1642,7 @@ static int bus_append_timer_property(sd_bus_message *m, const char *field, const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq(field, "OnCalendar")) {
|
if (streq(field, "OnCalendar")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 0);
|
r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 0);
|
||||||
else
|
else
|
||||||
|
@ -1609,20 +1666,25 @@ static int bus_append_unit_property(sd_bus_message *m, const char *field, const
|
||||||
"JobTimeoutAction", "JobTimeoutRebootArgument",
|
"JobTimeoutAction", "JobTimeoutRebootArgument",
|
||||||
"StartLimitAction", "FailureAction", "SuccessAction",
|
"StartLimitAction", "FailureAction", "SuccessAction",
|
||||||
"RebootArgument", "CollectMode"))
|
"RebootArgument", "CollectMode"))
|
||||||
|
|
||||||
return bus_append_string(m, field, eq);
|
return bus_append_string(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field,
|
if (STR_IN_SET(field,
|
||||||
"StopWhenUnneeded", "RefuseManualStart", "RefuseManualStop",
|
"StopWhenUnneeded", "RefuseManualStart", "RefuseManualStop",
|
||||||
"AllowIsolate", "IgnoreOnIsolate", "DefaultDependencies"))
|
"AllowIsolate", "IgnoreOnIsolate", "DefaultDependencies"))
|
||||||
|
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "JobTimeoutSec", "JobRunningTimeoutSec", "StartLimitIntervalSec"))
|
if (STR_IN_SET(field, "JobTimeoutSec", "JobRunningTimeoutSec", "StartLimitIntervalSec"))
|
||||||
|
|
||||||
return bus_append_parse_sec_rename(m, field, eq);
|
return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
|
||||||
if (streq(field, "StartLimitBurst"))
|
if (streq(field, "StartLimitBurst"))
|
||||||
|
|
||||||
return bus_append_safe_atou(m, field, eq);
|
return bus_append_safe_atou(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "SuccessActionExitStatus", "FailureActionExitStatus")) {
|
if (STR_IN_SET(field, "SuccessActionExitStatus", "FailureActionExitStatus")) {
|
||||||
|
|
||||||
if (isempty(eq))
|
if (isempty(eq))
|
||||||
r = sd_bus_message_append(m, "(sv)", field, "i", -1);
|
r = sd_bus_message_append(m, "(sv)", field, "i", -1);
|
||||||
else {
|
else {
|
||||||
|
@ -1642,6 +1704,7 @@ static int bus_append_unit_property(sd_bus_message *m, const char *field, const
|
||||||
|
|
||||||
if (unit_dependency_from_string(field) >= 0 ||
|
if (unit_dependency_from_string(field) >= 0 ||
|
||||||
STR_IN_SET(field, "Documentation", "RequiresMountsFor"))
|
STR_IN_SET(field, "Documentation", "RequiresMountsFor"))
|
||||||
|
|
||||||
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
return bus_append_strv(m, field, eq, EXTRACT_UNQUOTE);
|
||||||
|
|
||||||
t = condition_type_from_string(field);
|
t = condition_type_from_string(field);
|
||||||
|
|
|
@ -7977,7 +7977,7 @@ static void help_states(void) {
|
||||||
|
|
||||||
static int help_boot_loader_entry(void) {
|
static int help_boot_loader_entry(void) {
|
||||||
_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_strv_free_ char **l = NULL;
|
_cleanup_free_ char **l = NULL;
|
||||||
sd_bus *bus;
|
sd_bus *bus;
|
||||||
char **i;
|
char **i;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -167,12 +167,6 @@ int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char
|
||||||
int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len);
|
int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len);
|
||||||
int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type);
|
int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type);
|
||||||
|
|
||||||
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nhmsg_type, int nh_family, unsigned char nh_protocol);
|
|
||||||
|
|
||||||
int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags);
|
|
||||||
int sd_rtnl_message_nexthop_set_family(sd_netlink_message *m, uint8_t family);
|
|
||||||
int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family);
|
|
||||||
|
|
||||||
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags);
|
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags);
|
||||||
int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state);
|
int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state);
|
||||||
int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family);
|
int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family);
|
||||||
|
|
|
@ -425,10 +425,9 @@ int main(int argc, char *argv[]) {
|
||||||
export = 1;
|
export = 1;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
printf("Usage: %s [--export] [--help] <device>\n"
|
printf("Usage: ata_id [--export] [--help] <device>\n"
|
||||||
" -x,--export print values as environment keys\n"
|
" -x,--export print values as environment keys\n"
|
||||||
" -h,--help print this help text\n\n",
|
" -h,--help print this help text\n\n");
|
||||||
program_invocation_short_name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -849,13 +849,12 @@ int main(int argc, char *argv[]) {
|
||||||
log_open();
|
log_open();
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
printf("Usage: %s [options] <device>\n"
|
printf("Usage: cdrom_id [options] <device>\n"
|
||||||
" -l,--lock-media lock the media (to enable eject request events)\n"
|
" -l,--lock-media lock the media (to enable eject request events)\n"
|
||||||
" -u,--unlock-media unlock the media\n"
|
" -u,--unlock-media unlock the media\n"
|
||||||
" -e,--eject-media eject the media\n"
|
" -e,--eject-media eject the media\n"
|
||||||
" -d,--debug debug to stderr\n"
|
" -d,--debug debug to stderr\n"
|
||||||
" -h,--help print this help text\n\n",
|
" -h,--help print this help text\n\n");
|
||||||
program_invocation_short_name);
|
|
||||||
goto exit;
|
goto exit;
|
||||||
default:
|
default:
|
||||||
rc = 1;
|
rc = 1;
|
||||||
|
|
|
@ -44,7 +44,7 @@ static int run(int argc, char **argv) {
|
||||||
log_open();
|
log_open();
|
||||||
|
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Usage: %s [SYSFS_PATH]", program_invocation_short_name);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Usage: hidraw_id [SYSFS_PATH]");
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
r = device_new_from_strv(&device, environ);
|
r = device_new_from_strv(&device, environ);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "architecture.h"
|
|
||||||
#include "conf-files.h"
|
#include "conf-files.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "device-util.h"
|
#include "device-util.h"
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
#include "udev-event.h"
|
#include "udev-event.h"
|
||||||
#include "udev-rules.h"
|
#include "udev-rules.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
#include "virt.h"
|
|
||||||
|
|
||||||
#define RULES_DIRS (const char* const*) CONF_PATHS_STRV("udev/rules.d")
|
#define RULES_DIRS (const char* const*) CONF_PATHS_STRV("udev/rules.d")
|
||||||
|
|
||||||
|
@ -71,7 +69,6 @@ typedef enum {
|
||||||
TK_M_DEVLINK, /* strv, sd_device_get_devlink_first(), sd_device_get_devlink_next() */
|
TK_M_DEVLINK, /* strv, sd_device_get_devlink_first(), sd_device_get_devlink_next() */
|
||||||
TK_M_NAME, /* string, name of network interface */
|
TK_M_NAME, /* string, name of network interface */
|
||||||
TK_M_ENV, /* string, device property, takes key through attribute */
|
TK_M_ENV, /* string, device property, takes key through attribute */
|
||||||
TK_M_CONST, /* string, system-specific hard-coded constant */
|
|
||||||
TK_M_TAG, /* strv, sd_device_get_tag_first(), sd_device_get_tag_next() */
|
TK_M_TAG, /* strv, sd_device_get_tag_first(), sd_device_get_tag_next() */
|
||||||
TK_M_SUBSYSTEM, /* string, sd_device_get_subsystem() */
|
TK_M_SUBSYSTEM, /* string, sd_device_get_subsystem() */
|
||||||
TK_M_DRIVER, /* string, sd_device_get_driver() */
|
TK_M_DRIVER, /* string, sd_device_get_driver() */
|
||||||
|
@ -621,12 +618,6 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp
|
||||||
r = rule_line_add_token(rule_line, TK_A_ENV, op, value, attr);
|
r = rule_line_add_token(rule_line, TK_A_ENV, op, value, attr);
|
||||||
} else
|
} else
|
||||||
r = rule_line_add_token(rule_line, TK_M_ENV, op, value, attr);
|
r = rule_line_add_token(rule_line, TK_M_ENV, op, value, attr);
|
||||||
} else if (streq(key, "CONST")) {
|
|
||||||
if (isempty(attr) || !STR_IN_SET(attr, "arch", "virt"))
|
|
||||||
return log_token_invalid_attr(rules, key);
|
|
||||||
if (!is_match)
|
|
||||||
return log_token_invalid_op(rules, key);
|
|
||||||
r = rule_line_add_token(rule_line, TK_M_CONST, op, value, attr);
|
|
||||||
} else if (streq(key, "TAG")) {
|
} else if (streq(key, "TAG")) {
|
||||||
if (attr)
|
if (attr)
|
||||||
return log_token_invalid_attr(rules, key);
|
return log_token_invalid_attr(rules, key);
|
||||||
|
@ -1583,17 +1574,6 @@ static int udev_rule_apply_token_to_event(
|
||||||
val = hashmap_get(properties_list, token->data);
|
val = hashmap_get(properties_list, token->data);
|
||||||
|
|
||||||
return token_match_string(token, val);
|
return token_match_string(token, val);
|
||||||
case TK_M_CONST: {
|
|
||||||
const char *k = token->data;
|
|
||||||
|
|
||||||
if (streq(k, "arch"))
|
|
||||||
val = architecture_to_string(uname_architecture());
|
|
||||||
else if (streq(k, "virt"))
|
|
||||||
val = virtualization_to_string(detect_virtualization());
|
|
||||||
else
|
|
||||||
assert_not_reached("Invalid CONST key");
|
|
||||||
return token_match_string(token, val);
|
|
||||||
}
|
|
||||||
case TK_M_TAG:
|
case TK_M_TAG:
|
||||||
case TK_M_PARENTS_TAG:
|
case TK_M_PARENTS_TAG:
|
||||||
FOREACH_DEVICE_TAG(dev, val)
|
FOREACH_DEVICE_TAG(dev, val)
|
||||||
|
@ -2345,7 +2325,7 @@ static int apply_static_dev_perms(const char *devnode, uid_t uid, gid_t gid, mod
|
||||||
|
|
||||||
static int udev_rule_line_apply_static_dev_perms(UdevRuleLine *rule_line) {
|
static int udev_rule_line_apply_static_dev_perms(UdevRuleLine *rule_line) {
|
||||||
UdevRuleToken *token;
|
UdevRuleToken *token;
|
||||||
_cleanup_strv_free_ char **tags = NULL;
|
_cleanup_free_ char **tags = NULL;
|
||||||
uid_t uid = UID_INVALID;
|
uid_t uid = UID_INVALID;
|
||||||
gid_t gid = GID_INVALID;
|
gid_t gid = GID_INVALID;
|
||||||
mode_t mode = MODE_INVALID;
|
mode_t mode = MODE_INVALID;
|
||||||
|
|
|
@ -255,6 +255,3 @@ MaxLeaseTimeSec=
|
||||||
DefaultLeaseTimeSec=
|
DefaultLeaseTimeSec=
|
||||||
EmitTimezone=
|
EmitTimezone=
|
||||||
DNS=
|
DNS=
|
||||||
[NextHop]
|
|
||||||
Id=
|
|
||||||
Gateway=
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
[Match]
|
|
||||||
Name=veth99
|
|
||||||
|
|
||||||
[Network]
|
|
||||||
IPv6AcceptRA=no
|
|
||||||
Address=192.168.5.10/24
|
|
||||||
Gateway=192.168.5.1
|
|
||||||
|
|
||||||
[NextHop]
|
|
||||||
Id=1
|
|
||||||
Gateway=192.168.5.1
|
|
|
@ -1,7 +0,0 @@
|
||||||
[Match]
|
|
||||||
Name=veth-peer
|
|
||||||
|
|
||||||
[Network]
|
|
||||||
IPv6AcceptRA=no
|
|
||||||
Address=2600::1/0
|
|
||||||
Address=192.168.5.1/24
|
|
|
@ -113,16 +113,6 @@ def expectedFailureIfLinkFileFieldIsNotSet():
|
||||||
|
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def expectedFailureIfNexthopIsNotAvailable():
|
|
||||||
def f(func):
|
|
||||||
rc = call('ip nexthop list')
|
|
||||||
if rc == 0:
|
|
||||||
return func
|
|
||||||
else:
|
|
||||||
return unittest.expectedFailure(func)
|
|
||||||
|
|
||||||
return f
|
|
||||||
|
|
||||||
def setUpModule():
|
def setUpModule():
|
||||||
global running_units
|
global running_units
|
||||||
|
|
||||||
|
@ -1412,8 +1402,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
'dummy99',
|
'dummy99',
|
||||||
'gretun97',
|
'gretun97',
|
||||||
'ip6gretun97',
|
'ip6gretun97',
|
||||||
'test1',
|
'test1'
|
||||||
'veth99',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
units = [
|
units = [
|
||||||
|
@ -1437,7 +1426,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
'25-neighbor-ipv6.network',
|
'25-neighbor-ipv6.network',
|
||||||
'25-neighbor-ip-dummy.network',
|
'25-neighbor-ip-dummy.network',
|
||||||
'25-neighbor-ip.network',
|
'25-neighbor-ip.network',
|
||||||
'25-nexthop.network',
|
|
||||||
'25-link-local-addressing-no.network',
|
'25-link-local-addressing-no.network',
|
||||||
'25-link-local-addressing-yes.network',
|
'25-link-local-addressing-yes.network',
|
||||||
'25-link-section-unmanaged.network',
|
'25-link-section-unmanaged.network',
|
||||||
|
@ -1447,8 +1435,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
'25-gateway-next-static.network',
|
'25-gateway-next-static.network',
|
||||||
'25-sysctl-disable-ipv6.network',
|
'25-sysctl-disable-ipv6.network',
|
||||||
'25-sysctl.network',
|
'25-sysctl.network',
|
||||||
'25-veth-peer.network',
|
|
||||||
'25-veth.netdev',
|
|
||||||
'26-link-local-addressing-ipv6.network',
|
'26-link-local-addressing-ipv6.network',
|
||||||
'configure-without-carrier.network',
|
'configure-without-carrier.network',
|
||||||
'routing-policy-rule-dummy98.network',
|
'routing-policy-rule-dummy98.network',
|
||||||
|
@ -1988,16 +1974,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
|
self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
|
||||||
self.assertNotRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
|
self.assertNotRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
|
||||||
|
|
||||||
@expectedFailureIfNexthopIsNotAvailable()
|
|
||||||
def test_nexthop(self):
|
|
||||||
copy_unit_to_networkd_unit_path('25-nexthop.network', '25-veth.netdev', '25-veth-peer.network')
|
|
||||||
start_networkd()
|
|
||||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
|
||||||
|
|
||||||
output = check_output('ip nexthop list dev veth99')
|
|
||||||
print(output)
|
|
||||||
self.assertRegex(output, '192.168.5.1')
|
|
||||||
|
|
||||||
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
||||||
links = [
|
links = [
|
||||||
'dummy98',
|
'dummy98',
|
||||||
|
|
Loading…
Reference in New Issue