network/netdev: follow-ups for reloading .netdev files (#34979)

Follow-ups for #34909.
This commit is contained in:
Luca Boccassi
2024-11-14 11:36:26 +00:00
committed by GitHub
20 changed files with 380 additions and 133 deletions
+1
View File
@@ -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,
};
+22 -9
View File
@@ -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;
+5
View File
@@ -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,
};
+5
View File
@@ -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,
};
+5
View File
@@ -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,
};
+2
View File
@@ -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) {
+2
View File
@@ -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,
};
+96 -43
View File
@@ -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,32 @@ 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)
return true;
Link *link;
if (link_get_by_index(netdev->manager, netdev->ifindex, &link) < 0)
return true; /* The netdev does not exist yet. We can set MAC address. */
return NETDEV_VTABLE(netdev)->can_set_mac(netdev, hw_addr);
if (hw_addr_equal(&link->hw_addr, hw_addr))
return false; /* Unchanged, not necessary to set. */
/* Soem netdevs refuse to update MAC address even if the interface is not running, e.g. ipvlan.
* Some other netdevs have the IFF_LIVE_ADDR_CHANGE flag and can update update MAC address even if
* the interface is running, e.g. dummy. For those cases, use custom checkers. */
if (NETDEV_VTABLE(netdev)->can_set_mac)
return NETDEV_VTABLE(netdev)->can_set_mac(netdev, hw_addr);
/* Before ad72c4a06acc6762e84994ac2f722da7a07df34e and 0ec92a8f56ff07237dbe8af7c7a72aba7f957baf
* (both in v6.5), the kernel refuse to set MAC address for existing netdevs even if it is unchanged.
* So, by default, do not update MAC address if the it is running. See eth_prepare_mac_addr_change(),
* which is called by eth_mac_addr(). Note, the result of netif_running() is mapped to operstate
* and flags. See rtnl_fill_ifinfo() and dev_get_flags(). */
return link->kernel_operstate == IF_OPER_DOWN &&
(link->flags & (IFF_RUNNING | IFF_LOWER_UP | IFF_DORMANT)) == 0;
}
static bool netdev_can_set_mtu(NetDev *netdev, uint32_t mtu) {
@@ -653,18 +663,35 @@ static bool netdev_can_set_mtu(NetDev *netdev, uint32_t mtu) {
if (mtu <= 0)
return false;
if (!NETDEV_VTABLE(netdev)->can_set_mtu)
return true;
Link *link;
if (link_get_by_index(netdev->manager, netdev->ifindex, &link) < 0)
return true; /* The netdev does not exist yet. We can set MTU. */
return NETDEV_VTABLE(netdev)->can_set_mtu(netdev, mtu);
if (mtu < link->min_mtu || link->max_mtu < mtu)
return false; /* The MTU is out of range. */
if (link->mtu == mtu)
return false; /* Unchanged, not necessary to set. */
/* Some netdevs cannot change MTU, e.g. vxlan. Let's use the custom checkers in such cases. */
if (NETDEV_VTABLE(netdev)->can_set_mtu)
return NETDEV_VTABLE(netdev)->can_set_mtu(netdev, mtu);
/* By default, allow to update the MTU. */
return true;
}
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 +854,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 +874,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 +957,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 +995,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;
}
+4
View File
@@ -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];
+5
View File
@@ -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,
};
+8
View File
@@ -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,
};
+78 -69
View File
@@ -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,
-1
View File
@@ -8,7 +8,6 @@ typedef struct TunTap TunTap;
struct TunTap {
NetDev meta;
int fd;
char *user_name;
char *group_name;
bool multi_queue;
+1
View File
@@ -150,4 +150,5 @@ const NetDevVTable veth_vtable = {
.get_ifindex = netdev_veth_get_ifindex,
.iftype = ARPHRD_ETHER,
.generate_mac = true,
.keep_existing = true,
};
+6
View File
@@ -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,
};
+1
View File
@@ -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,
};
+5
View File
@@ -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,
+1
View File
@@ -1265,4 +1265,5 @@ const NetDevVTable wireguard_vtable = {
.create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = wireguard_verify,
.iftype = ARPHRD_NONE,
.keep_existing = true,
};