Compare commits

...

7 Commits

Author SHA1 Message Date
Parks Projets ff6bddd770
Merge edef33b554 into d209e197f8 2024-11-22 10:48:54 -05:00
Lennart Poettering d209e197f8
userdbctl: two trivial fixlets (#35296)
Fixes: #35294
2024-11-22 16:06:01 +01:00
Antonio Alvarez Feijoo 9ed090230e tpm2-util: fix parameter name 2024-11-22 16:04:16 +01:00
Lennart Poettering 47c5ca237b userdbctl: respect selected disposition also when showing gid boundaries
Follow-up for: ad5de3222f
2024-11-22 11:28:30 +01:00
Lennart Poettering 7f8a4f12df userdbctl: fix counting
Fixes: #35294
2024-11-22 11:28:28 +01:00
Lennart Poettering e412fc5e04 userbdctl: show 'mapped' user range only inside of userns
Outside of userns the concept makes no sense, there cannot be users
mapped from further outside.
2024-11-22 11:28:17 +01:00
Guillaume GONNET edef33b554
network/netdev: add support to create HSR interface 2023-02-05 20:09:01 +01:00
10 changed files with 282 additions and 6 deletions

View File

@ -200,6 +200,9 @@
<row><entry><varname>wlan</varname></entry> <row><entry><varname>wlan</varname></entry>
<entry>A virtual wireless network (WLAN) interface.</entry></row> <entry>A virtual wireless network (WLAN) interface.</entry></row>
<row><entry><varname>hsr</varname></entry>
<entry>IEC 62439 defined High-availability Seamless Redundancy (HSR) and Parallel Redundancy Protocol (PRP).</entry></row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
@ -2760,6 +2763,56 @@
</variablelist> </variablelist>
</refsect1> </refsect1>
<refsect1>
<title>[HSR] Section Options</title>
<para>The [HSR] section only applies for netdevs of kind <literal>hsr</literal> and accepts the
following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>SlaveInterface1=</varname></term>
<listitem>
<para>Name of the first interface bound to the HSR device.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SlaveInterface2=</varname></term>
<listitem>
<para>Name of the second interface bound to the HSR device. Must be a different network
interface than the one specified in <varname>SlaveInterface1</varname>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SupervisionTag=</varname></term>
<listitem>
<para>The last byte of the multicast address used for HSR supervision frames.
Takes an integer in the range 0…255. The default value is 0.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Version=</varname></term>
<listitem>
<para>The version of the underlying protocol. The default value is 0.
This parameter should only be used when <varname>Protocol=HSR</varname>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Protocol=</varname></term>
<listitem>
<para>The underlying protocol to use. Possible values are
<literal>HSR</literal> (High-availability Seamless Redundancy) and
<literal>PRP</literal> (Parallel Redundancy Protocol).
The default value is <literal>HSR</literal>.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1> <refsect1>
<title>Examples</title> <title>Examples</title>
<example> <example>

View File

@ -239,6 +239,16 @@ static const NLAPolicy rtnl_link_info_data_gre_policies[] = {
[IFLA_GRE_ERSPAN_HWID] = BUILD_POLICY(U16), [IFLA_GRE_ERSPAN_HWID] = BUILD_POLICY(U16),
}; };
static const NLAPolicy rtnl_link_info_data_hsr_policies[] = {
[IFLA_HSR_SLAVE1] = BUILD_POLICY(U32),
[IFLA_HSR_SLAVE2] = BUILD_POLICY(U32),
[IFLA_HSR_MULTICAST_SPEC] = BUILD_POLICY(U8),
[IFLA_HSR_VERSION] = BUILD_POLICY(U8),
[IFLA_HSR_SUPERVISION_ADDR] = BUILD_POLICY_WITH_SIZE(ETHER_ADDR, ETH_ALEN),
[IFLA_HSR_SEQ_NR] = BUILD_POLICY(U16),
[IFLA_HSR_PROTOCOL] = BUILD_POLICY(U8),
};
static const NLAPolicy rtnl_link_info_data_ipoib_policies[] = { static const NLAPolicy rtnl_link_info_data_ipoib_policies[] = {
[IFLA_IPOIB_PKEY] = BUILD_POLICY(U16), [IFLA_IPOIB_PKEY] = BUILD_POLICY(U16),
[IFLA_IPOIB_MODE] = BUILD_POLICY(U16), [IFLA_IPOIB_MODE] = BUILD_POLICY(U16),
@ -412,8 +422,8 @@ static const NLAPolicySetUnionElement rtnl_link_info_data_policy_set_union_eleme
BUILD_UNION_ELEMENT_BY_STRING("gretap", rtnl_link_info_data_gre), BUILD_UNION_ELEMENT_BY_STRING("gretap", rtnl_link_info_data_gre),
/* /*
BUILD_UNION_ELEMENT_BY_STRING("gtp", rtnl_link_info_data_gtp), BUILD_UNION_ELEMENT_BY_STRING("gtp", rtnl_link_info_data_gtp),
BUILD_UNION_ELEMENT_BY_STRING("hsr", rtnl_link_info_data_hsr),
*/ */
BUILD_UNION_ELEMENT_BY_STRING("hsr", rtnl_link_info_data_hsr),
BUILD_UNION_ELEMENT_BY_STRING("ip6erspan", rtnl_link_info_data_gre), BUILD_UNION_ELEMENT_BY_STRING("ip6erspan", rtnl_link_info_data_gre),
BUILD_UNION_ELEMENT_BY_STRING("ip6gre", rtnl_link_info_data_gre), BUILD_UNION_ELEMENT_BY_STRING("ip6gre", rtnl_link_info_data_gre),
BUILD_UNION_ELEMENT_BY_STRING("ip6gretap", rtnl_link_info_data_gre), BUILD_UNION_ELEMENT_BY_STRING("ip6gretap", rtnl_link_info_data_gre),

View File

@ -10,6 +10,7 @@ sources = files(
'netdev/dummy.c', 'netdev/dummy.c',
'netdev/fou-tunnel.c', 'netdev/fou-tunnel.c',
'netdev/geneve.c', 'netdev/geneve.c',
'netdev/hsr.c',
'netdev/ifb.c', 'netdev/ifb.c',
'netdev/ipoib.c', 'netdev/ipoib.c',
'netdev/ipvlan.c', 'netdev/ipvlan.c',

142
src/network/netdev/hsr.c Normal file
View File

@ -0,0 +1,142 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if_arp.h>
#include "hsr.h"
#include "string-table.h"
static const char* const hsr_protocol_table[_NETDEV_HSR_PROTOCOL_MAX] = {
[NETDEV_HSR_PROTOCOL_HSR] = "HSR",
[NETDEV_HSR_PROTOCOL_PRP] = "PRP",
};
DEFINE_STRING_TABLE_LOOKUP(hsr_protocol, HsrProtocol);
DEFINE_CONFIG_PARSE_ENUM(config_parse_hsr_protocol, hsr_protocol, HsrProtocol,
"Failed to parse Protocol=");
static int netdev_hsr_get_iface_indexes(Hsr *hsr, int *indexes) {
Link *link = NULL;
int r, i;
assert(hsr);
for (i = 0; i < _NETDEV_HSR_SLAVE_MAX; i++) {
r = link_get_by_name(hsr->meta.manager, hsr->slave_ifaces[i], &link);
if (r < 0)
return r;
if (indexes)
indexes[i] = link->ifindex;
}
return 0;
}
static int netdev_hsr_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Hsr *hsr;
int indexes[_NETDEV_HSR_SLAVE_MAX];
int r;
assert(netdev);
assert(!link);
assert(m);
hsr = HSR(netdev);
assert(hsr);
r = netdev_hsr_get_iface_indexes(hsr, indexes);
if (r < 0)
return r;
r = sd_netlink_message_append_u32(m, IFLA_HSR_SLAVE1, indexes[NETDEV_HSR_SLAVE1]);
if (r < 0)
return r;
r = sd_netlink_message_append_u32(m, IFLA_HSR_SLAVE2, indexes[NETDEV_HSR_SLAVE2]);
if (r < 0)
return r;
r = sd_netlink_message_append_u8(m, IFLA_HSR_MULTICAST_SPEC, hsr->multicast_spec);
if (r < 0)
return r;
/* Protocol version is not supported by kernel module when PRP is used. */
if (hsr->protocol == NETDEV_HSR_PROTOCOL_HSR) {
r = sd_netlink_message_append_u8(m, IFLA_HSR_VERSION, hsr->version);
if (r < 0)
return r;
}
r = sd_netlink_message_append_u8(m, IFLA_HSR_PROTOCOL, hsr->protocol);
if (r < 0)
return r;
return 0;
}
static int netdev_hsr_verify(NetDev *netdev, const char *filename) {
Hsr *hsr;
int i;
assert(netdev);
assert(filename);
hsr = HSR(netdev);
assert(hsr);
for (i = 0; i < _NETDEV_HSR_SLAVE_MAX; i++) {
if (!hsr->slave_ifaces[i])
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"HSR without SlaveInterface%d= configured in %s. Ignoring",
(i + 1), filename);
}
if (streq(hsr->slave_ifaces[NETDEV_HSR_SLAVE1], hsr->slave_ifaces[NETDEV_HSR_SLAVE2]))
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"SlaveInterface1= and SlaveInterface2= must be different in %s. Ignoring",
filename);
return 0;
}
static int netdev_hsr_is_ready_to_create(NetDev *netdev, Link *link) {
Hsr *hsr;
assert(netdev);
hsr = HSR(netdev);
assert(hsr);
return netdev_hsr_get_iface_indexes(hsr, NULL) >= 0;
}
static void netdev_hsr_done(NetDev *netdev) {
Hsr *hsr;
int i;
assert(netdev);
hsr = HSR(netdev);
assert(hsr);
for (i = 0; i < _NETDEV_HSR_SLAVE_MAX; i++)
free(hsr->slave_ifaces[i]);
}
const NetDevVTable hsr_vtable = {
.object_size = sizeof(Hsr),
.sections = NETDEV_COMMON_SECTIONS "HSR\0",
.fill_message_create = netdev_hsr_fill_message_create,
.config_verify = netdev_hsr_verify,
.is_ready_to_create = netdev_hsr_is_ready_to_create,
.done = netdev_hsr_done,
.create_type = NETDEV_CREATE_INDEPENDENT,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
};

38
src/network/netdev/hsr.h Normal file
View File

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
typedef struct Hsr Hsr;
#include "netdev.h"
typedef enum HsrSlave {
NETDEV_HSR_SLAVE1,
NETDEV_HSR_SLAVE2,
_NETDEV_HSR_SLAVE_MAX,
_NETDEV_HSR_SLAVE_INVALID = -EINVAL,
} HsrSlave;
typedef enum HsrProtocol {
NETDEV_HSR_PROTOCOL_HSR = HSR_PROTOCOL_HSR,
NETDEV_HSR_PROTOCOL_PRP = HSR_PROTOCOL_PRP,
_NETDEV_HSR_PROTOCOL_MAX,
_NETDEV_HSR_PROTOCOL_INVALID = -EINVAL,
} HsrProtocol;
struct Hsr {
NetDev meta;
char *slave_ifaces[_NETDEV_HSR_SLAVE_MAX];
uint8_t multicast_spec;
HsrProtocol protocol;
uint8_t version;
};
DEFINE_NETDEV_CAST(HSR, Hsr);
extern const NetDevVTable hsr_vtable;
const char *hsr_protocol_to_string(HsrProtocol d) _const_;
HsrProtocol hsr_protocol_from_string(const char *d) _pure_;
CONFIG_PARSER_PROTOTYPE(config_parse_hsr_protocol);

View File

@ -11,6 +11,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include "conf-parser.h" #include "conf-parser.h"
#include "fou-tunnel.h" #include "fou-tunnel.h"
#include "geneve.h" #include "geneve.h"
#include "hsr.h"
#include "ipoib.h" #include "ipoib.h"
#include "ipvlan.h" #include "ipvlan.h"
#include "l2tp-tunnel.h" #include "l2tp-tunnel.h"
@ -276,3 +277,8 @@ IPoIB.IgnoreUserspaceMulticastGroups, config_parse_tristate,
WLAN.PhysicalDevice, config_parse_wiphy, 0, 0 WLAN.PhysicalDevice, config_parse_wiphy, 0, 0
WLAN.Type, config_parse_wlan_iftype, 0, offsetof(WLan, iftype) WLAN.Type, config_parse_wlan_iftype, 0, offsetof(WLan, iftype)
WLAN.WDS, config_parse_tristate, 0, offsetof(WLan, wds) WLAN.WDS, config_parse_tristate, 0, offsetof(WLan, wds)
HSR.SlaveInterface1, config_parse_ifname, 0, offsetof(Hsr, slave_ifaces[NETDEV_HSR_SLAVE1])
HSR.SlaveInterface2, config_parse_ifname, 0, offsetof(Hsr, slave_ifaces[NETDEV_HSR_SLAVE2])
HSR.SupervisionTag, config_parse_uint8, 0, offsetof(Hsr, multicast_spec)
HSR.Version, config_parse_uint8, 0, offsetof(Hsr, version)
HSR.Protocol, config_parse_hsr_protocol, 0, offsetof(Hsr, protocol)

View File

@ -18,6 +18,7 @@
#include "fd-util.h" #include "fd-util.h"
#include "fou-tunnel.h" #include "fou-tunnel.h"
#include "geneve.h" #include "geneve.h"
#include "hsr.h"
#include "ifb.h" #include "ifb.h"
#include "ipoib.h" #include "ipoib.h"
#include "ipvlan.h" #include "ipvlan.h"
@ -65,6 +66,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_GENEVE] = &geneve_vtable, [NETDEV_KIND_GENEVE] = &geneve_vtable,
[NETDEV_KIND_GRE] = &gre_vtable, [NETDEV_KIND_GRE] = &gre_vtable,
[NETDEV_KIND_GRETAP] = &gretap_vtable, [NETDEV_KIND_GRETAP] = &gretap_vtable,
[NETDEV_KIND_HSR] = &hsr_vtable,
[NETDEV_KIND_IFB] = &ifb_vtable, [NETDEV_KIND_IFB] = &ifb_vtable,
[NETDEV_KIND_IP6GRE] = &ip6gre_vtable, [NETDEV_KIND_IP6GRE] = &ip6gre_vtable,
[NETDEV_KIND_IP6GRETAP] = &ip6gretap_vtable, [NETDEV_KIND_IP6GRETAP] = &ip6gretap_vtable,
@ -106,6 +108,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_GENEVE] = "geneve", [NETDEV_KIND_GENEVE] = "geneve",
[NETDEV_KIND_GRE] = "gre", [NETDEV_KIND_GRE] = "gre",
[NETDEV_KIND_GRETAP] = "gretap", [NETDEV_KIND_GRETAP] = "gretap",
[NETDEV_KIND_HSR] = "hsr",
[NETDEV_KIND_IFB] = "ifb", [NETDEV_KIND_IFB] = "ifb",
[NETDEV_KIND_IP6GRE] = "ip6gre", [NETDEV_KIND_IP6GRE] = "ip6gre",
[NETDEV_KIND_IP6GRETAP] = "ip6gretap", [NETDEV_KIND_IP6GRETAP] = "ip6gretap",

View File

@ -24,6 +24,7 @@
"-Bridge\0" \ "-Bridge\0" \
"-FooOverUDP\0" \ "-FooOverUDP\0" \
"-GENEVE\0" \ "-GENEVE\0" \
"-HSR\0" \
"-IPoIB\0" \ "-IPoIB\0" \
"-IPVLAN\0" \ "-IPVLAN\0" \
"-IPVTAP\0" \ "-IPVTAP\0" \
@ -59,6 +60,7 @@ typedef enum NetDevKind {
NETDEV_KIND_GENEVE, NETDEV_KIND_GENEVE,
NETDEV_KIND_GRE, NETDEV_KIND_GRE,
NETDEV_KIND_GRETAP, NETDEV_KIND_GRETAP,
NETDEV_KIND_HSR,
NETDEV_KIND_IFB, NETDEV_KIND_IFB,
NETDEV_KIND_IP6GRE, NETDEV_KIND_IP6GRE,
NETDEV_KIND_IP6GRETAP, NETDEV_KIND_IP6GRETAP,

View File

@ -392,7 +392,7 @@ int tpm2_make_pcr_json_array(uint32_t pcr_mask, sd_json_variant **ret);
int tpm2_parse_pcr_json_array(sd_json_variant *v, uint32_t *ret); int tpm2_parse_pcr_json_array(sd_json_variant *v, uint32_t *ret);
int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, const struct iovec *pubkey, uint32_t pubkey_pcr_mask, uint16_t primary_alg, const struct iovec blobs[], size_t n_blobs, const struct iovec policy_hash[], size_t n_policy_hash, const struct iovec *salt, const struct iovec *srk, const struct iovec *pcrlock_nv, TPM2Flags flags, sd_json_variant **ret); int tpm2_make_luks2_json(int keyslot, uint32_t hash_pcr_mask, uint16_t pcr_bank, const struct iovec *pubkey, uint32_t pubkey_pcr_mask, uint16_t primary_alg, const struct iovec blobs[], size_t n_blobs, const struct iovec policy_hash[], size_t n_policy_hash, const struct iovec *salt, const struct iovec *srk, const struct iovec *pcrlock_nv, TPM2Flags flags, sd_json_variant **ret);
int tpm2_parse_luks2_json(sd_json_variant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, struct iovec *ret_pubkey, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, struct iovec **ret_blobs, size_t *ret_n_blobs, struct iovec **ret_policy_hash, size_t *ret_n_policy_hash, struct iovec *ret_salt, struct iovec *ret_srk, struct iovec *pcrlock_nv, TPM2Flags *ret_flags); int tpm2_parse_luks2_json(sd_json_variant *v, int *ret_keyslot, uint32_t *ret_hash_pcr_mask, uint16_t *ret_pcr_bank, struct iovec *ret_pubkey, uint32_t *ret_pubkey_pcr_mask, uint16_t *ret_primary_alg, struct iovec **ret_blobs, size_t *ret_n_blobs, struct iovec **ret_policy_hash, size_t *ret_n_policy_hash, struct iovec *ret_salt, struct iovec *ret_srk, struct iovec *ret_pcrlock_nv, TPM2Flags *ret_flags);
/* Default to PCR 7 only */ /* Default to PCR 7 only */
#define TPM2_PCR_INDEX_DEFAULT UINT32_C(7) #define TPM2_PCR_INDEX_DEFAULT UINT32_C(7)

View File

@ -23,6 +23,7 @@
#include "user-util.h" #include "user-util.h"
#include "userdb.h" #include "userdb.h"
#include "verbs.h" #include "verbs.h"
#include "virt.h"
static enum { static enum {
OUTPUT_CLASSIC, OUTPUT_CLASSIC,
@ -139,10 +140,16 @@ static int show_user(UserRecord *ur, Table *table) {
return 0; return 0;
} }
static bool test_show_mapped(void) {
/* Show mapped user range only in environments where user mapping is a thing. */
return running_in_userns() > 0;
}
static const struct { static const struct {
uid_t first, last; uid_t first, last;
const char *name; const char *name;
UserDisposition disposition; UserDisposition disposition;
bool (*test)(void);
} uid_range_table[] = { } uid_range_table[] = {
{ {
.first = 1, .first = 1,
@ -175,11 +182,12 @@ static const struct {
.last = MAP_UID_MAX, .last = MAP_UID_MAX,
.name = "mapped", .name = "mapped",
.disposition = USER_REGULAR, .disposition = USER_REGULAR,
.test = test_show_mapped,
}, },
}; };
static int table_add_uid_boundaries(Table *table, const UIDRange *p) { static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
int r; int r, n_added = 0;
assert(table); assert(table);
@ -192,6 +200,9 @@ static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
if (!uid_range_covers(p, i->first, i->last - i->first + 1)) if (!uid_range_covers(p, i->first, i->last - i->first + 1))
continue; continue;
if (i->test && !i->test())
continue;
name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN),
" begin ", i->name, " users ", " begin ", i->name, " users ",
special_glyph(SPECIAL_GLYPH_ARROW_DOWN)); special_glyph(SPECIAL_GLYPH_ARROW_DOWN));
@ -249,9 +260,11 @@ static int table_add_uid_boundaries(Table *table, const UIDRange *p) {
TABLE_INT, 1); /* sort after any other entry with the same UID */ TABLE_INT, 1); /* sort after any other entry with the same UID */
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
n_added += 2;
} }
return ELEMENTSOF(uid_range_table) * 2; return n_added;
} }
static int add_unavailable_uid(Table *table, uid_t start, uid_t end) { static int add_unavailable_uid(Table *table, uid_t start, uid_t end) {
@ -565,16 +578,22 @@ static int show_group(GroupRecord *gr, Table *table) {
} }
static int table_add_gid_boundaries(Table *table, const UIDRange *p) { static int table_add_gid_boundaries(Table *table, const UIDRange *p) {
int r; int r, n_added = 0;
assert(table); assert(table);
FOREACH_ELEMENT(i, uid_range_table) { FOREACH_ELEMENT(i, uid_range_table) {
_cleanup_free_ char *name = NULL, *comment = NULL; _cleanup_free_ char *name = NULL, *comment = NULL;
if (!FLAGS_SET(arg_disposition_mask, UINT64_C(1) << i->disposition))
continue;
if (!uid_range_covers(p, i->first, i->last - i->first + 1)) if (!uid_range_covers(p, i->first, i->last - i->first + 1))
continue; continue;
if (i->test && !i->test())
continue;
name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN),
" begin ", i->name, " groups ", " begin ", i->name, " groups ",
special_glyph(SPECIAL_GLYPH_ARROW_DOWN)); special_glyph(SPECIAL_GLYPH_ARROW_DOWN));
@ -626,9 +645,11 @@ static int table_add_gid_boundaries(Table *table, const UIDRange *p) {
TABLE_INT, 1); /* sort after any other entry with the same GID */ TABLE_INT, 1); /* sort after any other entry with the same GID */
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
n_added += 2;
} }
return ELEMENTSOF(uid_range_table) * 2; return n_added;
} }
static int add_unavailable_gid(Table *table, uid_t start, uid_t end) { static int add_unavailable_gid(Table *table, uid_t start, uid_t end) {