feat: figure out netlink version on a device in runtime

This commit is contained in:
Yaroslav Gurov 2025-08-23 18:17:17 +02:00
parent b648e1b45f
commit 4fd6667b29
2 changed files with 14 additions and 14 deletions

View file

@ -25,9 +25,9 @@
#define IPC_SUPPORTS_KERNEL_INTERFACE
void put_magic_header_attr(struct nlmsghdr *nlh, int attr_name, char *header_field)
void put_magic_header_attr(uint8_t version, struct nlmsghdr *nlh, int attr_name, char *header_field)
{
if (contains_hyphen(header_field)) {
if (version >= 2) {
mnl_attr_put_strz(nlh, attr_name, header_field);
} else {
uint32_t magic_header = strtoul(header_field, NULL, 10);
@ -177,7 +177,7 @@ static int kernel_set_device(struct wgdevice *dev)
struct nlmsghdr *nlh;
struct mnlg_socket *nlg;
nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
nlg = mnlg_socket_open(WG_GENL_NAME);
if (!nlg)
return -errno;
@ -207,13 +207,13 @@ again:
if (dev->flags & WGDEVICE_HAS_S4)
mnl_attr_put_u16(nlh, WGDEVICE_A_S4, dev->transport_packet_junk_size);
if (dev->flags & WGDEVICE_HAS_H1)
put_magic_header_attr(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header);
put_magic_header_attr(nlg->version, nlh, WGDEVICE_A_H1, dev->init_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H2)
put_magic_header_attr(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header);
put_magic_header_attr(nlg->version, nlh, WGDEVICE_A_H2, dev->response_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H3)
put_magic_header_attr(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header);
put_magic_header_attr(nlg->version, nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_H4)
put_magic_header_attr(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header);
put_magic_header_attr(nlg->version, nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_I1)
mnl_attr_put_strz(nlh, WGDEVICE_A_I1, dev->i1);
if (dev->flags & WGDEVICE_HAS_I2)
@ -685,7 +685,7 @@ try_again:
if (!*device)
return -errno;
nlg = mnlg_socket_open(WG_GENL_NAME, WG_GENL_VERSION);
nlg = mnlg_socket_open(WG_GENL_NAME);
if (!nlg) {
free_wgdevice(*device);
*device = NULL;

View file

@ -718,17 +718,18 @@ static int get_family_id_attr_cb(const struct nlattr *attr, void *data)
static int get_family_id_cb(const struct nlmsghdr *nlh, void *data)
{
uint16_t *p_id = data;
struct mnlg_socket *nlg = data;
struct nlattr *tb[CTRL_ATTR_MAX + 1] = { 0 };
mnl_attr_parse(nlh, sizeof(struct genlmsghdr), get_family_id_attr_cb, tb);
if (!tb[CTRL_ATTR_FAMILY_ID])
if (!tb[CTRL_ATTR_FAMILY_ID] || !tb[CTRL_ATTR_VERSION])
return MNL_CB_ERROR;
*p_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
nlg->id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
nlg->version = mnl_attr_get_u32(tb[CTRL_ATTR_VERSION]);
return MNL_CB_OK;
}
static struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version)
static struct mnlg_socket *mnlg_socket_open(const char *family_name)
{
struct mnlg_socket *nlg;
struct nlmsghdr *nlh;
@ -767,13 +768,12 @@ static struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t ver
}
errno = 0;
if (mnlg_socket_recv_run(nlg, get_family_id_cb, &nlg->id) < 0) {
if (mnlg_socket_recv_run(nlg, get_family_id_cb, nlg) < 0) {
errno = errno == ENOENT ? EPROTONOSUPPORT : errno;
err = errno ? -errno : -ENOSYS;
goto err_mnlg_socket_recv_run;
}
nlg->version = version;
errno = 0;
return nlg;