mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-21 20:05:42 +02:00
module/network: break out message parsing code
This also allows us to actually handle errors (by aborting run())
This commit is contained in:
parent
8352d89491
commit
dcf8051f1a
1 changed files with 77 additions and 54 deletions
|
@ -33,6 +33,10 @@ struct private {
|
|||
char *iface;
|
||||
struct particle *label;
|
||||
|
||||
int nl_sock;
|
||||
|
||||
bool get_addresses;
|
||||
|
||||
int ifindex;
|
||||
uint8_t mac[6];
|
||||
bool carrier;
|
||||
|
@ -47,6 +51,8 @@ destroy(struct module *mod)
|
|||
{
|
||||
struct private *m = mod->private;
|
||||
|
||||
assert(m->nl_sock == -1);
|
||||
|
||||
m->label->destroy(m->label);
|
||||
|
||||
tll_free(m->addrs);
|
||||
|
@ -304,8 +310,10 @@ handle_address(struct module *mod, uint16_t type,
|
|||
const void *raw_addr = RTA_DATA(attr);
|
||||
size_t addr_len = RTA_PAYLOAD(attr);
|
||||
|
||||
#if defined(LOG_ENABLE_DBG) && LOG_ENABLE_DBG
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
inet_ntop(msg->ifa_family, raw_addr, s, sizeof(s));
|
||||
#endif
|
||||
LOG_DBG("%s: IFA_ADDRESS: %s", m->iface, s);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -379,6 +387,61 @@ netlink_receive_messages(int sock, void **reply, size_t *len)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
process_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
|
||||
/* Process response */
|
||||
for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {
|
||||
switch (hdr->nlmsg_type) {
|
||||
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 */
|
||||
if (m->get_addresses && m->ifindex != -1) {
|
||||
m->get_addresses = false;
|
||||
send_rt_request(m->nl_sock, RTM_GETADDR);
|
||||
}
|
||||
break;
|
||||
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK: {
|
||||
const struct ifinfomsg *msg = NLMSG_DATA(hdr);
|
||||
size_t msg_len = IFLA_PAYLOAD(hdr);
|
||||
|
||||
handle_link(mod, hdr->nlmsg_type, msg, msg_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR: {
|
||||
const struct ifaddrmsg *msg = NLMSG_DATA(hdr);
|
||||
size_t msg_len = IFA_PAYLOAD(hdr);
|
||||
|
||||
handle_address(mod, hdr->nlmsg_type, msg, msg_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case NLMSG_ERROR:{
|
||||
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||
LOG_ERRNO_P("netlink", err->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARN(
|
||||
"unrecognized netlink message type: 0x%x", hdr->nlmsg_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
run(struct module_run_context *ctx)
|
||||
{
|
||||
|
@ -387,24 +450,21 @@ run(struct module_run_context *ctx)
|
|||
|
||||
module_signal_ready(ctx);
|
||||
|
||||
int nl_sock = netlink_connect();
|
||||
if (nl_sock == -1)
|
||||
m->nl_sock = netlink_connect();
|
||||
if (m->nl_sock == -1)
|
||||
return 1;
|
||||
|
||||
if (!send_rt_request(nl_sock, RTM_GETLINK)) {
|
||||
close(nl_sock);
|
||||
if (!send_rt_request(m->nl_sock, RTM_GETLINK)) {
|
||||
close(m->nl_sock);
|
||||
m->nl_sock = -1;
|
||||
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}
|
||||
{.fd = m->nl_sock, .events = POLLIN}
|
||||
};
|
||||
|
||||
poll(fds, 2, -1);
|
||||
|
@ -422,58 +482,19 @@ run(struct module_run_context *ctx)
|
|||
/* Read one (or more) messages */
|
||||
void *reply;
|
||||
size_t len;
|
||||
if (!netlink_receive_messages(nl_sock, &reply, &len))
|
||||
if (!netlink_receive_messages(m->nl_sock, &reply, &len))
|
||||
break;
|
||||
|
||||
/* Process response */
|
||||
for (const struct nlmsghdr *hdr = (const struct nlmsghdr *)reply;
|
||||
NLMSG_OK(hdr, len);
|
||||
hdr = NLMSG_NEXT(hdr, len))
|
||||
{
|
||||
switch (hdr->nlmsg_type) {
|
||||
case NLMSG_DONE:
|
||||
/* Request initial list of IPv4/6 addresses */
|
||||
if (get_addresses && m->ifindex != -1) {
|
||||
get_addresses = false;
|
||||
send_rt_request(nl_sock, RTM_GETADDR);
|
||||
}
|
||||
break;
|
||||
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK: {
|
||||
const struct ifinfomsg *msg = NLMSG_DATA(hdr);
|
||||
size_t msg_len = IFLA_PAYLOAD(hdr);
|
||||
|
||||
handle_link(mod, hdr->nlmsg_type, msg, msg_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR: {
|
||||
const struct ifaddrmsg *msg = NLMSG_DATA(hdr);
|
||||
size_t msg_len = IFA_PAYLOAD(hdr);
|
||||
|
||||
handle_address(mod, hdr->nlmsg_type, msg, msg_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case NLMSG_ERROR:{
|
||||
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||
LOG_ERRNO_P("netlink", err->error);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARN(
|
||||
"unrecognized netlink message type: 0x%x", hdr->nlmsg_type);
|
||||
break;
|
||||
}
|
||||
if (!process_reply(mod, (const struct nlmsghdr *)reply, len)) {
|
||||
free(reply);
|
||||
break;
|
||||
}
|
||||
|
||||
free(reply);
|
||||
}
|
||||
|
||||
close(nl_sock);
|
||||
close(m->nl_sock);
|
||||
m->nl_sock = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -484,6 +505,8 @@ module_network(const char *iface, struct particle *label)
|
|||
priv->iface = strdup(iface);
|
||||
priv->label = label;
|
||||
|
||||
priv->nl_sock = -1;
|
||||
priv->get_addresses = true;
|
||||
priv->ifindex = -1;
|
||||
priv->carrier = false;
|
||||
priv->state = IF_OPER_DOWN;
|
||||
|
|
Loading…
Add table
Reference in a new issue