未收到 RTM_DELLINK netlink 事件

问题描述 投票:0回答:1

我有一个小测试代码,用于检查来自

RTNLGRP_LINK
多播组的 eth 接口打开/关闭事件,但不幸的是,即使我拔下并重新插入网络电缆,我总是收到
RTM_NEWLINK
事件。我期望拔下电缆时会出现
RTM_DELLINK
,连接电缆时会出现
RTM_NEWLINK
。我正在使用 libnl-3.4.0 库。

任何人都可以指出我做错了什么吗?

extern "C"
{
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <arpa/inet.h>
}

#include <iostream>

static int parseLink(struct nlmsghdr *hdr)
{
    struct ifinfomsg *iface = (struct ifinfomsg *)nlmsg_data(hdr);

    struct nlattr *attrs[IFLA_MAX + 1];

    if (nlmsg_parse(hdr, sizeof(struct ifinfomsg), attrs, IFLA_MAX, nullptr) < 0)
    {
        std::cerr << "problem parsing Netlink response" << std::endl;
        return -1;
    }

    if (attrs[IFLA_IFNAME] != nullptr)
    {
        if (hdr->nlmsg_type == RTM_NEWLINK)
        {
            std::cout << "Interface " << (char *)nla_data(attrs[IFLA_IFNAME]) << " added" << std::endl;
        }
        else if (hdr->nlmsg_type == RTM_DELLINK)
        {
            std::cout << "Interface " << (char *)nla_data(attrs[IFLA_IFNAME]) << " deleted" << std::endl;
        }
    }
    return 0;
}

static int receiveNewMsg(struct nl_msg *msg, void *arg)
{
    struct nlmsghdr *nlh = nlmsg_hdr(msg);
    int len = nlh->nlmsg_len;
    while (nlmsg_ok(nlh, len))
    {
        if (nlh->nlmsg_type != RTM_NEWLINK && nlh->nlmsg_type != RTM_DELLINK)
        {
            if (nlh->nlmsg_type == NLMSG_DONE)
            {
                std::cout << "message complete" << std::endl;
            }
            nlh = nlmsg_next(nlh, &len);
            continue;
        }
        if ((nlh->nlmsg_type == RTM_DELLINK) || (nlh->nlmsg_type == RTM_NEWLINK))
        {
            parseLink(nlh);
        }
        nlh = nlmsg_next(nlh, &len);
    }
    return 0;
}

int main(int argc, char const *argv[])
{
    struct nl_sock *sk;

    /* Allocate a new socket */
    sk = nl_socket_alloc();

    /*
    * Notifications do not use sequence numbers, disable sequence number checking.
    */
    nl_socket_disable_seq_check(sk);

    /*
    * Define a callback function, which will be called for each notification received
    */
    nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, receiveNewMsg, nullptr);
    nl_socket_modify_cb(sk, NL_CB_FINISH, NL_CB_CUSTOM, receiveNewMsg, nullptr);

    /* Connect to routing netlink protocol */
    nl_connect(sk, NETLINK_ROUTE);

    /* Subscribe to link notifications group */
    nl_socket_add_memberships(sk, RTNLGRP_LINK);

    /*
    * Start receiving messages. The function nl_recvmsgs_default() will block
    * until one or more netlink messages (notification) are received which
    * will be passed on to my_func().
    */

    while (1)
        nl_recvmsgs_default(sk);

    return 0;
}

CMakeLists.txt编译上述代码:

cmake_minimum_required(VERSION 3.10)

project(mptcpd VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include_directories(/usr/include/libnl3/)

file(GLOB SOURCES
    *.h
    *.cpp
)

add_executable(${PROJECT_NAME} ${SOURCES})

target_link_libraries(${PROJECT_NAME} libnl-3.so)

更新: 我认为这与 libnl 库有关,所以我尝试了一个没有 libnl 库的示例,但事情是一样的。

这是我尝试过的示例:http://olegkutkov.me/2018/02/14/monitoring-linux-networking-state-using-netlink/

c++ netlink
1个回答
0
投票

您可能想检查消息标志中的

IFF_RUNNING
(和
IFF_UP
)。

仅当您删除整个接口(仅可能的虚拟接口,例如 VLAN)时,才应通知链路本身已删除。换句话说,拔掉电缆并不会删除接口,您仍然应该能够通过

ip link show
看到它。

© www.soinside.com 2019 - 2024. All rights reserved.