Compare commits

..

No commits in common. "7d94934b9dd9ceacc18da914ce781272aee6f573" and "349176ae6c095725ddc11599dd03c7f16a5bb099" have entirely different histories.

46 changed files with 330 additions and 1273 deletions

View File

@ -1150,29 +1150,6 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</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> <refsect1>

View File

@ -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>

View File

@ -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

View File

@ -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)
}; };
@ -172,7 +165,7 @@ enum {
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2) #define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2) #define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
/* /*
Generic structure for encapsulation of optional route information. Generic structure for encapsulation of optional route information.
It is reminiscent of sockaddr, but with sa_family replaced It is reminiscent of sockaddr, but with sa_family replaced
with attribute type. with attribute type.
@ -212,7 +205,7 @@ struct rtmsg {
unsigned char rtm_table; /* Routing table id */ unsigned char rtm_table; /* Routing table id */
unsigned char rtm_protocol; /* Routing protocol; see below */ unsigned char rtm_protocol; /* Routing protocol; see below */
unsigned char rtm_scope; /* See below */ unsigned char rtm_scope; /* See below */
unsigned char rtm_type; /* See below */ unsigned char rtm_type; /* See below */
unsigned rtm_flags; unsigned rtm_flags;
@ -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
}; };
@ -523,7 +515,7 @@ struct ifinfomsg {
}; };
/******************************************************************** /********************************************************************
* prefix information * prefix information
****/ ****/
struct prefixmsg { struct prefixmsg {
@ -537,7 +529,7 @@ struct prefixmsg {
unsigned char prefix_pad3; unsigned char prefix_pad3;
}; };
enum enum
{ {
PREFIX_UNSPEC, PREFIX_UNSPEC,
PREFIX_ADDRESS, PREFIX_ADDRESS,
@ -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)

View File

@ -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,24 +201,6 @@ static int automount_set_where(Automount *a) {
return 1; return 1;
} }
static int automount_add_extras(Automount *a) {
int r;
r = automount_set_where(a);
if (r < 0)
return r;
r = automount_add_trigger_dependencies(a);
if (r < 0)
return r;
r = automount_add_mount_dependencies(a);
if (r < 0)
return r;
return automount_add_default_dependencies(a);
}
static int automount_load(Unit *u) { static int automount_load(Unit *u) {
Automount *a = AUTOMOUNT(u); Automount *a = AUTOMOUNT(u);
int r; int r;
@ -225,16 +209,27 @@ static int automount_load(Unit *u) {
assert(u->load_state == UNIT_STUB); assert(u->load_state == UNIT_STUB);
/* Load a .automount file */ /* Load a .automount file */
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; r = automount_set_where(a);
if (r < 0)
return r;
r = automount_add_extras(a); r = automount_add_trigger_dependencies(a);
if (r < 0) if (r < 0)
return r; return r;
r = automount_add_mount_dependencies(a);
if (r < 0)
return r;
r = automount_add_default_dependencies(a);
if (r < 0)
return r;
}
return automount_verify(a); return automount_verify(a);
} }

View File

@ -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

View File

@ -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;

View File

@ -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);
} }

View File

@ -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,20 +333,6 @@ 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) {
int r;
r = path_add_trigger_dependencies(p);
if (r < 0)
return r;
r = path_add_mount_dependencies(p);
if (r < 0)
return r;
return path_add_default_dependencies(p);
}
static int path_load(Unit *u) { static int path_load(Unit *u) {
Path *p = PATH(u); Path *p = PATH(u);
int r; int r;
@ -352,16 +340,24 @@ static int path_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;
r = path_add_extras(p); r = path_add_trigger_dependencies(p);
if (r < 0) if (r < 0)
return r; return r;
r = path_add_mount_dependencies(p);
if (r < 0)
return r;
r = path_add_default_dependencies(p);
if (r < 0)
return r;
}
return path_verify(p); return path_verify(p);
} }

View File

@ -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,17 +176,23 @@ 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);
if (r < 0)
return r;
r = scope_add_extras(s); r = unit_set_default_slice(u);
if (r < 0) if (r < 0)
return r; return r;
r = scope_add_default_dependencies(s);
if (r < 0)
return r;
}
return scope_verify(s); return scope_verify(s);
} }

View File

@ -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 */
r = service_add_extras(s); if (u->load_state == UNIT_LOADED) {
if (r < 0)
return r; /* 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);
if (r < 0)
return r;
}
return service_verify(s); return service_verify(s);
} }

View File

@ -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,25 +170,25 @@ 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 */
r = unit_patch_contexts(u); if (u->load_state == UNIT_LOADED) {
if (r < 0)
return r;
r = slice_add_parent_slice(s); r = unit_patch_contexts(u);
if (r < 0) if (r < 0)
return r; return r;
r = slice_add_default_dependencies(s); r = slice_add_parent_slice(s);
if (r < 0) if (r < 0)
return r; return r;
r = slice_add_default_dependencies(s);
if (r < 0)
return r;
}
return slice_verify(s); return slice_verify(s);
} }

View File

@ -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 */
r = socket_add_extras(s);
/* This is a new unit? Then let's add in some extras */ if (r < 0)
r = socket_add_extras(s); return r;
if (r < 0) }
return r;
return socket_verify(s); return socket_verify(s);
} }

View File

@ -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);
} }

View File

@ -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) {

View File

@ -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,25 +178,24 @@ 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;
r = timer_setup_persistent(t); r = timer_setup_persistent(t);
if (r < 0) if (r < 0)
return r; return r;
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);
} }

View File

@ -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,12 +1371,8 @@ 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
@ -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);
} }
r = UNIT_VTABLE(u)->load(u); if (UNIT_VTABLE(u)->load) {
if (r < 0) r = UNIT_VTABLE(u)->load(u);
goto fail; if (r < 0)
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);

View File

@ -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);

View File

@ -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);

View File

@ -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 = {

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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

View File

@ -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);

View File

@ -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, \

View File

@ -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;

View File

@ -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);

View File

@ -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) {
} }
} }
(void) ndisc_router_process_default(link, rt); if (ndisc_prefix_is_black_listed(link, rt) == 0) {
(void) ndisc_router_process_options(link, rt); (void) ndisc_router_process_default(link, rt);
(void) ndisc_router_process_options(link, rt);
}
return r; return r;
} }

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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");

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
} }
} }

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -255,6 +255,3 @@ MaxLeaseTimeSec=
DefaultLeaseTimeSec= DefaultLeaseTimeSec=
EmitTimezone= EmitTimezone=
DNS= DNS=
[NextHop]
Id=
Gateway=

View File

@ -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

View File

@ -1,7 +0,0 @@
[Match]
Name=veth-peer
[Network]
IPv6AcceptRA=no
Address=2600::1/0
Address=192.168.5.1/24

View File

@ -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',