NETIF Msg Level

The design of the network interface message level setting.

History

The design of the debugging message interface was guided andconstrained by backwards compatibility previous practice. It is usefulto understand the history and evolution in order to understand currentpractice and relate it to older driver source code.

From the beginning of Linux, each network device driver has had a localinteger variable that controls the debug message level. The messagelevel ranged from 0 to 7, and monotonically increased in verbosity.

The message level was not precisely defined past level 3, but werealways implemented within +-1 of the specified level. Drivers tendedto shed the more verbose level messages as they matured.

  • 0 Minimal messages, only essential information on fatal errors.
  • 1 Standard messages, initialization status. No run-time messages
  • 2 Special media selection messages, generally timer-driver.
  • 3 Interface starts and stops, including normal status messages
  • 4 Tx and Rx frame error messages, and abnormal driver operation
  • 5 Tx packet queue information, interrupt events.
  • 6 Status on each completed Tx packet and received Rx packets
  • 7 Initial contents of Tx and Rx packets

Initially this message level variable was uniquely named in each drivere.g. “lance_debug”, so that a kernel symbolic debugger could locate andmodify the setting. When kernel modules became common, the variableswere consistently renamed to “debug” and allowed to be set as a moduleparameter.

This approach worked well. However there is always a demand foradditional features. Over the years the following emerged asreasonable and easily implemented enhancements

  • Using an ioctl() call to modify the level.
  • Per-interface rather than per-driver message level setting.
  • More selective control over the type of messages emitted.

The netif_msg recommendation adds these features with only a minorcomplexity and code size increase.

The recommendation is the following points

  • Retaining the per-driver integer variable “debug” as a moduleparameter with a default level of ‘1’.

  • Adding a per-interface private variable named “msg_enable”. Thevariable is a bit map rather than a level, and is initialized as:

    1 << debug

    Or more precisely:

    debug < 0 ? 0 : 1 << min(sizeof(int)-1, debug)

    Messages should changes from:

    if (debug > 1)     printk(MSG_DEBUG "%s: ...

    to:

    if (np->msg_enable & NETIF_MSG_LINK)     printk(MSG_DEBUG "%s: ...

The set of message levels is named

Old levelNameBit position
0NETIF_MSG_DRV0x0001
1NETIF_MSG_PROBE0x0002
2NETIF_MSG_LINK0x0004
2NETIF_MSG_TIMER0x0004
3NETIF_MSG_IFDOWN0x0008
3NETIF_MSG_IFUP0x0008
4NETIF_MSG_RX_ERR0x0010
4NETIF_MSG_TX_ERR0x0010
5NETIF_MSG_TX_QUEUED0x0020
5NETIF_MSG_INTR0x0020
6NETIF_MSG_TX_DONE0x0040
6NETIF_MSG_RX_STATUS0x0040
7NETIF_MSG_PKTDATA0x0080