mirror of
https://github.com/systemd/systemd.git
synced 2025-02-01 09:47:35 +03:00
Compare commits
10 Commits
016fa04943
...
3b225d351a
Author | SHA1 | Date | |
---|---|---|---|
|
3b225d351a | ||
|
7010e03c7b | ||
|
ee70a3d458 | ||
|
315363c2c3 | ||
|
cc3592f055 | ||
|
0cd35fdce5 | ||
|
7e02637a77 | ||
|
0f59519bc2 | ||
|
23851db5c0 | ||
|
708aeff369 |
@ -72,4 +72,5 @@ const NetDevVTable bare_udp_vtable = {
|
||||
.fill_message_create = netdev_bare_udp_fill_message_create,
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.iftype = ARPHRD_NONE,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
@ -56,13 +56,23 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_arp_all_targets, bond_arp_all_targets
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_primary_reselect, bond_primary_reselect, BondPrimaryReselect);
|
||||
|
||||
static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
|
||||
assert(!link);
|
||||
assert(m);
|
||||
|
||||
Bond *b = BOND(netdev);
|
||||
int r;
|
||||
|
||||
if (b->mode != _NETDEV_BOND_MODE_INVALID) {
|
||||
assert(netdev->manager);
|
||||
assert(!link);
|
||||
assert(m);
|
||||
|
||||
if (netdev->ifindex > 0) {
|
||||
r = link_get_by_index(netdev->manager, netdev->ifindex, &link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
bool up = link && FLAGS_SET(link->flags, IFF_UP);
|
||||
bool has_slaves = link && !set_isempty(link->slaves);
|
||||
|
||||
if (b->mode != _NETDEV_BOND_MODE_INVALID && !up && !has_slaves) {
|
||||
r = sd_netlink_message_append_u8(m, IFLA_BOND_MODE, b->mode);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -75,7 +85,8 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin
|
||||
}
|
||||
|
||||
if (b->lacp_rate != _NETDEV_BOND_LACP_RATE_INVALID &&
|
||||
b->mode == NETDEV_BOND_MODE_802_3AD) {
|
||||
b->mode == NETDEV_BOND_MODE_802_3AD &&
|
||||
!up) {
|
||||
r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_LACP_RATE, b->lacp_rate);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -119,14 +130,16 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin
|
||||
}
|
||||
|
||||
if (b->ad_select != _NETDEV_BOND_AD_SELECT_INVALID &&
|
||||
b->mode == NETDEV_BOND_MODE_802_3AD) {
|
||||
b->mode == NETDEV_BOND_MODE_802_3AD &&
|
||||
!up) {
|
||||
r = sd_netlink_message_append_u8(m, IFLA_BOND_AD_SELECT, b->ad_select);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (b->fail_over_mac != _NETDEV_BOND_FAIL_OVER_MAC_INVALID &&
|
||||
b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP) {
|
||||
b->mode == NETDEV_BOND_MODE_ACTIVE_BACKUP &&
|
||||
!has_slaves) {
|
||||
r = sd_netlink_message_append_u8(m, IFLA_BOND_FAIL_OVER_MAC, b->fail_over_mac);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -181,7 +194,7 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin
|
||||
return r;
|
||||
}
|
||||
|
||||
if (b->ad_user_port_key != 0) {
|
||||
if (b->ad_user_port_key != 0 && !up) {
|
||||
r = sd_netlink_message_append_u16(m, IFLA_BOND_AD_USER_PORT_KEY, b->ad_user_port_key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -197,7 +210,7 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (b->tlb_dynamic_lb >= 0) {
|
||||
if (b->tlb_dynamic_lb >= 0 && !up) {
|
||||
r = sd_netlink_message_append_u8(m, IFLA_BOND_TLB_DYNAMIC_LB, b->tlb_dynamic_lb);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -281,12 +281,17 @@ static void bridge_init(NetDev *netdev) {
|
||||
b->ageing_time = USEC_INFINITY;
|
||||
}
|
||||
|
||||
static bool bridge_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetDevVTable bridge_vtable = {
|
||||
.object_size = sizeof(Bridge),
|
||||
.init = bridge_init,
|
||||
.sections = NETDEV_COMMON_SECTIONS "Bridge\0",
|
||||
.post_create = netdev_bridge_post_create,
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.can_set_mac = bridge_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
|
@ -4,10 +4,15 @@
|
||||
|
||||
#include "dummy.h"
|
||||
|
||||
static bool dummy_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetDevVTable dummy_vtable = {
|
||||
.object_size = sizeof(Dummy),
|
||||
.sections = NETDEV_COMMON_SECTIONS,
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.can_set_mac = dummy_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
|
@ -254,6 +254,10 @@ static int netdev_geneve_verify(NetDev *netdev, const char *filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool geneve_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void geneve_init(NetDev *netdev) {
|
||||
Geneve *v = GENEVE(netdev);
|
||||
|
||||
@ -272,6 +276,7 @@ const NetDevVTable geneve_vtable = {
|
||||
.fill_message_create = netdev_geneve_fill_message_create,
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.config_verify = netdev_geneve_verify,
|
||||
.can_set_mac = geneve_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
|
@ -60,6 +60,7 @@ const NetDevVTable ipvlan_vtable = {
|
||||
.can_set_mac = ipvlan_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
||||
const NetDevVTable ipvtap_vtable = {
|
||||
@ -71,6 +72,7 @@ const NetDevVTable ipvtap_vtable = {
|
||||
.can_set_mac = ipvlan_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
||||
IPVlanMode link_get_ipvlan_mode(Link *link) {
|
||||
|
@ -178,6 +178,7 @@ const NetDevVTable macvtap_vtable = {
|
||||
.create_type = NETDEV_CREATE_STACKED,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
||||
const NetDevVTable macvlan_vtable = {
|
||||
@ -189,4 +190,5 @@ const NetDevVTable macvlan_vtable = {
|
||||
.create_type = NETDEV_CREATE_STACKED,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
@ -400,7 +400,7 @@ int netdev_enter_ready(NetDev *netdev) {
|
||||
assert(netdev);
|
||||
assert(netdev->ifname);
|
||||
|
||||
if (netdev->state != NETDEV_STATE_CREATING)
|
||||
if (!IN_SET(netdev->state, NETDEV_STATE_LOADING, NETDEV_STATE_CREATING))
|
||||
return 0;
|
||||
|
||||
netdev->state = NETDEV_STATE_READY;
|
||||
@ -432,18 +432,17 @@ static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev
|
||||
assert(netdev->state != _NETDEV_STATE_INVALID);
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r == -EEXIST)
|
||||
log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
|
||||
else if (r < 0) {
|
||||
log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
|
||||
if (r >= 0)
|
||||
log_netdev_debug(netdev, "Created.");
|
||||
else if (r == -EEXIST && netdev->ifindex > 0)
|
||||
log_netdev_debug(netdev, "Already exists.");
|
||||
else {
|
||||
log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_netdev_debug(netdev, "Created");
|
||||
|
||||
return 1;
|
||||
return netdev_enter_ready(netdev);
|
||||
}
|
||||
|
||||
int netdev_set_ifindex_internal(NetDev *netdev, int ifindex) {
|
||||
@ -464,8 +463,6 @@ int netdev_set_ifindex_internal(NetDev *netdev, int ifindex) {
|
||||
}
|
||||
|
||||
static int netdev_set_ifindex_impl(NetDev *netdev, const char *name, int ifindex) {
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
assert(name);
|
||||
assert(ifindex > 0);
|
||||
@ -478,11 +475,7 @@ static int netdev_set_ifindex_impl(NetDev *netdev, const char *name, int ifindex
|
||||
"Received netlink message with unexpected interface name %s (ifindex=%i).",
|
||||
name, ifindex);
|
||||
|
||||
r = netdev_set_ifindex_internal(netdev, ifindex);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
return netdev_enter_ready(netdev);
|
||||
return netdev_set_ifindex_internal(netdev, ifindex);
|
||||
}
|
||||
|
||||
int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *message) {
|
||||
@ -636,15 +629,35 @@ finalize:
|
||||
|
||||
static bool netdev_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
assert(netdev);
|
||||
assert(netdev->manager);
|
||||
assert(hw_addr);
|
||||
|
||||
if (hw_addr->length <= 0)
|
||||
return false;
|
||||
|
||||
if (!NETDEV_VTABLE(netdev)->can_set_mac)
|
||||
if (NETDEV_VTABLE(netdev)->can_set_mac)
|
||||
return NETDEV_VTABLE(netdev)->can_set_mac(netdev, hw_addr);
|
||||
|
||||
/* Default action: refuse to set MAC address when the netdev already exists and is running.
|
||||
* See eth_prepare_mac_addr_change(), which is called by eth_mac_addr().
|
||||
* Before ad72c4a06acc6762e84994ac2f722da7a07df34e and 0ec92a8f56ff07237dbe8af7c7a72aba7f957baf
|
||||
* (both in v6.5), the kernel refuse to set MAC address for existing netdevs even if it is unchanged.
|
||||
* Note, netdev kind with IFF_LIVE_ADDR_CHANGE can change MAC address even if it is already up.
|
||||
* For such netdev kind, we should introduce can_set_mac(), and allow to set MAC address. */
|
||||
Link *link;
|
||||
if (link_get_by_index(netdev->manager, netdev->ifindex, &link) < 0)
|
||||
return true;
|
||||
|
||||
return NETDEV_VTABLE(netdev)->can_set_mac(netdev, hw_addr);
|
||||
/* The result of netif_running() is mapped to operstate and flags.
|
||||
* See rtnl_fill_ifinfo() and dev_get_flags(). */
|
||||
if (link->kernel_operstate != IF_OPER_DOWN ||
|
||||
(link->flags & (IFF_RUNNING | IFF_LOWER_UP | IFF_DORMANT)) != 0)
|
||||
return false;
|
||||
|
||||
if (hw_addr_equal(&link->hw_addr, hw_addr))
|
||||
return false; /* Unchanged, not necessary to set. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool netdev_can_set_mtu(NetDev *netdev, uint32_t mtu) {
|
||||
@ -662,9 +675,14 @@ static bool netdev_can_set_mtu(NetDev *netdev, uint32_t mtu) {
|
||||
static int netdev_create_message(NetDev *netdev, Link *link, sd_netlink_message *m) {
|
||||
int r;
|
||||
|
||||
r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (netdev->ifindex <= 0) {
|
||||
/* Set interface name when it is newly created. Otherwise, the kernel older than
|
||||
* bd039b5ea2a91ea707ee8539df26456bd5be80af (v6.2) will refuse the netlink message even if
|
||||
* the name is unchanged. */
|
||||
r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
struct hw_addr_data hw_addr;
|
||||
r = netdev_generate_hw_addr(netdev, link, netdev->ifname, &netdev->hw_addr, &hw_addr);
|
||||
@ -827,7 +845,16 @@ static int stacked_netdev_process_request(Request *req, Link *link, void *userda
|
||||
assert(link);
|
||||
|
||||
if (!netdev_is_managed(netdev))
|
||||
return 1; /* Already detached, due to e.g. reloading .netdev files, cancelling the request. */
|
||||
goto cancelled; /* Already detached, due to e.g. reloading .netdev files, cancelling the request. */
|
||||
|
||||
if (NETDEV_VTABLE(netdev)->keep_existing && netdev->ifindex > 0) {
|
||||
/* Already exists, and the netdev does not support updating, entering the ready state. */
|
||||
r = netdev_enter_ready(netdev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
goto cancelled;
|
||||
}
|
||||
|
||||
r = netdev_is_ready_to_create(netdev, link);
|
||||
if (r <= 0)
|
||||
@ -838,21 +865,41 @@ static int stacked_netdev_process_request(Request *req, Link *link, void *userda
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
|
||||
|
||||
return 1;
|
||||
|
||||
cancelled:
|
||||
assert_se(TAKE_PTR(req->counter) == &link->create_stacked_netdev_messages);
|
||||
link->create_stacked_netdev_messages--;
|
||||
|
||||
if (link->create_stacked_netdev_messages == 0) {
|
||||
link->stacked_netdevs_created = true;
|
||||
log_link_debug(link, "Stacked netdevs created.");
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
|
||||
NetDev *netdev = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not create stacked netdev");
|
||||
if (r >= 0)
|
||||
log_netdev_debug(netdev, "Created.");
|
||||
else if (r == -EEXIST && netdev->ifindex > 0)
|
||||
log_netdev_debug(netdev, "Already exists.");
|
||||
else {
|
||||
log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
|
||||
netdev_enter_failed(netdev);
|
||||
link_enter_failed(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) netdev_enter_ready(netdev);
|
||||
|
||||
if (link->create_stacked_netdev_messages == 0) {
|
||||
link->stacked_netdevs_created = true;
|
||||
log_link_debug(link, "Stacked netdevs created.");
|
||||
@ -901,6 +948,15 @@ static int independent_netdev_process_request(Request *req, Link *link, void *us
|
||||
if (!netdev_is_managed(netdev))
|
||||
return 1; /* Already detached, due to e.g. reloading .netdev files, cancelling the request. */
|
||||
|
||||
if (NETDEV_VTABLE(netdev)->keep_existing && netdev->ifindex > 0) {
|
||||
/* Already exists, and the netdev does not support updating, entering the ready state. */
|
||||
r = netdev_enter_ready(netdev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 1; /* Skip this request. */
|
||||
}
|
||||
|
||||
r = netdev_is_ready_to_create(netdev, NULL);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
@ -930,21 +986,9 @@ static int netdev_request_to_create(NetDev *netdev) {
|
||||
if (netdev->state != NETDEV_STATE_LOADING)
|
||||
return 0; /* Already configured (at least tried previously). Not necessary to reconfigure. */
|
||||
|
||||
r = netdev_is_ready_to_create(netdev, NULL);
|
||||
r = netdev_queue_request(netdev, independent_netdev_process_request, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
/* If the netdev has no dependency, then create it now. */
|
||||
r = independent_netdev_create(netdev);
|
||||
if (r < 0)
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
|
||||
|
||||
} else {
|
||||
/* Otherwise, wait for the dependencies being resolved. */
|
||||
r = netdev_queue_request(netdev, independent_netdev_process_request, NULL);
|
||||
if (r < 0)
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to request to create netdev: %m");
|
||||
}
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to request to create netdev: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -199,6 +199,10 @@ typedef struct NetDevVTable {
|
||||
|
||||
/* When assigning ifindex to the netdev, skip to check if the netdev kind matches. */
|
||||
bool skip_netdev_kind_check;
|
||||
|
||||
/* Provides if the netdev can be updated, that is, whether RTM_NEWLINK with existing ifindex is supported or not.
|
||||
* If this is true, the netdev does not support updating. */
|
||||
bool keep_existing;
|
||||
} NetDevVTable;
|
||||
|
||||
extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
|
||||
|
@ -4,10 +4,15 @@
|
||||
|
||||
#include "netdevsim.h"
|
||||
|
||||
static bool netdevsim_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetDevVTable netdevsim_vtable = {
|
||||
.object_size = sizeof(NetDevSim),
|
||||
.sections = NETDEV_COMMON_SECTIONS,
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.can_set_mac = netdevsim_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
|
@ -1119,6 +1119,11 @@ static void netdev_tunnel_init(NetDev *netdev) {
|
||||
t->ttl = DEFAULT_IPV6_TTL;
|
||||
}
|
||||
|
||||
static bool tunnel_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
assert(IN_SET(netdev->kind, NETDEV_KIND_GRETAP, NETDEV_KIND_IP6GRETAP, NETDEV_KIND_ERSPAN));
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetDevVTable ipip_vtable = {
|
||||
.object_size = sizeof(Tunnel),
|
||||
.init = netdev_tunnel_init,
|
||||
@ -1188,6 +1193,7 @@ const NetDevVTable gretap_vtable = {
|
||||
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
|
||||
.config_verify = netdev_tunnel_verify,
|
||||
.needs_reconfigure = tunnel_needs_reconfigure,
|
||||
.can_set_mac = tunnel_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
@ -1213,6 +1219,7 @@ const NetDevVTable ip6gretap_vtable = {
|
||||
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
|
||||
.config_verify = netdev_tunnel_verify,
|
||||
.needs_reconfigure = tunnel_needs_reconfigure,
|
||||
.can_set_mac = tunnel_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
@ -1238,6 +1245,7 @@ const NetDevVTable erspan_vtable = {
|
||||
.is_ready_to_create = netdev_tunnel_is_ready_to_create,
|
||||
.config_verify = netdev_tunnel_verify,
|
||||
.needs_reconfigure = tunnel_needs_reconfigure,
|
||||
.can_set_mac = tunnel_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
};
|
||||
|
@ -36,15 +36,33 @@ static TunTap* TUNTAP(NetDev *netdev) {
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_FULL(named_fd_hash_ops, char, string_hash_func, string_compare_func, free, void, close_fd_ptr);
|
||||
|
||||
int manager_add_tuntap_fd(Manager *m, int fd, const char *name) {
|
||||
static int manager_add_tuntap_fd_impl(Manager *m, int fd, const char *name) {
|
||||
_cleanup_free_ char *tuntap_name = NULL;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(fd >= 0);
|
||||
assert(name);
|
||||
|
||||
tuntap_name = strdup(name);
|
||||
if (!tuntap_name)
|
||||
return log_oom_debug();
|
||||
|
||||
r = hashmap_ensure_put(&m->tuntap_fds_by_name, &named_fd_hash_ops, tuntap_name, FD_TO_PTR(fd));
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to store tuntap fd: %m");
|
||||
|
||||
TAKE_PTR(tuntap_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_add_tuntap_fd(Manager *m, int fd, const char *name) {
|
||||
const char *p;
|
||||
|
||||
assert(m);
|
||||
assert(fd >= 0);
|
||||
assert(name);
|
||||
|
||||
p = startswith(name, "tuntap-");
|
||||
if (!p)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Received unknown fd (%s).", name);
|
||||
@ -52,66 +70,76 @@ int manager_add_tuntap_fd(Manager *m, int fd, const char *name) {
|
||||
if (!ifname_valid(p))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Received tuntap fd with invalid name (%s).", p);
|
||||
|
||||
tuntap_name = strdup(p);
|
||||
if (!tuntap_name)
|
||||
return log_oom_debug();
|
||||
return manager_add_tuntap_fd_impl(m, fd, p);
|
||||
}
|
||||
|
||||
r = hashmap_ensure_put(&m->tuntap_fds_by_name, &named_fd_hash_ops, tuntap_name, FD_TO_PTR(fd));
|
||||
static int netdev_take_tuntap_fd(Manager *m, const char *ifname) {
|
||||
_unused_ _cleanup_free_ char *name = NULL;
|
||||
void *p;
|
||||
|
||||
assert(m);
|
||||
assert(ifname);
|
||||
|
||||
p = hashmap_remove2(m->tuntap_fds_by_name, ifname, (void**) &name);
|
||||
if (!p)
|
||||
return -EBADF;
|
||||
|
||||
return PTR_TO_FD(p);
|
||||
}
|
||||
|
||||
static int netdev_push_tuntap_fd(NetDev *netdev, int fd) {
|
||||
_unused_ _cleanup_close_ int fd_old = -EBADF;
|
||||
int r;
|
||||
|
||||
assert(netdev->manager);
|
||||
|
||||
fd_old = netdev_take_tuntap_fd(netdev->manager, netdev->ifname);
|
||||
|
||||
if (!TUNTAP(netdev)->keep_fd)
|
||||
return 0;
|
||||
|
||||
r = manager_add_tuntap_fd_impl(netdev->manager, fd, netdev->ifname);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to store tuntap fd: %m");
|
||||
return r;
|
||||
|
||||
TAKE_PTR(tuntap_name);
|
||||
return 0;
|
||||
(void) notify_push_fdf(fd, "tuntap-%s", netdev->ifname);
|
||||
return 1; /* saved */
|
||||
}
|
||||
|
||||
static void manager_close_and_notify_tuntap_fd(Manager *m, const char *ifname) {
|
||||
assert(m);
|
||||
assert(ifname);
|
||||
|
||||
/* netdev_take_tuntap_fd() may invalidate ifname. Hence, need to create fdname earlier. */
|
||||
const char *fdname = strjoina("tuntap-", ifname);
|
||||
close_and_notify_warn(netdev_take_tuntap_fd(m, ifname), fdname);
|
||||
}
|
||||
|
||||
void manager_clear_unmanaged_tuntap_fds(Manager *m) {
|
||||
char *name;
|
||||
const char *name;
|
||||
void *p;
|
||||
|
||||
assert(m);
|
||||
|
||||
while ((p = hashmap_steal_first_key_and_value(m->tuntap_fds_by_name, (void**) &name))) {
|
||||
close_and_notify_warn(PTR_TO_FD(p), name);
|
||||
name = mfree(name);
|
||||
HASHMAP_FOREACH_KEY(p, name, m->tuntap_fds_by_name) {
|
||||
NetDev *netdev;
|
||||
|
||||
if (netdev_get(m, name, &netdev) < 0 ||
|
||||
!IN_SET(netdev->kind, NETDEV_KIND_TAP, NETDEV_KIND_TUN) ||
|
||||
!TUNTAP(netdev)->keep_fd)
|
||||
manager_close_and_notify_tuntap_fd(m, name);
|
||||
}
|
||||
}
|
||||
|
||||
static int tuntap_take_fd(NetDev *netdev) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
void *p;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
assert(netdev->manager);
|
||||
|
||||
r = link_get_by_name(netdev->manager, netdev->ifname, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = hashmap_remove2(netdev->manager->tuntap_fds_by_name, netdev->ifname, (void**) &name);
|
||||
if (!p)
|
||||
return -ENOENT;
|
||||
|
||||
log_netdev_debug(netdev, "Found file descriptor in fd store.");
|
||||
return PTR_TO_FD(p);
|
||||
}
|
||||
|
||||
static int netdev_create_tuntap(NetDev *netdev) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
struct ifreq ifr = {};
|
||||
TunTap *t;
|
||||
TunTap *t = TUNTAP(netdev);
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
assert(netdev->manager);
|
||||
t = TUNTAP(netdev);
|
||||
assert(t);
|
||||
|
||||
fd = TAKE_FD(t->fd);
|
||||
if (fd < 0)
|
||||
fd = tuntap_take_fd(netdev);
|
||||
if (fd < 0)
|
||||
fd = open(TUN_DEV, O_RDWR|O_CLOEXEC);
|
||||
fd = open(TUN_DEV, O_RDWR|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return log_netdev_error_errno(netdev, errno, "Failed to open " TUN_DEV ": %m");
|
||||
|
||||
@ -175,42 +203,25 @@ static int netdev_create_tuntap(NetDev *netdev) {
|
||||
if (ioctl(fd, TUNSETPERSIST, 1) < 0)
|
||||
return log_netdev_error_errno(netdev, errno, "TUNSETPERSIST failed: %m");
|
||||
|
||||
if (t->keep_fd) {
|
||||
t->fd = TAKE_FD(fd);
|
||||
(void) notify_push_fdf(t->fd, "tuntap-%s", netdev->ifname);
|
||||
}
|
||||
r = netdev_push_tuntap_fd(netdev, fd);
|
||||
if (r < 0)
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to save TUN/TAP fd: %m");
|
||||
if (r > 0)
|
||||
TAKE_FD(fd);
|
||||
|
||||
netdev_enter_ready(netdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tuntap_init(NetDev *netdev) {
|
||||
TunTap *t;
|
||||
|
||||
assert(netdev);
|
||||
t = TUNTAP(netdev);
|
||||
assert(t);
|
||||
|
||||
t->fd = -EBADF;
|
||||
}
|
||||
|
||||
static void tuntap_drop(NetDev *netdev) {
|
||||
TunTap *t;
|
||||
|
||||
assert(netdev);
|
||||
t = TUNTAP(netdev);
|
||||
assert(t);
|
||||
|
||||
t->fd = close_and_notify_warn(t->fd, netdev->ifname);
|
||||
manager_close_and_notify_tuntap_fd(netdev->manager, netdev->ifname);
|
||||
}
|
||||
|
||||
static void tuntap_done(NetDev *netdev) {
|
||||
TunTap *t;
|
||||
TunTap *t = TUNTAP(netdev);
|
||||
|
||||
assert(netdev);
|
||||
t = TUNTAP(netdev);
|
||||
assert(t);
|
||||
|
||||
t->fd = safe_close(t->fd);
|
||||
t->user_name = mfree(t->user_name);
|
||||
t->group_name = mfree(t->group_name);
|
||||
}
|
||||
@ -237,7 +248,6 @@ const NetDevVTable tun_vtable = {
|
||||
.object_size = sizeof(TunTap),
|
||||
.sections = NETDEV_COMMON_SECTIONS "Tun\0",
|
||||
.config_verify = tuntap_verify,
|
||||
.init = tuntap_init,
|
||||
.drop = tuntap_drop,
|
||||
.done = tuntap_done,
|
||||
.create = netdev_create_tuntap,
|
||||
@ -249,7 +259,6 @@ const NetDevVTable tap_vtable = {
|
||||
.object_size = sizeof(TunTap),
|
||||
.sections = NETDEV_COMMON_SECTIONS "Tap\0",
|
||||
.config_verify = tuntap_verify,
|
||||
.init = tuntap_init,
|
||||
.drop = tuntap_drop,
|
||||
.done = tuntap_done,
|
||||
.create = netdev_create_tuntap,
|
||||
|
@ -8,7 +8,6 @@ typedef struct TunTap TunTap;
|
||||
struct TunTap {
|
||||
NetDev meta;
|
||||
|
||||
int fd;
|
||||
char *user_name;
|
||||
char *group_name;
|
||||
bool multi_queue;
|
||||
|
@ -150,4 +150,5 @@ const NetDevVTable veth_vtable = {
|
||||
.get_ifindex = netdev_veth_get_ifindex,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
@ -21,11 +21,17 @@ static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool vrf_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const NetDevVTable vrf_vtable = {
|
||||
.object_size = sizeof(Vrf),
|
||||
.sections = NETDEV_COMMON_SECTIONS "VRF\0",
|
||||
.fill_message_create = netdev_vrf_fill_message_create,
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.can_set_mac = vrf_can_set_mac,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
.generate_mac = true,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
@ -124,4 +124,5 @@ const NetDevVTable vxcan_vtable = {
|
||||
.set_ifindex = netdev_vxcan_set_ifindex,
|
||||
.get_ifindex = netdev_vxcan_get_ifindex,
|
||||
.iftype = ARPHRD_CAN,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
@ -197,6 +197,10 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool vxlan_can_set_mac(NetDev *netdev, const struct hw_addr_data *hw_addr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vxlan_can_set_mtu(NetDev *netdev, uint32_t mtu) {
|
||||
assert(netdev);
|
||||
|
||||
@ -452,6 +456,7 @@ const NetDevVTable vxlan_vtable = {
|
||||
.create_type = NETDEV_CREATE_STACKED,
|
||||
.is_ready_to_create = netdev_vxlan_is_ready_to_create,
|
||||
.config_verify = netdev_vxlan_verify,
|
||||
.can_set_mac = vxlan_can_set_mac,
|
||||
.can_set_mtu = vxlan_can_set_mtu,
|
||||
.needs_reconfigure = vxlan_needs_reconfigure,
|
||||
.iftype = ARPHRD_ETHER,
|
||||
|
@ -1265,4 +1265,5 @@ const NetDevVTable wireguard_vtable = {
|
||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||
.config_verify = wireguard_verify,
|
||||
.iftype = ARPHRD_NONE,
|
||||
.keep_existing = true,
|
||||
};
|
||||
|
@ -193,6 +193,27 @@ class NetworkdTestingUtilities:
|
||||
class BridgeTest(NetworkdTestingUtilities, unittest.TestCase):
|
||||
"""Provide common methods for testing networkd against servers."""
|
||||
|
||||
def wait_online(self):
|
||||
try:
|
||||
subprocess.check_call([NETWORKD_WAIT_ONLINE, '--interface', 'port1', '--interface', 'port2', '--timeout=10'])
|
||||
except (AssertionError, subprocess.CalledProcessError):
|
||||
# show networkd status, journal, and DHCP server log on failure
|
||||
print('---- interface status ----')
|
||||
sys.stdout.flush()
|
||||
subprocess.call(['ip', 'a', 'show', 'dev', 'mybridge'])
|
||||
subprocess.call(['ip', 'a', 'show', 'dev', 'port1'])
|
||||
subprocess.call(['ip', 'a', 'show', 'dev', 'port2'])
|
||||
print('---- networkctl status ----')
|
||||
sys.stdout.flush()
|
||||
rc = subprocess.call(['networkctl', '-n', '0', 'status', 'mybridge', 'port1', 'port2'])
|
||||
if rc != 0:
|
||||
print(f"'networkctl status' exited with an unexpected code {rc}")
|
||||
print('---- journal ----')
|
||||
subprocess.check_output(['journalctl', '--sync'])
|
||||
sys.stdout.flush()
|
||||
subprocess.call(['journalctl', '-b', '--no-pager', '--quiet', '-I', '-u', 'systemd-networkd.service'])
|
||||
raise
|
||||
|
||||
def setUp(self):
|
||||
self.write_network('50-port1.netdev', '''\
|
||||
[NetDev]
|
||||
@ -233,6 +254,7 @@ Gateway=192.168.250.1
|
||||
''')
|
||||
subprocess.call(['systemctl', 'reset-failed', 'systemd-networkd', 'systemd-resolved'])
|
||||
subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
|
||||
self.wait_online()
|
||||
|
||||
def tearDown(self):
|
||||
subprocess.check_call(['systemctl', 'stop', 'systemd-networkd.socket'])
|
||||
@ -255,8 +277,7 @@ Priority=28
|
||||
''')
|
||||
subprocess.check_call(['ip', 'link', 'set', 'dev', 'port1', 'down'])
|
||||
subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
|
||||
subprocess.check_call([NETWORKD_WAIT_ONLINE, '--interface',
|
||||
'port1', '--timeout=5'])
|
||||
self.wait_online()
|
||||
self.assertEqual(self.read_attr('port1', 'brport/priority'), '28')
|
||||
|
||||
def test_bridge_port_priority_set_zero(self):
|
||||
@ -268,8 +289,7 @@ Priority=0
|
||||
''')
|
||||
subprocess.check_call(['ip', 'link', 'set', 'dev', 'port2', 'down'])
|
||||
subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
|
||||
subprocess.check_call([NETWORKD_WAIT_ONLINE, '--interface',
|
||||
'port2', '--timeout=5'])
|
||||
self.wait_online()
|
||||
self.assertEqual(self.read_attr('port2', 'brport/priority'), '0')
|
||||
|
||||
def test_bridge_port_property(self):
|
||||
@ -288,8 +308,7 @@ Priority=23
|
||||
''')
|
||||
subprocess.check_call(['ip', 'link', 'set', 'dev', 'port2', 'down'])
|
||||
subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
|
||||
subprocess.check_call([NETWORKD_WAIT_ONLINE, '--interface',
|
||||
'port2', '--timeout=5'])
|
||||
self.wait_online()
|
||||
|
||||
self.assertEqual(self.read_attr('port2', 'brport/priority'), '23')
|
||||
self.assertEqual(self.read_attr('port2', 'brport/hairpin_mode'), '1')
|
||||
|
@ -1628,6 +1628,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, 'ethertype ip ')
|
||||
self.assertRegex(output, 'srcportmin 1001 ')
|
||||
|
||||
touch_network_unit('25-bareudp.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('bareudp99:degraded')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('batman-adv')
|
||||
def test_batadv(self):
|
||||
copy_network_unit('25-batadv.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
@ -1640,6 +1644,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.assertRegex(output, 'batadv')
|
||||
|
||||
touch_network_unit('25-batadv.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('batadv99:degraded')
|
||||
|
||||
def test_bridge(self):
|
||||
copy_network_unit('25-bridge.netdev', '25-bridge-configure-without-carrier.network')
|
||||
start_networkd()
|
||||
@ -1964,6 +1972,17 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, 'link/ether 12:34:56:78:9a:bf')
|
||||
self.assertRegex(output, 'mtu 1800')
|
||||
|
||||
touch_network_unit(
|
||||
'25-veth.netdev',
|
||||
'26-netdev-link-local-addressing-yes.network',
|
||||
'25-veth-mtu.netdev')
|
||||
networkctl_reload()
|
||||
self.wait_online(
|
||||
'veth99:degraded',
|
||||
'veth-peer:degraded',
|
||||
'veth-mtu:degraded',
|
||||
'veth-mtu-peer:degraded')
|
||||
|
||||
def check_tuntap(self, attached):
|
||||
pid = networkd_pid()
|
||||
name = psutil.Process(pid).name()[:15]
|
||||
@ -2023,6 +2042,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
|
||||
self.check_tuntap(True)
|
||||
|
||||
touch_network_unit('25-tun.netdev', '25-tap.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('testtun99:degraded', 'testtap99:degraded')
|
||||
|
||||
self.check_tuntap(True)
|
||||
|
||||
remove_network_unit('26-netdev-link-local-addressing-yes.network')
|
||||
restart_networkd()
|
||||
self.wait_online('testtun99:degraded', 'testtap99:degraded', setup_state='unmanaged')
|
||||
@ -2048,6 +2073,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.wait_online('vrf99:carrier')
|
||||
self.networkctl_check_unit('vrf99', '25-vrf', '26-netdev-link-local-addressing-yes')
|
||||
|
||||
touch_network_unit('25-vrf.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl()
|
||||
self.wait_online('vrf99:carrier')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('vcan')
|
||||
def test_vcan(self):
|
||||
copy_network_unit('25-vcan.netdev', '26-netdev-link-local-addressing-yes.network',
|
||||
@ -2069,6 +2098,14 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.assertIn('mtu 16 ', output)
|
||||
|
||||
touch_network_unit(
|
||||
'25-vcan.netdev',
|
||||
'26-netdev-link-local-addressing-yes.network',
|
||||
'25-vcan98.netdev',
|
||||
'25-vcan98.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('vcan99:carrier', 'vcan98:carrier')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('vxcan')
|
||||
def test_vxcan(self):
|
||||
copy_network_unit('25-vxcan.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
@ -2080,6 +2117,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.networkctl_check_unit('vxcan99', '25-vxcan', '26-netdev-link-local-addressing-yes')
|
||||
self.networkctl_check_unit('vxcan-peer', '25-vxcan', '26-netdev-link-local-addressing-yes')
|
||||
|
||||
touch_network_unit('25-vxcan.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl()
|
||||
self.wait_online('vxcan99:carrier', 'vxcan-peer:carrier')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('wireguard')
|
||||
def test_wireguard(self):
|
||||
copy_credential('25-wireguard-endpoint-peer0-cred.txt', 'network.wireguard.peer0.endpoint')
|
||||
@ -2211,6 +2252,14 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
output = check_output('wg show wg97 fwmark')
|
||||
self.assertEqual(output, '0x4d3')
|
||||
|
||||
touch_network_unit(
|
||||
'25-wireguard.netdev', '25-wireguard.network',
|
||||
'25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network',
|
||||
'25-wireguard-public-key.txt', '25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt',
|
||||
'25-wireguard-no-peer.netdev', '25-wireguard-no-peer.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('wg99:routable', 'wg98:routable', 'wg97:carrier')
|
||||
|
||||
def test_geneve(self):
|
||||
copy_network_unit('25-geneve.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
start_networkd()
|
||||
@ -2225,6 +2274,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, 'udpcsum')
|
||||
self.assertRegex(output, 'udp6zerocsumrx')
|
||||
|
||||
touch_network_unit('25-geneve.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('geneve99:degraded')
|
||||
|
||||
def test_ipip_tunnel(self):
|
||||
copy_network_unit('12-dummy.netdev', '25-ipip.network',
|
||||
'25-ipip-tunnel.netdev', '25-tunnel.network',
|
||||
@ -2825,6 +2878,13 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55556')
|
||||
|
||||
touch_network_unit(
|
||||
'25-fou-ipproto-ipip.netdev', '25-fou-ipproto-gre.netdev',
|
||||
'25-fou-ipip.netdev', '25-fou-sit.netdev',
|
||||
'25-fou-gre.netdev', '25-fou-gretap.netdev')
|
||||
networkctl_reload()
|
||||
self.wait_online('ipiptun96:off', 'sittun96:off', 'gretun96:off', 'gretap96:off', setup_state='unmanaged')
|
||||
|
||||
def test_vxlan(self):
|
||||
copy_network_unit('11-dummy.netdev', '25-vxlan-test1.network',
|
||||
'25-vxlan.netdev', '25-vxlan.network',
|
||||
@ -2929,6 +2989,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.wait_online('nlmon99:carrier')
|
||||
self.networkctl_check_unit('nlmon99', '25-nlmon', '26-netdev-link-local-addressing-yes')
|
||||
|
||||
touch_network_unit('25-nlmon.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('nlmon99:carrier')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('ifb')
|
||||
def test_ifb(self):
|
||||
copy_network_unit('25-ifb.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
@ -2937,6 +3001,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
self.wait_online('ifb99:degraded')
|
||||
self.networkctl_check_unit('ifb99', '25-ifb', '26-netdev-link-local-addressing-yes')
|
||||
|
||||
touch_network_unit('25-ifb.netdev', '26-netdev-link-local-addressing-yes.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('ifb99:degraded')
|
||||
|
||||
@unittest.skipUnless(os.cpu_count() >= 2, reason="CPU count should be >= 2 to pass this test")
|
||||
def test_rps_cpu_1(self):
|
||||
copy_network_unit('12-dummy.netdev', '12-dummy.network', '25-rps-cpu-1.link')
|
||||
@ -3093,6 +3161,12 @@ class NetworkdL2TPTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, "Peer session 18, tunnel 11")
|
||||
self.assertRegex(output, "interface name: l2tp-ses2")
|
||||
|
||||
touch_network_unit(
|
||||
'11-dummy.netdev', '25-l2tp-dummy.network',
|
||||
'25-l2tp-udp.netdev', '25-l2tp.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('test1:routable', 'l2tp-ses1:degraded', 'l2tp-ses2:degraded')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('l2tp_eth', 'l2tp_ip', 'l2tp_netlink')
|
||||
def test_l2tp_ip(self):
|
||||
copy_network_unit('11-dummy.netdev', '25-l2tp-dummy.network',
|
||||
@ -3122,6 +3196,12 @@ class NetworkdL2TPTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, "Peer session 28, tunnel 12")
|
||||
self.assertRegex(output, "interface name: l2tp-ses4")
|
||||
|
||||
touch_network_unit(
|
||||
'11-dummy.netdev', '25-l2tp-dummy.network',
|
||||
'25-l2tp-ip.netdev', '25-l2tp.network')
|
||||
networkctl_reload()
|
||||
self.wait_online('test1:routable', 'l2tp-ses3:degraded', 'l2tp-ses4:degraded')
|
||||
|
||||
class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
|
||||
def setUp(self):
|
||||
@ -5365,6 +5445,15 @@ class NetworkdBondTests(unittest.TestCase, Utilities):
|
||||
self.wait_online('dummy98:enslaved', 'bond199:degraded')
|
||||
self.assertNotIn('dummy98: Bringing link down', read_networkd_log(since=since))
|
||||
|
||||
# test for reloading.
|
||||
touch_network_unit(
|
||||
'23-active-slave.network',
|
||||
'23-bond199.network',
|
||||
'25-bond-active-backup-slave.netdev',
|
||||
'12-dummy.netdev')
|
||||
networkctl_reload()
|
||||
self.wait_online('dummy98:enslaved', 'bond199:degraded')
|
||||
|
||||
def test_bond_primary_slave(self):
|
||||
copy_network_unit('23-primary-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
|
||||
start_networkd()
|
||||
@ -5636,11 +5725,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
|
||||
self.check_bridge_port_attr('bridge99', 'dummy98', 'bpdu_guard', '0')
|
||||
self.check_bridge_port_attr('bridge99', 'dummy98', 'root_block', '0')
|
||||
|
||||
def test_bridge_property(self):
|
||||
copy_network_unit('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
|
||||
'26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
|
||||
'25-bridge99.network')
|
||||
start_networkd()
|
||||
def check_bridge_property(self):
|
||||
self.wait_online('dummy98:enslaved', 'test1:enslaved', 'bridge99:routable')
|
||||
|
||||
output = check_output('ip -d link show bridge99')
|
||||
@ -5683,6 +5768,24 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.check_bridge_port_attr('bridge99', 'test1', 'priority', '0')
|
||||
|
||||
def test_bridge_property(self):
|
||||
copy_network_unit('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
|
||||
'26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
|
||||
'25-bridge99.network')
|
||||
start_networkd()
|
||||
self.check_bridge_property()
|
||||
|
||||
# test reload
|
||||
touch_network_unit(
|
||||
'11-dummy.netdev',
|
||||
'12-dummy.netdev',
|
||||
'26-bridge.netdev',
|
||||
'26-bridge-slave-interface-1.network',
|
||||
'26-bridge-slave-interface-2.network',
|
||||
'25-bridge99.network')
|
||||
networkctl_reload()
|
||||
self.check_bridge_property()
|
||||
|
||||
check_output('ip address add 192.168.0.16/24 dev bridge99')
|
||||
output = check_output('ip addr show bridge99')
|
||||
print(output)
|
||||
|
Loading…
x
Reference in New Issue
Block a user