mirror of
https://github.com/troglobit/finit.git
synced 2026-11-06 15:51:03 +00:00
plugins: netlink: fix resync request size alignment with kernel
For RTM_GETLINK we need a `struct ifinfomsg`, not `struct rtmsg`, otherwise the kernel will get 8 extra bytes and complain about it. This patch makes sure to set the correct iface change mask as well, and increases the debug logs a bit to get a fix on sizes used. We increase the recv() buffer 8k -> 64k to make sure we can get all data in one big swoop. Plan is to refactor this mess in a later commit. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
910bb13711
commit
6c60b67588
1 file changed
+43
-10
+43
-10
@@ -32,7 +32,16 @@
|
|||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
|
|
||||||
#define NL_BUFSZ 8192
|
/* Used on resync, when we potentially read ALL interfaces in the system */
|
||||||
|
#define NL_BUFSZ 65536
|
||||||
|
|
||||||
|
struct nl_request {
|
||||||
|
struct nlmsghdr nh;
|
||||||
|
union {
|
||||||
|
struct rtmsg rtm;
|
||||||
|
struct ifinfomsg ifi;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
static int nl_defidx;
|
static int nl_defidx;
|
||||||
static int nl_ifdown;
|
static int nl_ifdown;
|
||||||
@@ -262,19 +271,42 @@ static int nl_parse(struct nlmsghdr *nh, ssize_t len)
|
|||||||
|
|
||||||
static int nl_resync_act(int sd, unsigned int seq, int type)
|
static int nl_resync_act(int sd, unsigned int seq, int type)
|
||||||
{
|
{
|
||||||
struct nlmsghdr *nh;
|
struct nl_request *nlr = (struct nl_request *)nl_buf;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
nh = (struct nlmsghdr *)nl_buf;
|
memset(nlr, 0, sizeof(struct nl_request));
|
||||||
nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
nlr->nh.nlmsg_type = type;
|
||||||
nh->nlmsg_type = type;
|
nlr->nh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
|
||||||
nh->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
|
nlr->nh.nlmsg_seq = seq;
|
||||||
nh->nlmsg_seq = seq;
|
nlr->nh.nlmsg_pid = 1;
|
||||||
nh->nlmsg_pid = 1;
|
|
||||||
|
|
||||||
if (send(sd, nh, nh->nlmsg_len, 0) < 0)
|
switch (type) {
|
||||||
|
case RTM_GETROUTE:
|
||||||
|
nlr->rtm.rtm_family = AF_INET;
|
||||||
|
nlr->rtm.rtm_table = RT_TABLE_MAIN;
|
||||||
|
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_GETLINK:
|
||||||
|
nlr->ifi.ifi_family = AF_UNSPEC;
|
||||||
|
nlr->ifi.ifi_change = 0xFFFFFFFF;
|
||||||
|
nlr->nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
_w("Cannot resync, unhandled message type %d", type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send(sd, nlr, nlr->nh.nlmsg_len, 0) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return nl_parse(nh, recv(sd, nl_buf, NL_BUFSZ, 0));
|
len = recv(sd, nl_buf, NL_BUFSZ, 0);
|
||||||
|
if (len < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
_d("recv %lld bytes in resync path", len);
|
||||||
|
return nl_parse((struct nlmsghdr *)nl_buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nl_resync_routes(int sd, unsigned int seq)
|
static void nl_resync_routes(int sd, unsigned int seq)
|
||||||
@@ -340,6 +372,7 @@ static void nl_callback(void *arg, int sd, int events)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_d("recv %lld bytes in regular path", len);
|
||||||
nl_parse((struct nlmsghdr *)nl_buf, len);
|
nl_parse((struct nlmsghdr *)nl_buf, len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in new issue
Block a user