1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-24 21:34:08 +03:00

network: move manager_{rtnl,udev}_process_link() to networkd-link.[ch]

This commit is contained in:
Yu Watanabe 2021-02-21 15:51:51 +09:00
parent 24e3ed843f
commit 3be9d62ad1
3 changed files with 150 additions and 152 deletions

View File

@ -11,6 +11,8 @@
#include "bond.h"
#include "bridge.h"
#include "bus-util.h"
#include "device-private.h"
#include "device-util.h"
#include "dhcp-identifier.h"
#include "dhcp-lease-internal.h"
#include "env-file.h"
@ -1734,7 +1736,7 @@ static void link_detach_from_manager(Link *link) {
link_unref(link);
}
void link_drop(Link *link) {
static void link_drop(Link *link) {
if (!link || link->state == LINK_STATE_LINGER)
return;
@ -2381,7 +2383,7 @@ static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
return 1;
}
int link_initialized(Link *link, sd_device *device) {
static int link_initialized(Link *link, sd_device *device) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
@ -2421,7 +2423,7 @@ int link_initialized(Link *link, sd_device *device) {
return 0;
}
int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
static int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
char ifindex_str[2 + DECIMAL_STR_MAX(int)];
Link *link;
@ -2506,6 +2508,57 @@ int link_ipv6ll_gained(Link *link, const struct in6_addr *address) {
return 0;
}
int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata) {
sd_device_action_t action;
Manager *m = userdata;
Link *link = NULL;
int r, ifindex;
assert(m);
assert(device);
r = sd_device_get_action(device, &action);
if (r < 0) {
log_device_debug_errno(device, r, "Failed to get udev action, ignoring device: %m");
return 0;
}
/* Ignore the "remove" uevent — let's remove a device only if rtnetlink says so. All other uevents
* are "positive" events in some form, i.e. inform us about a changed or new network interface, that
* still exists and we are interested in that. */
if (action == SD_DEVICE_REMOVE)
return 0;
r = sd_device_get_ifindex(device, &ifindex);
if (r < 0) {
log_device_debug_errno(device, r, "Ignoring udev %s event for device without ifindex or with invalid ifindex: %m",
device_action_to_string(action));
return 0;
}
r = device_is_renaming(device);
if (r < 0) {
log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m",
device_action_to_string(action));
return 0;
}
if (r > 0) {
log_device_debug(device, "Interface is under renaming, wait for the interface to be renamed.");
return 0;
}
r = link_get(m, ifindex, &link);
if (r < 0) {
if (r != -ENODEV)
log_debug_errno(r, "Failed to get link from ifindex %i, ignoring: %m", ifindex);
return 0;
}
(void) link_initialized(link, device);
return 0;
}
static int link_carrier_gained(Link *link) {
int r;
@ -2619,13 +2672,14 @@ int link_carrier_reset(Link *link) {
return 0;
}
/* This is called every time an interface admin state changes to up;
* specifically, when IFF_UP flag changes from unset to set */
static int link_admin_state_up(Link *link) {
int r;
assert(link);
/* This is called every time an interface admin state changes to up;
* specifically, when IFF_UP flag changes from unset to set. */
if (!link->network)
return 0;
@ -2649,7 +2703,6 @@ static int link_admin_state_up(Link *link) {
}
static int link_admin_state_down(Link *link) {
assert(link);
if (!link->network)
@ -2663,7 +2716,7 @@ static int link_admin_state_down(Link *link) {
return 0;
}
int link_update(Link *link, sd_netlink_message *m) {
static int link_update(Link *link, sd_netlink_message *m) {
_cleanup_strv_free_ char **s = NULL;
hw_addr_data hw_addr;
const char *ifname;
@ -2807,6 +2860,93 @@ int link_update(Link *link, sd_netlink_message *m) {
return 0;
}
int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
Link *link = NULL;
NetDev *netdev = NULL;
uint16_t type;
const char *name;
int r, ifindex;
assert(rtnl);
assert(message);
assert(m);
if (sd_netlink_message_is_error(message)) {
r = sd_netlink_message_get_errno(message);
if (r < 0)
log_message_warning_errno(message, r, "rtnl: Could not receive link message, ignoring");
return 0;
}
r = sd_netlink_message_get_type(message, &type);
if (r < 0) {
log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m");
return 0;
} else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) {
log_warning("rtnl: Received unexpected message type %u when processing link, ignoring.", type);
return 0;
}
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
if (r < 0) {
log_warning_errno(r, "rtnl: Could not get ifindex from link message, ignoring: %m");
return 0;
} else if (ifindex <= 0) {
log_warning("rtnl: received link message with invalid ifindex %d, ignoring.", ifindex);
return 0;
}
r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
if (r < 0) {
log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m");
return 0;
}
(void) link_get(m, ifindex, &link);
(void) netdev_get(m, name, &netdev);
switch (type) {
case RTM_NEWLINK:
if (!link) {
/* link is new, so add it */
r = link_add(m, message, &link);
if (r < 0) {
log_warning_errno(r, "Could not process new link message, ignoring: %m");
return 0;
}
}
if (netdev) {
/* netdev exists, so make sure the ifindex matches */
r = netdev_set_ifindex(netdev, message);
if (r < 0) {
log_warning_errno(r, "Could not process new link message for netdev, ignoring: %m");
return 0;
}
}
r = link_update(link, message);
if (r < 0) {
log_warning_errno(r, "Could not process link message, ignoring: %m");
return 0;
}
break;
case RTM_DELLINK:
link_drop(link);
netdev_drop(netdev);
break;
default:
assert_not_reached("Received link message with invalid RTNL message type.");
}
return 1;
}
static const char* const link_state_table[_LINK_STATE_MAX] = {
[LINK_STATE_PENDING] = "pending",
[LINK_STATE_INITIALIZED] = "initialized",

View File

@ -203,19 +203,15 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref);
int link_get(Manager *m, int ifindex, Link **ret);
int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
void link_drop(Link *link);
int link_down(Link *link, link_netlink_message_handler_t callback);
void link_enter_failed(Link *link);
int link_initialized(Link *link, sd_device *device);
void link_set_state(Link *link, LinkState state);
void link_check_ready(Link *link);
void link_update_operstate(Link *link, bool also_update_bond_master);
int link_update(Link *link, sd_netlink_message *message);
int link_carrier_reset(Link *link);
bool link_has_carrier(Link *link);
@ -236,6 +232,9 @@ LinkState link_state_from_string(const char *s) _pure_;
int link_configure(Link *link);
int link_reconfigure(Link *link, bool force);
int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata);
int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)

View File

@ -17,8 +17,6 @@
#include "bus-util.h"
#include "conf-parser.h"
#include "def.h"
#include "device-private.h"
#include "device-util.h"
#include "dns-domain.h"
#include "fd-util.h"
#include "fileio.h"
@ -49,7 +47,6 @@
#include "strv.h"
#include "sysctl-util.h"
#include "tmpfile-util.h"
#include "udev-util.h"
/* use 128 MB for receive socket kernel queue. */
#define RCVBUF_SIZE (128*1024*1024)
@ -182,57 +179,6 @@ int manager_connect_bus(Manager *m) {
return 0;
}
static int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata) {
sd_device_action_t action;
Manager *m = userdata;
Link *link = NULL;
int r, ifindex;
assert(m);
assert(device);
r = sd_device_get_action(device, &action);
if (r < 0) {
log_device_debug_errno(device, r, "Failed to get udev action, ignoring device: %m");
return 0;
}
/* Ignore the "remove" uevent — let's remove a device only if rtnetlink says so. All other uevents
* are "positive" events in some form, i.e. inform us about a changed or new network interface, that
* still exists and we are interested in that. */
if (action == SD_DEVICE_REMOVE)
return 0;
r = sd_device_get_ifindex(device, &ifindex);
if (r < 0) {
log_device_debug_errno(device, r, "Ignoring udev %s event for device without ifindex or with invalid ifindex: %m",
device_action_to_string(action));
return 0;
}
r = device_is_renaming(device);
if (r < 0) {
log_device_error_errno(device, r, "Failed to determine the device is renamed or not, ignoring '%s' uevent: %m",
device_action_to_string(action));
return 0;
}
if (r > 0) {
log_device_debug(device, "Interface is under renaming, wait for the interface to be renamed.");
return 0;
}
r = link_get(m, ifindex, &link);
if (r < 0) {
if (r != -ENODEV)
log_debug_errno(r, "Failed to get link from ifindex %i, ignoring: %m", ifindex);
return 0;
}
(void) link_initialized(link, device);
return 0;
}
static int manager_connect_udev(Manager *m) {
int r;
@ -264,93 +210,6 @@ static int manager_connect_udev(Manager *m) {
return 0;
}
static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
Link *link = NULL;
NetDev *netdev = NULL;
uint16_t type;
const char *name;
int r, ifindex;
assert(rtnl);
assert(message);
assert(m);
if (sd_netlink_message_is_error(message)) {
r = sd_netlink_message_get_errno(message);
if (r < 0)
log_message_warning_errno(message, r, "rtnl: Could not receive link message, ignoring");
return 0;
}
r = sd_netlink_message_get_type(message, &type);
if (r < 0) {
log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m");
return 0;
} else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)) {
log_warning("rtnl: Received unexpected message type %u when processing link, ignoring.", type);
return 0;
}
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
if (r < 0) {
log_warning_errno(r, "rtnl: Could not get ifindex from link message, ignoring: %m");
return 0;
} else if (ifindex <= 0) {
log_warning("rtnl: received link message with invalid ifindex %d, ignoring.", ifindex);
return 0;
}
r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
if (r < 0) {
log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m");
return 0;
}
(void) link_get(m, ifindex, &link);
(void) netdev_get(m, name, &netdev);
switch (type) {
case RTM_NEWLINK:
if (!link) {
/* link is new, so add it */
r = link_add(m, message, &link);
if (r < 0) {
log_warning_errno(r, "Could not process new link message, ignoring: %m");
return 0;
}
}
if (netdev) {
/* netdev exists, so make sure the ifindex matches */
r = netdev_set_ifindex(netdev, message);
if (r < 0) {
log_warning_errno(r, "Could not process new link message for netdev, ignoring: %m");
return 0;
}
}
r = link_update(link, message);
if (r < 0) {
log_warning_errno(r, "Could not process link message, ignoring: %m");
return 0;
}
break;
case RTM_DELLINK:
link_drop(link);
netdev_drop(netdev);
break;
default:
assert_not_reached("Received link message with invalid RTNL message type.");
}
return 1;
}
static int systemd_netlink_fd(void) {
int n, fd, rtnl_fd = -EINVAL;