mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 18:23:32 +08:00
Merge pull request #31109 from yuwata/nspawn-resolve-network-interface-before-move
nspawn: resolve network interface names before move to container namespace
This commit is contained in:
commit
4d8f4e02ba
@ -345,17 +345,11 @@ _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) {
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(ifname, -EINVAL);
|
||||
|
||||
r = parse_ifindex(ifname);
|
||||
if (r > 0)
|
||||
return sd_device_new_from_ifindex(ret, r);
|
||||
r = device_new_from_main_ifname(ret, ifname);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
if (ifname_valid(ifname)) {
|
||||
r = device_new_from_main_ifname(ret, ifname);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = rtnl_resolve_link_alternative_name(NULL, ifname, &main_name);
|
||||
r = rtnl_resolve_ifname_full(NULL, RESOLVE_IFNAME_ALTERNATIVE | RESOLVE_IFNAME_NUMERIC, ifname, &main_name, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -364,14 +358,15 @@ _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) {
|
||||
|
||||
_public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||
char ifname[IF_NAMESIZE];
|
||||
_cleanup_free_ char *ifname = NULL;
|
||||
int r, i;
|
||||
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(ifindex > 0, -EINVAL);
|
||||
|
||||
if (format_ifname(ifindex, ifname) < 0)
|
||||
return -ENODEV;
|
||||
r = rtnl_get_ifname_full(NULL, ifindex, &ifname, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = device_new_from_main_ifname(&dev, ifname);
|
||||
if (r < 0)
|
||||
|
@ -11,6 +11,154 @@
|
||||
#include "process-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
static int parse_newlink_message(
|
||||
sd_netlink_message *message,
|
||||
char **ret_name,
|
||||
char ***ret_altnames) {
|
||||
|
||||
_cleanup_strv_free_ char **altnames = NULL;
|
||||
int r, ifindex;
|
||||
|
||||
assert(message);
|
||||
|
||||
uint16_t type;
|
||||
r = sd_netlink_message_get_type(message, &type);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (type != RTM_NEWLINK)
|
||||
return -EPROTO;
|
||||
|
||||
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (ifindex <= 0)
|
||||
return -EPROTO;
|
||||
|
||||
if (ret_altnames) {
|
||||
r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &altnames);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ret_name) {
|
||||
r = sd_netlink_message_read_string_strdup(message, IFLA_IFNAME, ret_name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (ret_altnames)
|
||||
*ret_altnames = TAKE_PTR(altnames);
|
||||
|
||||
return ifindex;
|
||||
}
|
||||
|
||||
int rtnl_get_ifname_full(sd_netlink **rtnl, int ifindex, char **ret_name, char ***ret_altnames) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL;
|
||||
int r;
|
||||
|
||||
assert(ifindex > 0);
|
||||
|
||||
/* This is similar to if_indextoname(), but also optionally provides alternative names. */
|
||||
|
||||
if (!rtnl)
|
||||
rtnl = &our_rtnl;
|
||||
if (!*rtnl) {
|
||||
r = sd_netlink_open(rtnl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return parse_newlink_message(reply, ret_name, ret_altnames);
|
||||
}
|
||||
|
||||
int rtnl_resolve_ifname_full(
|
||||
sd_netlink **rtnl,
|
||||
ResolveInterfaceNameFlag flags,
|
||||
const char *name,
|
||||
char **ret_name,
|
||||
char ***ret_altnames) {
|
||||
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL;
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
assert(flags > 0);
|
||||
|
||||
/* This is similar to if_nametoindex(), but also resolves alternative names and decimal formatted
|
||||
* ifindex too. Returns ifindex, and optionally provides the main interface name and alternative
|
||||
* names.*/
|
||||
|
||||
if (!rtnl)
|
||||
rtnl = &our_rtnl;
|
||||
if (!*rtnl) {
|
||||
r = sd_netlink_open(rtnl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* First, use IFLA_IFNAME */
|
||||
if (FLAGS_SET(flags, RESOLVE_IFNAME_MAIN) && ifname_valid(name)) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r >= 0)
|
||||
return parse_newlink_message(reply, ret_name, ret_altnames);
|
||||
if (r != -ENODEV)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Next, try IFLA_ALT_IFNAME */
|
||||
if (FLAGS_SET(flags, RESOLVE_IFNAME_ALTERNATIVE) &&
|
||||
ifname_valid_full(name, IFNAME_VALID_ALTERNATIVE)) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_append_string(message, IFLA_ALT_IFNAME, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r >= 0)
|
||||
return parse_newlink_message(reply, ret_name, ret_altnames);
|
||||
/* The kernels older than 76c9ac0ee878f6693d398d3a95ccaf85e1f597a6 (v5.5) return -EINVAL. */
|
||||
if (!IN_SET(r, -ENODEV, -EINVAL))
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Finally, assume the string is a decimal formatted ifindex. */
|
||||
if (FLAGS_SET(flags, RESOLVE_IFNAME_NUMERIC)) {
|
||||
int ifindex;
|
||||
|
||||
ifindex = parse_ifindex(name);
|
||||
if (ifindex <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
return rtnl_get_ifname_full(rtnl, ifindex, ret_name, ret_altnames);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
|
||||
int r;
|
||||
@ -242,38 +390,6 @@ int rtnl_set_link_properties(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||
_cleanup_strv_free_ char **names = NULL;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(ifindex > 0);
|
||||
assert(ret);
|
||||
|
||||
if (!*rtnl) {
|
||||
r = sd_netlink_open(rtnl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_read_strv(reply, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names);
|
||||
if (r < 0 && r != -ENODATA)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtnl_update_link_alternative_names(
|
||||
sd_netlink **rtnl,
|
||||
uint16_t nlmsg_type,
|
||||
@ -374,92 +490,6 @@ int rtnl_set_link_alternative_names_by_ifname(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, char **ret) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL;
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
|
||||
int r, ifindex;
|
||||
|
||||
assert(name);
|
||||
|
||||
/* This returns ifindex and the main interface name. */
|
||||
|
||||
if (!ifname_valid_full(name, IFNAME_VALID_ALTERNATIVE))
|
||||
return -EINVAL;
|
||||
|
||||
if (!rtnl)
|
||||
rtnl = &our_rtnl;
|
||||
if (!*rtnl) {
|
||||
r = sd_netlink_open(rtnl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_append_string(message, IFLA_ALT_IFNAME, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r == -EINVAL)
|
||||
return -ENODEV; /* The device doesn't exist */
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(ifindex > 0);
|
||||
|
||||
if (ret) {
|
||||
r = sd_netlink_message_read_string_strdup(reply, IFLA_IFNAME, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return ifindex;
|
||||
}
|
||||
|
||||
int rtnl_resolve_ifname(sd_netlink **rtnl, const char *name) {
|
||||
int r;
|
||||
|
||||
/* Like if_nametoindex, but resolves "alternative names" too. */
|
||||
|
||||
assert(name);
|
||||
|
||||
r = if_nametoindex(name);
|
||||
if (r > 0)
|
||||
return r;
|
||||
|
||||
return rtnl_resolve_link_alternative_name(rtnl, name, NULL);
|
||||
}
|
||||
|
||||
int rtnl_resolve_interface(sd_netlink **rtnl, const char *name) {
|
||||
int r;
|
||||
|
||||
/* Like rtnl_resolve_ifname, but resolves interface numbers too. */
|
||||
|
||||
assert(name);
|
||||
|
||||
r = parse_ifindex(name);
|
||||
if (r > 0)
|
||||
return r;
|
||||
assert(r < 0);
|
||||
|
||||
return rtnl_resolve_ifname(rtnl, name);
|
||||
}
|
||||
|
||||
int rtnl_resolve_interface_or_warn(sd_netlink **rtnl, const char *name) {
|
||||
int r;
|
||||
|
||||
r = rtnl_resolve_interface(rtnl, name);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resolve interface \"%s\": %m", name);
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtnl_get_link_info(
|
||||
sd_netlink **rtnl,
|
||||
int ifindex,
|
||||
|
@ -19,6 +19,22 @@ typedef struct RouteVia {
|
||||
union in_addr_union address;
|
||||
} _packed_ RouteVia;
|
||||
|
||||
int rtnl_get_ifname_full(sd_netlink **rtnl, int ifindex, char **ret_name, char ***ret_altnames);
|
||||
|
||||
typedef enum ResolveInterfaceNameFlag {
|
||||
RESOLVE_IFNAME_MAIN = 1 << 0, /* resolve main interface name */
|
||||
RESOLVE_IFNAME_ALTERNATIVE = 1 << 1, /* resolve alternative name */
|
||||
RESOLVE_IFNAME_NUMERIC = 1 << 2, /* resolve decimal formatted ifindex */
|
||||
_RESOLVE_IFNAME_ALL = RESOLVE_IFNAME_MAIN | RESOLVE_IFNAME_ALTERNATIVE | RESOLVE_IFNAME_NUMERIC,
|
||||
} ResolveInterfaceNameFlag;
|
||||
|
||||
int rtnl_resolve_ifname_full(
|
||||
sd_netlink **rtnl,
|
||||
ResolveInterfaceNameFlag flags,
|
||||
const char *name,
|
||||
char **ret_name,
|
||||
char ***ret_altnames);
|
||||
|
||||
int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_name);
|
||||
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const* alternative_names);
|
||||
static inline int rtnl_append_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names) {
|
||||
@ -35,14 +51,32 @@ int rtnl_set_link_properties(
|
||||
uint32_t mtu,
|
||||
uint32_t gso_max_size,
|
||||
size_t gso_max_segments);
|
||||
int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret);
|
||||
static inline int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) {
|
||||
return rtnl_get_ifname_full(rtnl, ifindex, NULL, ret);
|
||||
}
|
||||
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names);
|
||||
int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char* const *alternative_names);
|
||||
int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names);
|
||||
int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, char **ret);
|
||||
int rtnl_resolve_ifname(sd_netlink **rtnl, const char *name);
|
||||
int rtnl_resolve_interface(sd_netlink **rtnl, const char *name);
|
||||
int rtnl_resolve_interface_or_warn(sd_netlink **rtnl, const char *name);
|
||||
static inline int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, char **ret) {
|
||||
return rtnl_resolve_ifname_full(rtnl, RESOLVE_IFNAME_ALTERNATIVE, name, ret, NULL);
|
||||
}
|
||||
static inline int rtnl_resolve_ifname(sd_netlink **rtnl, const char *name) {
|
||||
return rtnl_resolve_ifname_full(rtnl, RESOLVE_IFNAME_MAIN | RESOLVE_IFNAME_ALTERNATIVE, name, NULL, NULL);
|
||||
}
|
||||
static inline int rtnl_resolve_interface(sd_netlink **rtnl, const char *name) {
|
||||
return rtnl_resolve_ifname_full(rtnl, _RESOLVE_IFNAME_ALL, name, NULL, NULL);
|
||||
}
|
||||
static inline int rtnl_resolve_interface_or_warn(sd_netlink **rtnl, const char *name) {
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
|
||||
r = rtnl_resolve_interface(rtnl, name);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resolve interface \"%s\": %m", name);
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtnl_get_link_info(
|
||||
sd_netlink **rtnl,
|
||||
int ifindex,
|
||||
|
@ -512,6 +512,38 @@ int test_network_interfaces_initialized(char **iface_pairs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resolve_network_interface_names(char **iface_pairs) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
int r;
|
||||
|
||||
/* Due to a bug in kernel fixed by 8e15aee621618a3ee3abecaf1fd8c1428098b7ef (v6.6, backported to
|
||||
* 6.1.60 and 6.5.9), an interface with alternative names cannot be resolved by the alternative name
|
||||
* if the interface is moved to another network namespace. Hence, we need to adjust the provided
|
||||
* names before moving interfaces to container namespace. */
|
||||
|
||||
STRV_FOREACH_PAIR(from, to, iface_pairs) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
_cleanup_strv_free_ char **altnames = NULL;
|
||||
|
||||
r = rtnl_resolve_ifname_full(&rtnl, _RESOLVE_IFNAME_ALL, *from, &name, &altnames);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Always use the resolved name for 'from'. */
|
||||
free_and_replace(*from, name);
|
||||
|
||||
/* If the name 'to' is assigned as an alternative name, we cannot rename the interface.
|
||||
* Hence, use the assigned interface name (including the alternative names) as is, and
|
||||
* use the resolved name for 'to'. */
|
||||
if (strv_contains(altnames, *to)) {
|
||||
r = free_and_strdup_warn(to, *from);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netns_child_begin(int netns_fd, int *ret_original_netns_fd) {
|
||||
_cleanup_close_ int original_netns_fd = -EBADF;
|
||||
int r;
|
||||
@ -580,37 +612,6 @@ static int netns_fork_and_wait(int netns_fd, int *ret_original_netns_fd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int needs_rename(sd_netlink **rtnl, sd_device *dev, const char *name) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(dev);
|
||||
assert(name);
|
||||
|
||||
const char *ifname;
|
||||
r = sd_device_get_sysname(dev, &ifname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (streq(name, ifname))
|
||||
return false;
|
||||
|
||||
int ifindex;
|
||||
r = sd_device_get_ifindex(dev, &ifindex);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_strv_free_ char **altnames = NULL;
|
||||
r = rtnl_get_link_alternative_names(rtnl, ifindex, &altnames);
|
||||
if (r == -EOPNOTSUPP)
|
||||
return true; /* alternative interface name is not supported, hence the name is not
|
||||
* assigned to the interface. */
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return !strv_contains(altnames, name);
|
||||
}
|
||||
|
||||
static int move_wlan_interface_impl(sd_netlink **genl, int netns_fd, sd_device *dev) {
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *our_genl = NULL;
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
@ -666,12 +667,8 @@ static int move_wlan_interface_one(
|
||||
assert(temp_netns_fd);
|
||||
assert(netns_fd >= 0);
|
||||
assert(dev);
|
||||
assert(name);
|
||||
|
||||
r = needs_rename(rtnl, dev, name);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, r, "Failed to determine if the interface should be renamed to '%s': %m", name);
|
||||
if (r == 0)
|
||||
if (!name)
|
||||
return move_wlan_interface_impl(genl, netns_fd, dev);
|
||||
|
||||
/* The command NL80211_CMD_SET_WIPHY_NETNS takes phy instead of network interface, and does not take
|
||||
@ -728,7 +725,6 @@ static int move_network_interface_one(sd_netlink **rtnl, int netns_fd, sd_device
|
||||
assert(rtnl);
|
||||
assert(netns_fd >= 0);
|
||||
assert(dev);
|
||||
assert(name);
|
||||
|
||||
if (!*rtnl) {
|
||||
r = sd_netlink_open(rtnl);
|
||||
@ -749,10 +745,7 @@ static int move_network_interface_one(sd_netlink **rtnl, int netns_fd, sd_device
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, r, "Failed to append namespace fd to netlink message: %m");
|
||||
|
||||
r = needs_rename(rtnl, dev, name);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, r, "Failed to determine if the interface should be renamed to '%s': %m", name);
|
||||
if (r > 0) {
|
||||
if (name) {
|
||||
r = sd_netlink_message_append_string(m, IFLA_IFNAME, name);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, r, "Failed to add netlink interface name: %m");
|
||||
@ -777,15 +770,18 @@ int move_network_interfaces(int netns_fd, char **iface_pairs) {
|
||||
|
||||
STRV_FOREACH_PAIR(from, to, iface_pairs) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||
const char *name;
|
||||
|
||||
name = streq(*from, *to) ? NULL : *to;
|
||||
|
||||
r = sd_device_new_from_ifname(&dev, *from);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Unknown interface name %s: %m", *from);
|
||||
|
||||
if (device_is_devtype(dev, "wlan"))
|
||||
r = move_wlan_interface_one(&rtnl, &genl, &temp_netns_fd, netns_fd, dev, *to);
|
||||
r = move_wlan_interface_one(&rtnl, &genl, &temp_netns_fd, netns_fd, dev, name);
|
||||
else
|
||||
r = move_network_interface_one(&rtnl, netns_fd, dev, *to);
|
||||
r = move_network_interface_one(&rtnl, netns_fd, dev, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ether-addr-util.h"
|
||||
|
||||
int test_network_interfaces_initialized(char **iface_pairs);
|
||||
int resolve_network_interface_names(char **iface_pairs);
|
||||
|
||||
int setup_veth(const char *machine_name, pid_t pid, char iface_name[IFNAMSIZ], bool bridge, const struct ether_addr *provided_mac);
|
||||
int setup_veth_extra(const char *machine_name, pid_t pid, char **pairs);
|
||||
|
@ -5625,6 +5625,10 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = resolve_network_interface_names(arg_network_interfaces);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = verify_network_interfaces_initialized();
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
@ -248,9 +248,9 @@ TEST(in_addr_ifindex_to_string) {
|
||||
test_in_addr_ifindex_to_string_one(AF_INET, "10.11.12.13", 9, "10.11.12.13");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 10, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "::1", 11, "::1");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::", 12, "fe80::%12");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::", LOOPBACK_IFINDEX, "fe80::%1");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::", 0, "fe80::");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::14", 12, "fe80::14%12");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::14", 0, "fe80::14");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::15", -7, "fe80::15");
|
||||
test_in_addr_ifindex_to_string_one(AF_INET6, "fe80::16", LOOPBACK_IFINDEX, "fe80::16%1");
|
||||
}
|
||||
@ -265,9 +265,9 @@ TEST(in_addr_ifindex_from_string_auto) {
|
||||
assert_se(family == AF_INET6);
|
||||
assert_se(ifindex == 0);
|
||||
|
||||
assert_se(in_addr_ifindex_from_string_auto("fe80::18%19", &family, &ua, &ifindex) >= 0);
|
||||
assert_se(in_addr_ifindex_from_string_auto("fe80::18%1", &family, &ua, &ifindex) >= 0);
|
||||
assert_se(family == AF_INET6);
|
||||
assert_se(ifindex == 19);
|
||||
assert_se(ifindex == 1);
|
||||
|
||||
assert_se(in_addr_ifindex_from_string_auto("fe80::18%lo", &family, &ua, &ifindex) >= 0);
|
||||
assert_se(family == AF_INET6);
|
||||
@ -288,8 +288,8 @@ static void test_in_addr_ifindex_name_from_string_auto_one(const char *a, const
|
||||
TEST(in_addr_ifindex_name_from_string_auto) {
|
||||
test_in_addr_ifindex_name_from_string_auto_one("192.168.0.1", NULL);
|
||||
test_in_addr_ifindex_name_from_string_auto_one("192.168.0.1#test.com", "test.com");
|
||||
test_in_addr_ifindex_name_from_string_auto_one("fe80::18%19", NULL);
|
||||
test_in_addr_ifindex_name_from_string_auto_one("fe80::18%19#another.test.com", "another.test.com");
|
||||
test_in_addr_ifindex_name_from_string_auto_one("fe80::18%1", NULL);
|
||||
test_in_addr_ifindex_name_from_string_auto_one("fe80::18%1#another.test.com", "another.test.com");
|
||||
}
|
||||
|
||||
static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str, int family, uint16_t port, int ifindex,
|
||||
@ -356,15 +356,15 @@ TEST(in_addr_port_ifindex_name_from_string_auto) {
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53#example.com", AF_INET, 53, 0, "example.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18", AF_INET6, 0, 0, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18#hoge.com", AF_INET6, 0, 0, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19", AF_INET6, 0, 19, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%1", AF_INET6, 0, 1, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%lo", AF_INET6, 0, 1, NULL, "fe80::18%1");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53", AF_INET6, 53, 0, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%1", AF_INET6, 53, 1, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo", AF_INET6, 53, 1, NULL, "[fe80::18]:53%1");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19#hoge.com", AF_INET6, 0, 19, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%1#hoge.com", AF_INET6, 0, 1, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53#hoge.com", AF_INET6, 53, 0, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19#hoge.com", AF_INET6, 53, 19, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%1", AF_INET6, 53, 1, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%1#hoge.com", AF_INET6, 53, 1, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo", AF_INET6, 53, 1, NULL, "[fe80::18]:53%1");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo#hoge.com", AF_INET6, 53, 1, "hoge.com", "[fe80::18]:53%1#hoge.com");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user