Notification Chains

It’s important to distinguish between two kinds of registration. First, when a device is discovered, it is registered with the kernel as a generic device. Second, an NIC device is registered with the network stack as a network device. For example, a PCI Ethernet card is registered both as a generic PCI device with the PCI layer, and as an Ethernet card (where the device gets a name such as eth0) with the network stack.

The kernel’s many subsystems are heavily interdependent, so an event detected or generated by one of them could be of interest to others. To fulfill the need for interaction, Linux uses so-called notification chains.

Note that notification chains are used only between kernel subsystems.

A notification chain is simply a list of functions to execute when a given event occurs. Each function lets one other subsystem know about an event that occurred within, or was detected by, the subsystem calling the function.

Thus, for each notification chain there is a passive side (the notified) and an active side (the notifier), as in the so-called publish-and-subscribe model:

  1. The notified are the subsystems that ask to be notified about the event and that provide a callback function to invoke
  2. The notifier is the subsystem that experiences an event and calls the callback function.

each subsystem maintainer should know:

  1. The kinds of events from other subsystems he is interested in
  2. The kinds of events he knows about and that other subsystems may be interested in

The elements of the notification chain’s list are of type notifier_block, whose definition is the following:
struct notifier_block
{
int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
struct notifier_block *next;
int priority;
};

subsystems usually register their notifier_call functions only at boot time or at module load time, and from that moment on access the lists in a read-only manner (that is, shared).

Notifying Events on a Chain

Notifications are generated with notifier_call_chain.This function simply invokes, in order of priority, all the callback routines registered against the chain.

int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
{
   int ret = NOTIFY_DONE;
   struct notifier_block *nb = *n;
   while (nb)
   {
      ret = nb->notifier_call(nb, val, v);
      if (ret & NOTIFY_STOP_MASK)
      {
         return ret;
      }
      nb = nb->next;
   }
   return ret;
}
n
Notification chain.
val
Event type. The chain itself identifies a class of events; val unequivocally identifies an event type (i.e., NETDEV_REGISTER).
v
Input parameter that can be used by the handlers registered by the various clients.

The callback routines called by notifier_call_chain can return any of the NOTIFY_XXX values defined in include/linux/notifier.h:

NOTIFY_OK
Notification was processed correctly.
NOTIFY_DONE
Not interested in the notification.*
NOTIFY_BAD
Something went wrong. Stop calling the callback routines for this event.
NOTIFY_STOP
Routine invoked correctly. However, no further callbacks need to be called for this event.

NOTIFY_STOP_MASK
This flag is checked by notifier_call_chain to see whether to stop invoking the callback routines, or keep going. Both NOTIFY_BAD and NOTIFY_STOP include this flag in their definitions

Notification Chains for the Networking Subsystems

The kernel defines at least 10 different notification chains.

inetaddr_chain
Sends notifications about the insertion, removal, and change of an Internet Protocol Version 4 (IPv4) address on a local interface.

netdev_chain
Sends notifications about the registration status of network devices

Registrations to notification chains usually take place when the interested kernel component is initialized.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值