mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-04 17:47:03 +03:00
Merge pull request #25052 from yuwata/resolvconf-compat
resolvconf-compat: first try to use the specified interface name as is
This commit is contained in:
commit
8cf144c3f6
@ -171,9 +171,12 @@ int split_pair(const char *s, const char *sep, char **l, char **r);
|
||||
|
||||
int free_and_strdup(char **p, const char *s);
|
||||
static inline int free_and_strdup_warn(char **p, const char *s) {
|
||||
if (free_and_strdup(p, s) < 0)
|
||||
int r;
|
||||
|
||||
r = free_and_strdup(p, s);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
int free_and_strndup(char **p, const char *s, size_t l);
|
||||
|
||||
|
@ -108,51 +108,74 @@ static int interface_info_compare(const InterfaceInfo *a, const InterfaceInfo *b
|
||||
return strcmp_ptr(a->name, b->name);
|
||||
}
|
||||
|
||||
int ifname_mangle(const char *s) {
|
||||
_cleanup_free_ char *iface = NULL;
|
||||
int ifi;
|
||||
int ifname_mangle_full(const char *s, bool drop_protocol_specifier) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_strv_free_ char **found = NULL;
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
iface = strdup(s);
|
||||
if (!iface)
|
||||
return log_oom();
|
||||
if (drop_protocol_specifier) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
int ifindex_longest_name = -ENODEV;
|
||||
|
||||
ifi = rtnl_resolve_interface(NULL, iface);
|
||||
if (ifi < 0) {
|
||||
if (ifi == -ENODEV && arg_ifindex_permissive) {
|
||||
log_debug("Interface '%s' not found, but -f specified, ignoring.", iface);
|
||||
return 0; /* done */
|
||||
/* When invoked as resolvconf, drop the protocol specifier(s) at the end. */
|
||||
|
||||
buf = strdup(s);
|
||||
if (!buf)
|
||||
return log_oom();
|
||||
|
||||
for (;;) {
|
||||
r = rtnl_resolve_interface(&rtnl, buf);
|
||||
if (r > 0) {
|
||||
if (ifindex_longest_name <= 0)
|
||||
ifindex_longest_name = r;
|
||||
|
||||
r = strv_extend(&found, buf);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
char *dot = strrchr(buf, '.');
|
||||
if (!dot)
|
||||
break;
|
||||
|
||||
*dot = '\0';
|
||||
}
|
||||
|
||||
return log_error_errno(ifi, "Failed to resolve interface \"%s\": %m", iface);
|
||||
unsigned n = strv_length(found);
|
||||
if (n > 1) {
|
||||
_cleanup_free_ char *joined = NULL;
|
||||
|
||||
joined = strv_join(found, ", ");
|
||||
log_warning("Found multiple interfaces (%s) matching with '%s'. Using '%s' (ifindex=%i).",
|
||||
strna(joined), s, found[0], ifindex_longest_name);
|
||||
|
||||
} else if (n == 1) {
|
||||
const char *proto;
|
||||
|
||||
proto = ASSERT_PTR(startswith(s, found[0]));
|
||||
if (!isempty(proto))
|
||||
log_info("Dropped protocol specifier '%s' from '%s'. Using '%s' (ifindex=%i).",
|
||||
proto, s, found[0], ifindex_longest_name);
|
||||
}
|
||||
|
||||
r = ifindex_longest_name;
|
||||
} else
|
||||
r = rtnl_resolve_interface(&rtnl, s);
|
||||
if (r < 0) {
|
||||
if (ERRNO_IS_DEVICE_ABSENT(r) && arg_ifindex_permissive) {
|
||||
log_debug_errno(r, "Interface '%s' not found, but -f specified, ignoring: %m", s);
|
||||
return 0; /* done */
|
||||
}
|
||||
return log_error_errno(r, "Failed to resolve interface \"%s\": %m", s);
|
||||
}
|
||||
|
||||
if (arg_ifindex > 0 && arg_ifindex != ifi)
|
||||
if (arg_ifindex > 0 && arg_ifindex != r)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Specified multiple different interfaces. Refusing.");
|
||||
|
||||
arg_ifindex = ifi;
|
||||
free_and_replace(arg_ifname, iface);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ifname_resolvconf_mangle(const char *s) {
|
||||
const char *dot;
|
||||
|
||||
assert(s);
|
||||
|
||||
dot = strrchr(s, '.');
|
||||
if (dot) {
|
||||
_cleanup_free_ char *iface = NULL;
|
||||
|
||||
log_debug("Ignoring protocol specifier '%s'.", dot + 1);
|
||||
iface = strndup(s, dot - s);
|
||||
if (!iface)
|
||||
return log_oom();
|
||||
return ifname_mangle(iface);
|
||||
} else
|
||||
return ifname_mangle(s);
|
||||
arg_ifindex = r;
|
||||
return free_and_strdup_warn(&arg_ifname, found ? found[0] : s); /* found */
|
||||
}
|
||||
|
||||
static void print_source(uint64_t flags, usec_t rtt) {
|
||||
@ -3599,16 +3622,19 @@ static int compat_main(int argc, char *argv[], sd_bus *bus) {
|
||||
|
||||
static int run(int argc, char **argv) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
bool compat = false;
|
||||
int r;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
log_setup();
|
||||
|
||||
if (invoked_as(argv, "resolvconf"))
|
||||
if (invoked_as(argv, "resolvconf")) {
|
||||
compat = true;
|
||||
r = resolvconf_parse_argv(argc, argv);
|
||||
else if (invoked_as(argv, "systemd-resolve"))
|
||||
} else if (invoked_as(argv, "systemd-resolve")) {
|
||||
compat = true;
|
||||
r = compat_parse_argv(argc, argv);
|
||||
else
|
||||
} else
|
||||
r = native_parse_argv(argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
@ -3617,7 +3643,7 @@ static int run(int argc, char **argv) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "sd_bus_open_system: %m");
|
||||
|
||||
if (STR_IN_SET(program_invocation_short_name, "systemd-resolve", "resolvconf"))
|
||||
if (compat)
|
||||
return compat_main(argc, argv, bus);
|
||||
|
||||
return native_main(argc, argv, bus);
|
||||
|
@ -26,5 +26,10 @@ extern char **arg_set_dns;
|
||||
extern char **arg_set_domain;
|
||||
extern bool arg_ifindex_permissive;
|
||||
|
||||
int ifname_mangle(const char *s);
|
||||
int ifname_resolvconf_mangle(const char *s);
|
||||
int ifname_mangle_full(const char *s, bool drop_protocol_specifier);
|
||||
static inline int ifname_mangle(const char *s) {
|
||||
return ifname_mangle_full(s, false);
|
||||
}
|
||||
static inline int ifname_resolvconf_mangle(const char *s) {
|
||||
return ifname_mangle_full(s, true);
|
||||
}
|
||||
|
@ -109,9 +109,8 @@ int verb_set_default(int argc, char *argv[], void *userdata) {
|
||||
if (install_client_side()) {
|
||||
r = unit_file_set_default(arg_scope, UNIT_FILE_FORCE, arg_root, unit, &changes, &n_changes);
|
||||
install_changes_dump(r, "set default", changes, n_changes, arg_quiet);
|
||||
|
||||
if (r > 0)
|
||||
r = 0;
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
} else {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
@ -134,10 +133,9 @@ int verb_set_default(int argc, char *argv[], void *userdata) {
|
||||
/* Try to reload if enabled */
|
||||
if (!arg_no_reload) {
|
||||
r = daemon_reload(ACTION_RELOAD, /* graceful= */ false);
|
||||
if (r > 0)
|
||||
r = 0;
|
||||
} else
|
||||
r = 0;
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
emit_cmdline_warning();
|
||||
@ -147,7 +145,7 @@ int verb_set_default(int argc, char *argv[], void *userdata) {
|
||||
|
||||
r = determine_default(&final);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto finish;
|
||||
|
||||
if (!streq(final, unit))
|
||||
log_notice("Note: \"%s\" is the default unit (possibly a runtime override).", final);
|
||||
@ -156,5 +154,5 @@ int verb_set_default(int argc, char *argv[], void *userdata) {
|
||||
finish:
|
||||
install_changes_free(changes, n_changes);
|
||||
|
||||
return r;
|
||||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
@ -5,6 +5,9 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
# shellcheck source=test/units/assert.sh
|
||||
. "$(dirname "$0")"/assert.sh
|
||||
|
||||
: >/failed
|
||||
|
||||
RUN_OUT="$(mktemp)"
|
||||
@ -25,6 +28,36 @@ monitor_check_rr() {
|
||||
set -o pipefail
|
||||
}
|
||||
|
||||
# Test for resolvectl, resolvconf
|
||||
systemctl unmask systemd-resolved.service
|
||||
systemctl start systemd-resolved.service
|
||||
systemctl service-log-level systemd-resolved.service debug
|
||||
ip link add hoge type dummy
|
||||
ip link add hoge.foo type dummy
|
||||
resolvectl dns hoge 10.0.0.1 10.0.0.2
|
||||
resolvectl dns hoge.foo 10.0.0.3 10.0.0.4
|
||||
assert_in '10.0.0.1 10.0.0.2' "$(resolvectl dns hoge)"
|
||||
assert_in '10.0.0.3 10.0.0.4' "$(resolvectl dns hoge.foo)"
|
||||
resolvectl dns hoge 10.0.1.1 10.0.1.2
|
||||
resolvectl dns hoge.foo 10.0.1.3 10.0.1.4
|
||||
assert_in '10.0.1.1 10.0.1.2' "$(resolvectl dns hoge)"
|
||||
assert_in '10.0.1.3 10.0.1.4' "$(resolvectl dns hoge.foo)"
|
||||
if ! RESOLVCONF=$(command -v resolvconf 2>/dev/null); then
|
||||
TMPDIR=$(mktemp -d -p /tmp resolvconf-tests.XXXXXX)
|
||||
RESOLVCONF="$TMPDIR"/resolvconf
|
||||
ln -s "$(command -v resolvectl 2>/dev/null)" "$RESOLVCONF"
|
||||
fi
|
||||
echo nameserver 10.0.2.1 10.0.2.2 | "$RESOLVCONF" -a hoge
|
||||
echo nameserver 10.0.2.3 10.0.2.4 | "$RESOLVCONF" -a hoge.foo
|
||||
assert_in '10.0.2.1 10.0.2.2' "$(resolvectl dns hoge)"
|
||||
assert_in '10.0.2.3 10.0.2.4' "$(resolvectl dns hoge.foo)"
|
||||
echo nameserver 10.0.3.1 10.0.3.2 | "$RESOLVCONF" -a hoge.inet.ipsec.192.168.35
|
||||
echo nameserver 10.0.3.3 10.0.3.4 | "$RESOLVCONF" -a hoge.foo.dhcp
|
||||
assert_in '10.0.3.1 10.0.3.2' "$(resolvectl dns hoge)"
|
||||
assert_in '10.0.3.3 10.0.3.4' "$(resolvectl dns hoge.foo)"
|
||||
ip link del hoge
|
||||
ip link del hoge.foo
|
||||
|
||||
### SETUP ###
|
||||
# Configure network
|
||||
hostnamectl hostname ns1.unsigned.test
|
||||
@ -74,8 +107,9 @@ mkdir -p /etc/bind
|
||||
ln -svf /etc/bind.keys /etc/bind/bind.keys
|
||||
|
||||
# Start the services
|
||||
systemctl unmask systemd-networkd systemd-resolved
|
||||
systemctl start systemd-networkd systemd-resolved
|
||||
systemctl unmask systemd-networkd
|
||||
systemctl start systemd-networkd
|
||||
systemctl restart systemd-resolved
|
||||
# Create knot's runtime dir, since from certain version it's provided only by
|
||||
# the package and not created by tmpfiles/systemd
|
||||
if [[ ! -d /run/knot ]]; then
|
||||
|
Loading…
x
Reference in New Issue
Block a user