module/network: break out message parsing code

This also allows us to actually handle errors (by aborting run())
This commit is contained in:
Daniel Eklöf 2018-12-31 13:36:44 +01:00
parent 8352d89491
commit dcf8051f1a

View file

@ -33,6 +33,10 @@ struct private {
char *iface; char *iface;
struct particle *label; struct particle *label;
int nl_sock;
bool get_addresses;
int ifindex; int ifindex;
uint8_t mac[6]; uint8_t mac[6];
bool carrier; bool carrier;
@ -47,6 +51,8 @@ destroy(struct module *mod)
{ {
struct private *m = mod->private; struct private *m = mod->private;
assert(m->nl_sock == -1);
m->label->destroy(m->label); m->label->destroy(m->label);
tll_free(m->addrs); tll_free(m->addrs);
@ -304,8 +310,10 @@ handle_address(struct module *mod, uint16_t type,
const void *raw_addr = RTA_DATA(attr); const void *raw_addr = RTA_DATA(attr);
size_t addr_len = RTA_PAYLOAD(attr); size_t addr_len = RTA_PAYLOAD(attr);
#if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG
char s[INET6_ADDRSTRLEN]; char s[INET6_ADDRSTRLEN];
inet_ntop(msg->ifa_family, raw_addr, s, sizeof(s)); inet_ntop(msg->ifa_family, raw_addr, s, sizeof(s));
#endif
LOG_DBG("%s: IFA_ADDRESS: %s", m->iface, s); LOG_DBG("%s: IFA_ADDRESS: %s", m->iface, s);
mtx_lock(&mod->lock); mtx_lock(&mod->lock);
@ -379,63 +387,24 @@ netlink_receive_messages(int sock, void **reply, size_t *len)
return true; return true;
} }
static int static bool
run(struct module_run_context *ctx) process_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
{ {
struct module *mod = ctx->module;
struct private *m = mod->private; struct private *m = mod->private;
module_signal_ready(ctx);
int nl_sock = netlink_connect();
if (nl_sock == -1)
return 1;
if (!send_rt_request(nl_sock, RTM_GETLINK)) {
close(nl_sock);
return 1;
}
/* We must wait for NLMSG_DONE from the first request, before
* sending another one... */
bool get_addresses = true;
/* Main loop */
while (true) {
struct pollfd fds[] = {
{.fd = ctx->abort_fd, .events = POLLIN},
{.fd = nl_sock, .events = POLLIN}
};
poll(fds, 2, -1);
if (fds[0].revents & POLLIN)
break;
if (fds[1].revents & POLLHUP) {
LOG_ERR("disconnected from netlink socket");
break;
}
assert(fds[1].revents & POLLIN);
/* Read one (or more) messages */
void *reply;
size_t len;
if (!netlink_receive_messages(nl_sock, &reply, &len))
break;
/* Process response */ /* Process response */
for (const struct nlmsghdr *hdr = (const struct nlmsghdr *)reply; for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
NLMSG_OK(hdr, len);
hdr = NLMSG_NEXT(hdr, len))
{
switch (hdr->nlmsg_type) { switch (hdr->nlmsg_type) {
case NLMSG_DONE: case NLMSG_DONE:
if (m->ifindex == -1) {
LOG_ERR("%s: failed to find interface", m->iface);
return false;
}
/* Request initial list of IPv4/6 addresses */ /* Request initial list of IPv4/6 addresses */
if (get_addresses && m->ifindex != -1) { if (m->get_addresses && m->ifindex != -1) {
get_addresses = false; m->get_addresses = false;
send_rt_request(nl_sock, RTM_GETADDR); send_rt_request(m->nl_sock, RTM_GETADDR);
} }
break; break;
@ -460,7 +429,7 @@ run(struct module_run_context *ctx)
case NLMSG_ERROR:{ case NLMSG_ERROR:{
const struct nlmsgerr *err = NLMSG_DATA(hdr); const struct nlmsgerr *err = NLMSG_DATA(hdr);
LOG_ERRNO_P("netlink", err->error); LOG_ERRNO_P("netlink", err->error);
break; return false;
} }
default: default:
@ -470,10 +439,62 @@ run(struct module_run_context *ctx)
} }
} }
return true;
}
static int
run(struct module_run_context *ctx)
{
struct module *mod = ctx->module;
struct private *m = mod->private;
module_signal_ready(ctx);
m->nl_sock = netlink_connect();
if (m->nl_sock == -1)
return 1;
if (!send_rt_request(m->nl_sock, RTM_GETLINK)) {
close(m->nl_sock);
m->nl_sock = -1;
return 1;
}
/* Main loop */
while (true) {
struct pollfd fds[] = {
{.fd = ctx->abort_fd, .events = POLLIN},
{.fd = m->nl_sock, .events = POLLIN}
};
poll(fds, 2, -1);
if (fds[0].revents & POLLIN)
break;
if (fds[1].revents & POLLHUP) {
LOG_ERR("disconnected from netlink socket");
break;
}
assert(fds[1].revents & POLLIN);
/* Read one (or more) messages */
void *reply;
size_t len;
if (!netlink_receive_messages(m->nl_sock, &reply, &len))
break;
if (!process_reply(mod, (const struct nlmsghdr *)reply, len)) {
free(reply);
break;
}
free(reply); free(reply);
} }
close(nl_sock); close(m->nl_sock);
m->nl_sock = -1;
return 0; return 0;
} }
@ -484,6 +505,8 @@ module_network(const char *iface, struct particle *label)
priv->iface = strdup(iface); priv->iface = strdup(iface);
priv->label = label; priv->label = label;
priv->nl_sock = -1;
priv->get_addresses = true;
priv->ifindex = -1; priv->ifindex = -1;
priv->carrier = false; priv->carrier = false;
priv->state = IF_OPER_DOWN; priv->state = IF_OPER_DOWN;