mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-21 09:33:57 +03:00
network-generator: support to set NamePolicy= through kernel command line argument
Closes #16296.
This commit is contained in:
parent
ff516b4341
commit
a4c9bf2e51
@ -59,6 +59,7 @@
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ifname=</varname></term>
|
||||
<term><varname>net.ifname-policy=</varname></term>
|
||||
<listitem>
|
||||
<para>— translated into
|
||||
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry> files.</para>
|
||||
@ -88,6 +89,8 @@
|
||||
|
||||
<para>See
|
||||
<citerefentry project='man-pages'><refentrytitle>dracut.kernel</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
and
|
||||
<citerefentry><refentrytitle>systemd-udevd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
for option syntax and details.</para>
|
||||
</refsect1>
|
||||
|
||||
|
@ -224,6 +224,45 @@
|
||||
appear, which affects older name derivation algorithms, too.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>net.ifname-policy=<replaceable>policy1</replaceable>[,<replaceable>policy2</replaceable>,…][,<replaceable>MAC</replaceable>]</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies naming policies applied when renaming network interfaces. Takes a list of
|
||||
policies and an optional MAC address separated with comma. Each policy value must be one of
|
||||
the policies understood by the <varname>NamePolicy=</varname> setting in .link files, e.g.
|
||||
<literal>onboard</literal> or <literal>path</literal>. See
|
||||
<citerefentry><refentrytitle>systemd.link</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for more details. When the MAC address is specified, the policies are applied to the
|
||||
interface which has the address. When no MAC address is specified, the policies are applied
|
||||
to all interfaces. This kernel command line argument can be specified multiple times. This
|
||||
argument is not directly read from <command>systemd-udevd</command>, but read and converted
|
||||
to a .link file by <command>systemd-network-generator</command>. So, to make this argument
|
||||
take effect, <filename>systemd-network-generator.service</filename> must be enabled and
|
||||
started before starting <filename>systemd-udevd.service</filename>. See
|
||||
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
for more details about the service.</para>
|
||||
<para>Example:
|
||||
<programlisting>net.ifname-policy=keep,kernel,path,slot,onboard,01:23:45:67:89:ab
|
||||
net.ifname-policy=keep,kernel,path,slot,onboard,mac</programlisting>
|
||||
This is mostly equivalent to creating the following .link files:
|
||||
<programlisting># 91-name-policy-with-mac.link
|
||||
[Match]
|
||||
MACAddress=01:23:45:67:89:ab
|
||||
|
||||
[Link]
|
||||
NamePolicy=keep kernel path slot onboard
|
||||
AlternativeNamePolicy=path slot onboard</programlisting>
|
||||
and
|
||||
<programlisting># 92-name-policy-for-all.link
|
||||
[Match]
|
||||
OriginalName=*
|
||||
|
||||
[Link]
|
||||
NamePolicy=keep kernel path slot onboard mac
|
||||
AlternativeNamePolicy=path slot onboard mac</programlisting>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<!-- when adding entries here, consider also adding them in kernel-command-line.xml -->
|
||||
</refsect1>
|
||||
|
@ -65,9 +65,10 @@ static int link_save(Link *link, const char *dest_dir) {
|
||||
|
||||
assert(link);
|
||||
|
||||
r = asprintf(&filename, "90-%s.link",
|
||||
link->ifname);
|
||||
if (r < 0)
|
||||
filename = strjoin(!isempty(link->ifname) ? "90" :
|
||||
!hw_addr_is_null(&link->mac) ? "91" : "92",
|
||||
"-", link->filename, ".link");
|
||||
if (!filename)
|
||||
return log_oom();
|
||||
|
||||
r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
@ -104,7 +105,7 @@ static int context_save(Context *context) {
|
||||
r = k;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(link, context->links_by_name) {
|
||||
HASHMAP_FOREACH(link, context->links_by_filename) {
|
||||
k = link_save(link, p);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "hostname-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "netif-naming-scheme.h"
|
||||
#include "network-generator.h"
|
||||
#include "parse-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
@ -25,6 +26,7 @@
|
||||
|
||||
# .link
|
||||
ifname=<interface>:<MAC>
|
||||
net.ifname-policy=policy1[,policy2,...][,<MAC>] # This is an original rule, not supported by other tools.
|
||||
|
||||
# .netdev
|
||||
vlan=<vlanname>:<phydevice>
|
||||
@ -263,7 +265,10 @@ static Link *link_free(Link *link) {
|
||||
if (!link)
|
||||
return NULL;
|
||||
|
||||
free(link->filename);
|
||||
free(link->ifname);
|
||||
strv_free(link->policies);
|
||||
strv_free(link->alt_policies);
|
||||
return mfree(link);
|
||||
}
|
||||
|
||||
@ -276,28 +281,43 @@ static int link_new(
|
||||
Link **ret) {
|
||||
|
||||
_cleanup_(link_freep) Link *link = NULL;
|
||||
_cleanup_free_ char *ifname = NULL;
|
||||
_cleanup_free_ char *ifname = NULL, *filename = NULL;
|
||||
int r;
|
||||
|
||||
assert(context);
|
||||
assert(mac);
|
||||
|
||||
if (!ifname_valid(name))
|
||||
return -EINVAL;
|
||||
if (name) {
|
||||
if (!ifname_valid(name))
|
||||
return -EINVAL;
|
||||
|
||||
ifname = strdup(name);
|
||||
if (!ifname)
|
||||
return -ENOMEM;
|
||||
ifname = strdup(name);
|
||||
if (!ifname)
|
||||
return -ENOMEM;
|
||||
|
||||
filename = strdup(name);
|
||||
if (!filename)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
filename = strdup(hw_addr_is_null(mac) ? "default" :
|
||||
HW_ADDR_TO_STR_FULL(mac, HW_ADDR_TO_STRING_NO_COLON));
|
||||
if (!filename)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
link = new(Link, 1);
|
||||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
*link = (Link) {
|
||||
.filename = TAKE_PTR(filename),
|
||||
.ifname = TAKE_PTR(ifname),
|
||||
.mac = *mac,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_put(&context->links_by_name, &string_hash_ops, link->ifname, link);
|
||||
r = hashmap_ensure_put(&context->links_by_filename, &string_hash_ops, link->filename, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -308,8 +328,10 @@ static int link_new(
|
||||
return 0;
|
||||
}
|
||||
|
||||
Link *link_get(Context *context, const char *ifname) {
|
||||
return hashmap_get(context->links_by_name, ifname);
|
||||
Link *link_get(Context *context, const char *filename) {
|
||||
assert(context);
|
||||
assert(filename);
|
||||
return hashmap_get(context->links_by_filename, filename);
|
||||
}
|
||||
|
||||
static int network_set_dhcp_type(Context *context, const char *ifname, const char *dhcp_type) {
|
||||
@ -922,6 +944,65 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v
|
||||
return link_new(context, name, &mac, NULL);
|
||||
}
|
||||
|
||||
static int parse_cmdline_ifname_policy(Context *context, const char *key, const char *value) {
|
||||
_cleanup_strv_free_ char **policies = NULL, **alt_policies = NULL;
|
||||
struct hw_addr_data mac = HW_ADDR_NULL;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
/* net.ifname-policy=policy1[,policy2,...][,<MAC>] */
|
||||
|
||||
if (proc_cmdline_value_missing(key, value))
|
||||
return -EINVAL;
|
||||
|
||||
for (const char *q = value; ; ) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
NamePolicy p;
|
||||
|
||||
r = extract_first_word(&q, &word, ",", 0);
|
||||
if (r == 0)
|
||||
break;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = name_policy_from_string(word);
|
||||
if (p < 0) {
|
||||
r = parse_hw_addr(word, &mac);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (hw_addr_is_null(&mac))
|
||||
return -EINVAL;
|
||||
|
||||
if (!isempty(q))
|
||||
return -EINVAL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (alternative_names_policy_from_string(word) >= 0) {
|
||||
r = strv_extend(&alt_policies, word);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = strv_consume(&policies, TAKE_PTR(word));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (strv_isempty(policies))
|
||||
return -EINVAL;
|
||||
|
||||
r = link_new(context, NULL, &mac, &link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link->policies = TAKE_PTR(policies);
|
||||
link->alt_policies = TAKE_PTR(alt_policies);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_cmdline_item(const char *key, const char *value, void *data) {
|
||||
Context *context = data;
|
||||
|
||||
@ -944,6 +1025,8 @@ int parse_cmdline_item(const char *key, const char *value, void *data) {
|
||||
return parse_cmdline_bond(context, key, value);
|
||||
if (streq(key, "ifname"))
|
||||
return parse_cmdline_ifname(context, key, value);
|
||||
if (streq(key, "net.ifname-policy"))
|
||||
return parse_cmdline_ifname_policy(context, key, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -995,7 +1078,7 @@ void context_clear(Context *context) {
|
||||
|
||||
hashmap_free_with_destructor(context->networks_by_name, network_free);
|
||||
hashmap_free_with_destructor(context->netdevs_by_name, netdev_free);
|
||||
hashmap_free_with_destructor(context->links_by_name, link_free);
|
||||
hashmap_free_with_destructor(context->links_by_filename, link_free);
|
||||
}
|
||||
|
||||
static int address_dump(Address *address, FILE *f) {
|
||||
@ -1123,11 +1206,25 @@ void link_dump(Link *link, FILE *f) {
|
||||
|
||||
if (!hw_addr_is_null(&link->mac))
|
||||
fprintf(f, "MACAddress=%s\n", HW_ADDR_TO_STR(&link->mac));
|
||||
else
|
||||
fputs("OriginalName=*\n", f);
|
||||
|
||||
fprintf(f,
|
||||
"\n[Link]\n"
|
||||
"Name=%s\n",
|
||||
link->ifname);
|
||||
fputs("\n[Link]\n", f);
|
||||
|
||||
if (!isempty(link->ifname))
|
||||
fprintf(f, "Name=%s\n", link->ifname);
|
||||
|
||||
if (!strv_isempty(link->policies)) {
|
||||
fputs("NamePolicy=", f);
|
||||
fputstrv(f, link->policies, " ", NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
if (!strv_isempty(link->alt_policies)) {
|
||||
fputs("AlternativeNamesPolicy=", f);
|
||||
fputstrv(f, link->alt_policies, " ", NULL);
|
||||
fputc('\n', f);
|
||||
}
|
||||
}
|
||||
|
||||
int network_format(Network *network, char **ret) {
|
||||
|
@ -81,17 +81,21 @@ struct NetDev {
|
||||
};
|
||||
|
||||
struct Link {
|
||||
char *filename;
|
||||
|
||||
/* [Match] */
|
||||
struct hw_addr_data mac;
|
||||
|
||||
/* [Link] */
|
||||
char *ifname;
|
||||
char **policies;
|
||||
char **alt_policies;
|
||||
};
|
||||
|
||||
typedef struct Context {
|
||||
Hashmap *networks_by_name;
|
||||
Hashmap *netdevs_by_name;
|
||||
Hashmap *links_by_name;
|
||||
Hashmap *links_by_filename;
|
||||
} Context;
|
||||
|
||||
int parse_cmdline_item(const char *key, const char *value, void *data);
|
||||
@ -106,6 +110,6 @@ NetDev *netdev_get(Context *context, const char *ifname);
|
||||
void netdev_dump(NetDev *netdev, FILE *f);
|
||||
int netdev_format(NetDev *netdev, char **ret);
|
||||
|
||||
Link *link_get(Context *context, const char *ifname);
|
||||
Link *link_get(Context *context, const char *filename);
|
||||
void link_dump(Link *link, FILE *f);
|
||||
int link_format(Link *link, char **ret);
|
||||
|
Loading…
Reference in New Issue
Block a user