Почему я не получаю сообщения от ядра? - PullRequest
1 голос
/ 11 июля 2020

Я пытаюсь отправить сообщение из ядра в пространство пользователя, используя generi c netlink и libnl, часть моего кода, которая делает это, реализована следующим образом:

int struct my_callback(struct sk_buff *skb, struct genl_info *info)
{
    struct sk_buff *obuff;
    void *msg_head;

    if ((obuff = genlmsg_new(0, GFP_KERNEL)) == NULL) { // I've tried to change the len to NLMSG_GOODSIZE but not worked
        pr_err("Failed allocating message to an reply\n");
        return 0;
    }

    if ((msg_head = genlmsg_put_reply(obuff, info, &lunatik_family, 0, LIST_STATES)) == NULL) {
        pr_err("Failed to put generic netlink header\n");
        return 0;
    }

    //I've tried to put a genlmsg_end(obuff, msg_head); but didn't work as well

    if (genlmsg_reply(obuff, info) < 0) {
        pr_err("Failed to send message to user space\n");
        return 0;
    }
    pr_info("Message sent to user-space\n");
    return 0;
}

Ps: LIST_STATES является членом enum и имеет значение 3

И мой код пользовательского пространства в основном:

static int req_handler(struct nl_msg *msg, void *arg)
{
    struct nlmsghdr *nlhdr;
    struct genlmsghdr *genlhdr;
    
    nlhdr = nlmsg_hdr(msg);
    genlhdr = genlmsg_hdr(nlhdr);

    printf("Received a message from kernel: %d\n", genlhdr->cmd);

    return NL_OK;
}


int socket_init(struct nl_sock *sock)
{
    int err = -1;

    if ((sock = nl_socket_alloc()) == NULL)
        return err;

    if ((err = genl_connect(sock)))
        return err;

    if ((err = genl_ctrl_resolve(sock, LUNATIK_FAMILY)) < 0)
        return err;

    // I've tried to use NL_CB_VALID, but when I use it I receive no message at all
    nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, req_handler, NULL);
    return 0;
}

Мой вывод на dmesg:

Сообщение отправлено в пользовательское пространство

И мой вывод в пользовательском пространстве:

Получено сообщение от ядра: 0

I должен получить 3 вместо 0, я заметил, что получаю только сообщение ACK, но не сообщение, которое я отправляю, я хотел бы знать, почему это происходит и что я делаю не так.

1 Ответ

0 голосов
/ 21 июля 2020

Результат genl_ctrl_resolve() двоякий:

  • Если <0, это код ошибки. </li>
  • Если> = 0, это семейный идентификационный номер.

Вы выбрасываете свой семейный идентификационный номер. Вместо

if ((err = genl_ctrl_resolve(sock, LUNATIK_FAMILY)) < 0)
    return err;

сделайте

if ((lunatik_family = genl_ctrl_resolve(sock, LUNATIK_FAMILY)) < 0)
    return lunatik_family;

Позже, когда вы настраиваете заголовок Netlink, обязательно используйте его:

if (!genlmsg_put(..., ..., ..., lunatik_family, ..., ..., LIST_STATES, ...))
    /* handle error */

И еще одна вещь: nl_socket_modify_cb() также возвращает код ошибки. Вместо

nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, req_handler, NULL);
return 0;

делать

return nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, req_handler, NULL);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...