A Simple Analysis of Netlink's failure to detect dellink events and the method of detecting network card insertion

Source: Internet
Author: User
Tags call back

Let's take a look at the implementation and summarize it. please correct me if you have any mistakes.
I see the source is kernel 2.6.27, ifplugd-0.28.
Question 1: Why can only rtm_newlink be obtained when Netlink is used to detect network cable plugging?
Question 2: How can I detect Nic plugging information.
Netlink is implemented under net/Netlink/af_netlink.c, but rtnetlink. C is implemented under net/core. There is also a Netlink. h under include/net.
If you use multicast as the keyword, you can find a function named nlmsg_multicast. Its role is multicast A Netlink message. OK, follow this to go up.
Function call relationship:
Nlmsg_multicast
^
|
Nlmsg_policy
^
|
Rtnl_notify
^
|
Rtmsg_ifinfo
^
|
Rtnetlink_event
^
|
Rtnetlink_dev_notifier
At this point, go up to register_netdevice_notifier (& rtnetlink_dev_notifier). When you register the notification chain, you don't have to go up and initialize it again.
The rtnetlink_event function provides the following processing functions:
Switch (event ){
Case netdev_unregister:
Rtmsg_ifinfo (rtm_dellink, Dev ,~ 0u );
Break;
Case netdev_register:
Rtmsg_ifinfo (rtm_newlink, Dev ,~ 0u );
Break;
Case netdev_up:
Case netdev_down:
Rtmsg_ifinfo (rtm_newlink, Dev, iff_up | iff_running );
Break;
Case netdev_change:
Case netdev_going_down:
Break;
Default:
Rtmsg_ifinfo (rtm_newlink, Dev, 0 );
Break;
It can be found that both netdev_up and netdev_down are processed in the same way.
Rtm_newlink. Only netdev_unregister uploads rtm_dellink. Currently, netdev_unregister is triggered when only the rmmod NIC Driver is used in this experiment.
Problem 1 should end here.
By the way, the dev_change_flags function is also called for rtmsg_ifinfo. This function is used when IOCTL siocsifflags is processed.
Problem 2 is mainly the four methods of ifplugd (without considering wireless), the Work Function in ifplugd. C:
Switch (api_mode ){
Case api_ethtool: detect_beat_func = interface_detect_beat_ethtool;
Break;
Case api_mii: detect_beat_func = interface_detect_beat_mii; break;
Case api_private: detect_beat_func = interface_detect_beat_priv;
Break;
Case api_wlan: detect_beat_func = interface_detect_beat_wlan; break;
Case api_iff: detect_beat_func = interface_detect_beat_iff; break;

Default:
Detect_beat_func = detect_beat_auto;
Ifplugd uses detect_beat_auto in the default configuration. In fact, this function is to try the above functions one by one. interface_detect_beat_ethtool and interface_detect_beat_mii. The status of the network card can be obtained through these four methods, but the implementation is different.
The following describes their implementation:
Method 1: interface_detect_beat_ethtool
Tune
The siocethtool Implementation of ioctl, and dev_ethtool function processing in net/CORE/dev. C. The ethtool mechanism in the kernel, the most
It was 98 years ago by David S.
Miller made it first. This is a cool man. It is mainly implemented in net/CORE/ethtool. C. Ifplugd uses the ethtool_glink command to obtain
Obtain the NIC status. The processing of this command is the ethtool_get_value function:
Case ethtool_glink:
Rc = ethtool_get_value (Dev, useraddr, ethcmd, Dev-> ethtool_ops-> get_link );
Ethtool_get_value
Call back Dev-> ethtool_ops-> get_link to get the NIC status. This method must be implemented by each NIC Driver.
For example, the e100_get_link function is implemented in drivers/NET/e100.c. Call e100_get_link
Mii_link_ OK (deivers/NET/MII. c), mii_link_ OK processing:
MII-> mdio_read (MII-> Dev, MII-> phy_id, mii_bmsr );
If (MII-> mdio_read (MII-> Dev, MII-> phy_id, mii_bmsr) & bmsr_lstatus)
Return 1;
Return 0;
Mdio_read is a callback implemented by each of the MII drivers. The specific implementation is back to the specific NIC driver, and the mdio_read function of E100 in e100.c. The ioread32 function is used to read the NIC register.
Method 2: interface_detect_beat_mii
Call the siocgmiiphy and siocgmiireg Implementation of ioctl, and process the following in the dev_ifsioc function (net/CORE/dev. C:
If (Dev-> do_ioctl ){
If (netif_device_present (Dev ))
Err = Dev-> do_ioctl (Dev, IFR, CMD );
Else
Err =-enodev;
}
Dev-> do_ioctl
It is implemented by each NIC Driver.
For example, the E100 function is called in the e100_do_ioctl function of drivers/NET/e100.c and e100_do_ioctl.
Generic_mii_ioctl (deivers/NET/MII. C ). The process is as follows:
Switch (CMD ){
Case siocgmiiphy:
Mii_data-> phy_id = mii_if-> phy_id;
/* Fall through */
Case siocgmiireg:
Mii_data-> val_out =
Mii_if-> mdio_read (mii_if-> Dev, mii_data-> phy_id,
Mii_data-> reg_num );
Break;
Many Nic Drivers call generic_mii_ioctl to process IOCTL. MII Definition
[Url = Response
. It seems that the NIC Driver monitors and controls the phy. For more information about mdio_read, see the stuff written in method 1 above.
Method 3: interface_detect_beat_priv
Base
In the same way as method 2, call the siocdevprivate of ioctl, and implement the dev_ifsioc function (net/Core
/Dev. c) Processing in same method 2, one difference is that siocdevprivate to siocdevprivate +
15 is a command defined by each Nic. Some Enis are implemented and some are not. For example, E100 does not implement this IOCTL. The rtl8150 usb nic Driver is implemented.
Method 4: interface_detect_beat_iff
Call the siocgifflags Implementation of ioctl, which is handled in the dev_ifsioc_locked function (net/CORE/dev. C:
Case siocgifflags:/* Get interface flags */
IFR-> ifr_flags = dev_get_flags (Dev );
Return 0;
The processing of the dev_get_flags function:
Flags = (Dev-> flags &~ (Iff_promisc |
Iff_allmulti |
Iff_running |
Iff_lower_up |
Iff_dormant) |
(Dev-> gflags & (iff_promisc |
Iff_allmulti ));
If (netif_running (Dev )){
If (netif_oper_up (Dev ))
Flags | = iff_running;
If (netif_carrier_ OK (Dev ))
Flags | = iff_lower_up;
If (netif_dormant (Dev ))
Flags | = iff_dormant;
The hardware is not checked by the NIC driver, but by the existing status flag.
To sum up, methods 1 and 2 should be the most safe. You can directly check the hardware registers. Method 3 may not support the driver, and method 4 is not very reliable.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.