udev: support AlternativeName= setting in .link file
This commit is contained in:
parent
4252696aec
commit
a5053a158b
|
@ -356,6 +356,14 @@
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>AlternativeName=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>The alternative interface name to use. This option can be specified multiple times.
|
||||||
|
If the empty string is assigned to this option, the list is reset, and all prior assignments
|
||||||
|
have no effect.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>MTUBytes=</varname></term>
|
<term><varname>MTUBytes=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "netlink-internal.h"
|
#include "netlink-internal.h"
|
||||||
#include "netlink-util.h"
|
#include "netlink-util.h"
|
||||||
|
#include "strv.h"
|
||||||
|
|
||||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
@ -83,6 +84,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
|
||||||
|
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(rtnl);
|
||||||
|
assert(ifindex > 0);
|
||||||
|
|
||||||
|
if (strv_isempty(alternative_names))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!*rtnl) {
|
||||||
|
r = sd_netlink_open(rtnl);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_message_close_container(message);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = sd_netlink_call(*rtnl, message, 0, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
|
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
|
||||||
struct nlmsgerr *err;
|
struct nlmsgerr *err;
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -49,6 +49,7 @@ static inline bool rtnl_message_type_is_qdisc(uint16_t type) {
|
||||||
|
|
||||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
|
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
|
||||||
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
|
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
|
||||||
|
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
|
||||||
|
|
||||||
int rtnl_log_parse_error(int r);
|
int rtnl_log_parse_error(int r);
|
||||||
int rtnl_log_create_error(int r);
|
int rtnl_log_create_error(int r);
|
||||||
|
|
|
@ -985,6 +985,66 @@ int config_parse_ifname(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_ifnames(
|
||||||
|
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_strv_free_ char **names = NULL;
|
||||||
|
char ***s = data;
|
||||||
|
const char *p;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
*s = strv_free(*s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = rvalue;
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *word = NULL;
|
||||||
|
|
||||||
|
r = extract_first_word(&p, &word, NULL, 0);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
"Failed to extract interface name, ignoring assignment: %s",
|
||||||
|
rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ifname_valid_full(word, ltype)) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0,
|
||||||
|
"Interface name is not valid or too long, ignoring assignment: %s",
|
||||||
|
word);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = strv_consume(&names, TAKE_PTR(word));
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
r = strv_extend_strv(s, names, true);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_ip_port(
|
int config_parse_ip_port(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
|
|
|
@ -137,6 +137,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_signal);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_personality);
|
CONFIG_PARSER_PROTOTYPE(config_parse_personality);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_permille);
|
CONFIG_PARSER_PROTOTYPE(config_parse_permille);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ifname);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ifname);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
|
CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
|
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
|
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
|
||||||
|
|
|
@ -35,6 +35,7 @@ Link.MACAddressPolicy, config_parse_mac_address_policy, 0,
|
||||||
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
|
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
|
||||||
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
|
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
|
||||||
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
|
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
|
||||||
|
Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
|
||||||
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
|
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
|
||||||
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
|
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
|
||||||
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
|
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
|
||||||
|
|
|
@ -58,6 +58,7 @@ static void link_config_free(link_config *link) {
|
||||||
free(link->mac);
|
free(link->mac);
|
||||||
free(link->name_policy);
|
free(link->name_policy);
|
||||||
free(link->name);
|
free(link->name);
|
||||||
|
strv_free(link->alternative_names);
|
||||||
free(link->alias);
|
free(link->alias);
|
||||||
|
|
||||||
free(link);
|
free(link);
|
||||||
|
@ -458,6 +459,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
|
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
|
||||||
|
|
||||||
|
r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
|
||||||
|
if (r < 0)
|
||||||
|
return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
|
||||||
|
|
||||||
*name = new_name;
|
*name = new_name;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct link_config {
|
||||||
MACAddressPolicy mac_address_policy;
|
MACAddressPolicy mac_address_policy;
|
||||||
NamePolicy *name_policy;
|
NamePolicy *name_policy;
|
||||||
char *name;
|
char *name;
|
||||||
|
char **alternative_names;
|
||||||
char *alias;
|
char *alias;
|
||||||
uint32_t mtu;
|
uint32_t mtu;
|
||||||
size_t speed;
|
size_t speed;
|
||||||
|
|
|
@ -16,6 +16,7 @@ MACAddressPolicy=
|
||||||
MACAddress=
|
MACAddress=
|
||||||
NamePolicy=
|
NamePolicy=
|
||||||
Name=
|
Name=
|
||||||
|
AlternativeName=
|
||||||
Alias=
|
Alias=
|
||||||
MTUBytes=
|
MTUBytes=
|
||||||
BitsPerSecond=
|
BitsPerSecond=
|
||||||
|
|
Loading…
Reference in New Issue