Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not getting RTM_DELLINK netlink event #280

Open
VenkateswaranJ opened this issue May 6, 2021 · 2 comments
Open

not getting RTM_DELLINK netlink event #280

VenkateswaranJ opened this issue May 6, 2021 · 2 comments

Comments

@VenkateswaranJ
Copy link

I have a small test code that checks for eth interface up/down events from the RTNLGRP_LINKmulticast group, but unfortunately, I'm always getting the RTM_NEWLINK event even when I unplug and replug the network cable. I expect RTM_DELLINK when I unplug the cable and RTM_NEWLINK when the cable is connected. I'm using libnl-3.4.0 library.

can anyone point out what I'm doing wrong?

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 to compile the above code:


cmake_minimum_required(VERSION 3.10)

project(test 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)
@chengyechun
Copy link

excuse me, unplug and replug the network cable is same as eth interface up/down?

@KanjiMonster
Copy link
Contributor

The RTM_NEWLINK is telling you that the link was updated (there is no explicit "updated" message type), and it lost its carrier (or gained it). You will see this is you check the contents of the IFLA_CARRIER field in the messages.

RTM_DELLINK will only be sent out if a network interface is removed completely, e.g. when deleting a vlan interface via ip link del ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants