networkd: manager - enumerate addresses globally, rather than per-link
The kernel always returns all addresses, rather than only for the given link, so let's only enumerate once.
This commit is contained in:
parent
2173cbf847
commit
45af44d47d
|
@ -1194,13 +1194,20 @@ uint32_t rtnl_message_get_serial(sd_rtnl_message *m) {
|
|||
return m->hdr->nlmsg_seq;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_is_error(sd_rtnl_message *m) {
|
||||
assert_return(m, 0);
|
||||
assert_return(m->hdr, 0);
|
||||
|
||||
return m->hdr->nlmsg_type == NLMSG_ERROR;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_get_errno(sd_rtnl_message *m) {
|
||||
struct nlmsgerr *err;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->hdr, -EINVAL);
|
||||
|
||||
if (m->hdr->nlmsg_type != NLMSG_ERROR)
|
||||
if (!sd_rtnl_message_is_error(m))
|
||||
return 0;
|
||||
|
||||
err = NLMSG_DATA(m->hdr);
|
||||
|
|
|
@ -296,11 +296,8 @@ static int dhcp4_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m,
|
|||
log_link_error(link, "could not set DHCPv4 address: %s",
|
||||
strerror(-r));
|
||||
link_enter_failed(link);
|
||||
} else if (r >= 0) {
|
||||
/* calling handler directly so take a ref */
|
||||
link_ref(link);
|
||||
link_get_address_handler(rtnl, m, link);
|
||||
}
|
||||
} else if (r >= 0)
|
||||
link_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
link_set_dhcp_routes(link);
|
||||
|
||||
|
|
|
@ -105,11 +105,8 @@ static int ipv4ll_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userd
|
|||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_error(link, "could not set ipv4ll address: %s", strerror(-r));
|
||||
link_enter_failed(link);
|
||||
} else if (r >= 0) {
|
||||
/* calling handler directly so take a ref */
|
||||
link_ref(link);
|
||||
link_get_address_handler(rtnl, m, link);
|
||||
}
|
||||
} else if (r >= 0)
|
||||
link_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
link->ipv4ll_address = true;
|
||||
|
||||
|
|
|
@ -576,32 +576,6 @@ int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||
_cleanup_link_unref_ Link *link = userdata;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
for (; m; m = sd_rtnl_message_next(m)) {
|
||||
r = sd_rtnl_message_get_errno(m);
|
||||
if (r < 0) {
|
||||
log_link_debug(link, "getting address failed: %s",
|
||||
strerror(-r));
|
||||
continue;
|
||||
}
|
||||
|
||||
r = link_rtnl_process_address(rtnl, m, link->manager);
|
||||
if (r < 0)
|
||||
log_link_warning(link, "could not process address: %s",
|
||||
strerror(-r));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||
_cleanup_link_unref_ Link *link = userdata;
|
||||
int r;
|
||||
|
@ -622,11 +596,8 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
|||
r = sd_rtnl_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
log_link_warning_errno(link, -r, "%-*s: could not set address: %m", IFNAMSIZ, link->ifname);
|
||||
else if (r >= 0) {
|
||||
/* calling handler directly so take a ref */
|
||||
link_ref(link);
|
||||
link_get_address_handler(rtnl, m, link);
|
||||
}
|
||||
else if (r >= 0)
|
||||
link_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->link_messages == 0) {
|
||||
log_link_debug(link, "addresses set");
|
||||
|
@ -1417,8 +1388,7 @@ int link_initialized(Link *link, struct udev_device *device) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
|
||||
void *userdata) {
|
||||
int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *userdata) {
|
||||
Manager *m = userdata;
|
||||
Link *link = NULL;
|
||||
uint16_t type;
|
||||
|
@ -1434,6 +1404,14 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
|
|||
assert(message);
|
||||
assert(m);
|
||||
|
||||
if (sd_rtnl_message_is_error(message)) {
|
||||
r = sd_rtnl_message_get_errno(message);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "rtnl: failed to receive address: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_get_type(message, &type);
|
||||
if (r < 0) {
|
||||
log_warning("rtnl: could not get message type");
|
||||
|
@ -1441,8 +1419,11 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
|
|||
}
|
||||
|
||||
r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
|
||||
if (r < 0 || ifindex <= 0) {
|
||||
log_warning("rtnl: received address message without valid ifindex, ignoring");
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "rtnl: could not get ifindex: %m");
|
||||
return 0;
|
||||
} else if (ifindex <= 0) {
|
||||
log_warning("rtnl: received address message with invalid ifindex: %d", ifindex);
|
||||
return 0;
|
||||
} else {
|
||||
r = link_get(m, ifindex, &link);
|
||||
|
@ -1594,18 +1575,6 @@ int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
|
|||
|
||||
log_link_debug(link, "link %d added", link->ifindex);
|
||||
|
||||
r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, link->ifindex,
|
||||
0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_rtnl_call_async(m->rtnl, req, link_get_address_handler, link, 0,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
|
||||
if (detect_container(NULL) <= 0) {
|
||||
/* not in a container, udev will be around */
|
||||
sprintf(ifindex_str, "n%d", link->ifindex);
|
||||
|
|
|
@ -99,7 +99,6 @@ int link_get(Manager *m, int ifindex, Link **ret);
|
|||
int link_add(Manager *manager, sd_rtnl_message *message, Link **ret);
|
||||
void link_drop(Link *link);
|
||||
|
||||
int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
|
||||
int link_address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
|
||||
int link_route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
|
||||
|
||||
|
|
|
@ -236,22 +236,33 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
|
|||
assert(message);
|
||||
assert(m);
|
||||
|
||||
if (sd_rtnl_message_is_error(message)) {
|
||||
r = sd_rtnl_message_get_errno(message);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "rtnl: could not receive link: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_get_type(message, &type);
|
||||
if (r < 0) {
|
||||
log_warning("rtnl: could not get message type");
|
||||
log_warning_errno(r, "rtnl: could not get message type: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
|
||||
if (r < 0 || ifindex <= 0) {
|
||||
log_warning("rtnl: received link message without valid ifindex");
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "rtnl: could not get ifindex: %m");
|
||||
return 0;
|
||||
} else if (ifindex <= 0) {
|
||||
log_warning("rtnl: received link message with invalid ifindex: %d", ifindex);
|
||||
return 0;
|
||||
} else
|
||||
link_get(m, ifindex, &link);
|
||||
|
||||
r = sd_rtnl_message_read_string(message, IFLA_IFNAME, &name);
|
||||
if (r < 0 || !name) {
|
||||
log_warning("rtnl: received link message without valid ifname");
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "rtnl: received link message without ifname: %m");
|
||||
return 0;
|
||||
} else
|
||||
netdev_get(m, name, &netdev);
|
||||
|
@ -271,7 +282,7 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
|
|||
/* netdev exists, so make sure the ifindex matches */
|
||||
r = netdev_set_ifindex(netdev, message);
|
||||
if (r < 0) {
|
||||
log_debug("could not set ifindex on netdev");
|
||||
log_debug_errno(r, "could not set ifindex on netdev: %m");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +309,7 @@ static int manager_rtnl_process_link(sd_rtnl *rtnl, sd_rtnl_message *message, vo
|
|||
int manager_rtnl_enumerate_links(Manager *m) {
|
||||
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
|
||||
sd_rtnl_message *link;
|
||||
int r, k;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(m->rtnl);
|
||||
|
@ -316,14 +327,7 @@ int manager_rtnl_enumerate_links(Manager *m) {
|
|||
return r;
|
||||
|
||||
for (link = reply; link; link = sd_rtnl_message_next(link)) {
|
||||
uint16_t type;
|
||||
|
||||
k = sd_rtnl_message_get_type(link, &type);
|
||||
if (k < 0)
|
||||
return k;
|
||||
|
||||
if (type != RTM_NEWLINK)
|
||||
continue;
|
||||
int k;
|
||||
|
||||
k = manager_rtnl_process_link(m->rtnl, link, m);
|
||||
if (k < 0)
|
||||
|
@ -333,6 +337,37 @@ int manager_rtnl_enumerate_links(Manager *m) {
|
|||
return r;
|
||||
}
|
||||
|
||||
int manager_rtnl_enumerate_addresses(Manager *m) {
|
||||
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
|
||||
sd_rtnl_message *addr;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(m->rtnl);
|
||||
|
||||
r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_rtnl_message_request_dump(req, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_rtnl_call(m->rtnl, req, 0, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (addr = reply; addr; addr = sd_rtnl_message_next(addr)) {
|
||||
int k;
|
||||
|
||||
k = link_rtnl_process_address(m->rtnl, addr, m);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||
Manager *m = userdata;
|
||||
struct udev_monitor *monitor = m->udev_monitor;
|
||||
|
|
|
@ -110,6 +110,12 @@ int main(int argc, char *argv[]) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
r = manager_rtnl_enumerate_addresses(m);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Could not enumerate links: %m");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sd_notify(false,
|
||||
"READY=1\n"
|
||||
"STATUS=Processing requests...");
|
||||
|
|
|
@ -203,6 +203,7 @@ int manager_load_config(Manager *m);
|
|||
bool manager_should_reload(Manager *m);
|
||||
|
||||
int manager_rtnl_enumerate_links(Manager *m);
|
||||
int manager_rtnl_enumerate_addresses(Manager *m);
|
||||
|
||||
int manager_rtnl_listen(Manager *m);
|
||||
int manager_udev_listen(Manager *m);
|
||||
|
|
|
@ -81,6 +81,7 @@ sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m);
|
|||
sd_rtnl_message *sd_rtnl_message_unref(sd_rtnl_message *m);
|
||||
|
||||
int sd_rtnl_message_request_dump(sd_rtnl_message *m, int dump);
|
||||
int sd_rtnl_message_is_error(sd_rtnl_message *m);
|
||||
int sd_rtnl_message_get_errno(sd_rtnl_message *m);
|
||||
int sd_rtnl_message_get_type(sd_rtnl_message *m, uint16_t *type);
|
||||
int sd_rtnl_message_is_broadcast(sd_rtnl_message *m);
|
||||
|
|
Loading…
Reference in a new issue